Mandelbrot Set: Revisited - 22/11/21

Back to Main Page

In a much earlier entry, I talked about my work creating a mandelbrot set viewer in python. I wanted to try and use it to explore how I could optimise code to run much more efficiently, and I did to an extent, managing to make it run a lot faster than the default speed by using the Numba library

I didn't manage to do what I really wanted to, though, which was use the power of my fancy new GPU that I had just bought, to speed up my code massively and do each pixel in parallel. However, after finishing the 4D raymarching engine, I had a setup for rendering shaders using the gpu at high speeds that I was pretty sure I could use.

The first step was to rip out all of the old shader code and inputs from the C++ code (Mostly all of the SDF configurations). Tidying it all up took a little while, but I eventually got something tht was quite similar in nature to ShaderToy, where I could just put shader code into a file and have it run simply. Once I had that, I could start to replicate all the mandelbrot code in it.

Some early attempts did not quite go to plan, because of minor mistakes in my logic.

Messed up view
Another messed up view

But once I fixed the errors in my logic, I got the lovely visuals I expected.

A successful render

And once that was all working, I reimplemented the python HSV to RGB conversion code I wrote in HLSL.

A render in colour

In my python code, it took about 20 seconds to do a single frame, which ran on a single thread of single core of my cpu. Now that I had every pixel running in parallel on my GPU, it ws running a lot faster. I'm still not sure exactly how fast it was running, but when I was doing the early experiments with my 4D rendering, my gpu started to make concerning hissing noises at around 1000-2000 FPS, and it was making the same noises now.

The next thing I wanted to do was add in keyboard input to move around and zoom into the image. This involved copying code back from the 4D stuff again to transfer values to the shader code. I set it up so that keyboard input is handled entirely in the C++ side of things, and it just sends over the coordinates and zoom level that you request, which it then renders. This was pretty simple as well.

Once issue I did find is that I quickly ran out of float precision, which resulted in very blocky renders

Loss of float precision resulting in blocky render

This was fixed with the help of a random person on discord, who told me to just change the datatype from vec2 to dvec2, and that instantly fixed the issue, which was very nice. The dvec2 class uses a double instead of a float to store the components, which has a lot more precision.

Back to Main Page