Making a bubble

Procedural shading languages are very powerful. With a relatively small program you can create extremely beautiful and subtle animated textures.

But that very power comes with a price: Because the resulting code is so compact, it can be difficult for somebody else to understand what you have written.

I’m thinking it would be useful to “unpack” such programs, so that people can understand how they really work. For example, the bubble below can be described in just a few dozen lines of shader code (plus another few dozen lines for my standard noise and turbulence functions).

If you click on the image, you can see the bubble as a real time procedural animation, together with the editable shader program that makes it work. That program is very short, but it’s also really difficult to understand.

I’m thinking that I might try to create a step-by-step version of the process of creation. As you click through the steps, the shader program, and the corresponding result, will progress from very simple (just a few lines of code at first) to the final result.

At each step, the result will get a little more interesting. And at each step I can annotate exactly what has changed in the program to cause the visual improvement from the previous step.

Hopefully, if I design these steps carefully, every piece of the shader program will end up making sense. Then maybe some people will start to create their own animated bubbles!

6 thoughts on “Making a bubble”

  1. A bit like JS source maps, no? linking from the minified to the not-minified, or in your case: from the hard-to-understand to the annotated.

  2. I am a big fan of Bret’s work, and these techniques all complement each other. What I am describing here is somewhat more literary than technical. It’s a way to take people on a journey through the story of how an idea was developed.

  3. Hi Prof. Perlin,

    I notice there is some artifacts with the rim of the sphere on my GTX1080:
    http://www.umiacs.umd.edu/~ruofei/perlin012517.PNG

    The artifacts disppear if I remove:
    c += z * ( c * max(0., .06 * dot(L, v)) + // Rim light
    vec3(.3,.3,.3)
    * pow(H(v + L) + .8 * H(v – L), 8.) ); // Highlights

    I guess it’s because of the distance field of the disk but I did not solve it.
    Any suggestions?

    Thanks!

  4. Thanks for catching that!

    The problem seems to be numerical issues in the sqrt function when its arguments are very near zero. The code that causes this symptom is actually inside the D function, at line 8.

    I have fixed it by changing b > .707 to b > .708. So now sqrt(b – .707) always produces a reasonable result.

Leave a Reply

Your email address will not be published. Required fields are marked *