Jeff Smith
banner
jeffsmith.bsky.social
Jeff Smith
@jeffsmith.bsky.social
Game designer and developer @ Incoming Games. Shadow of Aya coming soon. https://www.shadowofaya.com
But doctor,
November 20, 2025 at 8:57 PM
But doctor,
November 20, 2025 at 8:55 PM
As a final flourish, I add a simple particle system to simulate ash. And with that, the effect is done—until it’s not. Iteration continues, and the needs of tomorrow may outweigh the needs of today.

But that is another problem! One at a time.
October 17, 2025 at 4:44 PM
In the way these things sometimes happen, this works perfectly the first try.
October 17, 2025 at 4:44 PM
Until it works! In the end I add a vertical blur to let the distortion “rise” off the lava. I also tweak the noise for less intensity, and add a cosine wave to the original sine wave, using a different amplitude and frequency. I’m happy with the distortion pattern now, but something’s still missing.
October 17, 2025 at 4:44 PM
So much of this kind of work is iteration. You have an idea, you test the idea, you modify the idea, you test again. This thing I thought would work is too subtle, what if I multiply it? My code is broken, what error did I get? One problem at a time, over and over, and over again
October 17, 2025 at 4:44 PM
We’ll try a blur so that the mask softens and expands. This looks much nicer in this view, but will certainly need adjustment for the final effect. I can already guess that it'll need the gamma boosted, or a directional blur of some kind
October 17, 2025 at 4:44 PM
Let’s switch views to see the mask channel itself. We can see our perlin noise texture, and how it has the harsh edge of the lava tiles.
October 17, 2025 at 4:44 PM
Returning to our heat filter—and—it works! Well, it masks to the right layer. We still have to figure out this distortion effect. And the next thing I want to try is expanding the mask—looking at it now, it's become too subtle, only visible around the lava edges, in a way that’s easy to miss.
October 17, 2025 at 4:44 PM
This was a long detour, but we learned something, and that’s worth it in my book. (It also helped me solve a bug in an unrelated part of the code—a topic for another time.) Our updated originalDepth calculation now looks like this:
October 17, 2025 at 4:44 PM
Something about the number 10 is tickling my brain. I seem to recall a 10 somewhere related to camera setup, so let’s take a look in the camera code. Say, what’s this random -10 value?
October 17, 2025 at 4:44 PM
Hang on. The Lava layer should be at 5282, but in the shader output it’s 5292. And the layer that *is* visibly distorting, Rocks_2, is at 5272, not 5282 like the shader says. So every layer is off by 10 for some reason...?
October 17, 2025 at 4:44 PM
Let’s see what’s going on. My guesses are either a math error on my part (likely, and maybe an easy fix) or insufficient precision in the depth buffer (unlikely, and maybe impossible). Using my new tool, I can get the depth as interpreted by the shader at each pixel, and, uhh, huh. It looks… right?
October 17, 2025 at 4:44 PM
And so. On the shader we pack our value into the rgba channels of the output pixel. We then read the target surface as a buffer, and reverse the math to get back what we put in. Hardly efficient, but fine for a debugging tool—and lets us peek at exactly what values our shader is working with!
October 17, 2025 at 4:44 PM
That did not do the thing! At first glance I thought it did nothing at all, probably I screwed something up and broke the shader. But looking closer, it *is* distorting, and it is masking—just not on the right layer. So something is up with how we’re reading or writing the depth value, maybe
October 17, 2025 at 4:44 PM
This *should* enable us to mask on the lava layer by simply checking that `originalDepth == lavaLayerDepth`. And because of the way the depth buffer overwrites ‘further’ values with ‘nearer’, we get occlusion for free. In theory! So let’s spin that up… and… hm.
October 17, 2025 at 4:44 PM
By passing the buffer into a shader, it’s possible to read the original depth value like so (This formula works because we have an orthographic projection with a fixed-z-position camera; for other scenarios it would be more complex)
October 17, 2025 at 4:44 PM
Take two: I decided to try masking the distortion with a scrolling perlin noise texture. This definitely cuts down on the intensity, but I’m still feeling queasy looking at it. At this point I’m now certain that the final effect cannot cover the whole screen.
October 17, 2025 at 4:44 PM
My first attempt: a simple sine wave applied to the whole screen. Partly this was to be sure I’d set up the shader correctly, partly this was to see if sine distortion could work as a starting point. Verdict: uhhhhh I’ll get back to you, I immediately have a headache
October 17, 2025 at 4:44 PM
This has turned out all right! So I thought I’d do a little thread on it. For reference, this is what I started with—a typical fire-y area with no vfx applied. I quite like the lava animation my brother made, but I’m aiming to add just a little extra “this place is hot, like so hot you guys”
October 17, 2025 at 4:44 PM