Mandelbrot Normal Mapping

Опубликовано: 28 Июль 2026
на канале: Miles Waugh
858
33

Some code I wrote for rendering the Mandelbrot set with lighting in real-time (https://www.shadertoy.com/view/Nl2XRW). The vast majority of computation done is spent computing the orbits of points on the set. Lighting can be generalized to any form in which a depth pass can be created.

This method sort of "cheats" to make lighting extremely quick to compute. First, the set is computed to 1024 iterations in buffer A. The pass contains the normalized raw iteration count in the red channel, and the normalized smooth iteration count in the green channel. In buffer B, partial derivatives of the green (smooth iteration) channel of buffer A are sampled to determine the gradient vector on the plane given the plane is "vertically offset" by the green (smooth iteration) channel. This normalized vector is then dotted with the light direction. From this dot product, I take the acos to get the angle between the normal and light source, and pass it through a function to compute the lambert cosine term as if integrating over a solid angle (the sun) in the sky. Visual here: https://u.cubeupload.com/Piano_miles/..., and my mathematical proof in LaTeX here: https://u.cubeupload.com/Piano_miles/.... This is then colored, multiplied by light strength and an inverse square attenuation, then I add a blue/cyan color multiplied by a fake AO approximation (based on the view depth and the normal dotted with the camera ray). This gives a lighting pass, which is now contained in buffer B. Buffer C then takes the iteration count from buffer A and the lighting pass from buffer B, computes the color of the set, multiplies the color by the lighting, color grades, and accumulates samples (Monte Carlo) from previous frames. Lastly, a gamma correction is applied to the result of buffer C, and displayed on the screen.