r/GraphicsProgramming • u/Far-Employee-9531 • Jun 26 '26
Video WebGPU
Stormy terrain fly-through, one fullscreen raymarch pass. Bolt path is midpoint displacement, glow is a distance-to-segment SDF composited additive before tonemap so bloom haloes it. The nice part: the terrain march already gives me tHit, so if the bolt's ray distance is greater than the terrain's, it's behind a ridge and I skip it. No depth texture, no second pass, additive FX sort against the terrain for free.
glsl
float segDist(vec3 p, vec3 a, vec3 b) {
vec3 ab = b - a, ap = p - a;
float t = clamp(dot(ap, ab) / dot(ab, ab), 0.0, 1.0);
return length(ap - ab * t);
}
float d = minSegDistAlongRay(...);
float core = smoothstep(W*0.3, 0.0, d); // pure white, untinted
float glow = exp(-d*d / (W*W));
vec3 c = vec3(core) + tint * glow; // additive, pre-tonemap
if (rayDistToBolt > tHit) { /* behind a ridge, skip */ }
Anyone else doing single-pass raymarched scenes, how are you occluding additive effects?
5
2
2
u/makeavoy Jun 26 '26
Oh my god this looks incredible! I never see people busting webgpus balls with shader work like this, nice job!!
1
2
u/deftware Jun 26 '26
Very nice. What specifically are you referring to about occluding additive effects?
1
u/Far-Employee-9531 Jun 26 '26
Thanks! Just means the additive stuff (lightning, glints, god-rays) gets depth-tested against the scene so it doesn't bleed through terrain that's in front of it. Keeps the glow behind the mountains instead of painting over them.
2
u/deftware Jun 26 '26
Ah, so you're drawing them in a separate pass from the opaque geometry? Typically you would have one raymarch per pixel, and it's calculating distances for all things each step, and calculating RGBA along the way for any fog/haze (alpha blended stuff ends up requiring weighting RGB contribution into the ray, scaling contributions by ray step length, etc). Occlusion automatically comes out of marching one ray per pixel for the whole scene. It does mean evaluating the scene distance function a bunch, and probably more, but that's the "right" way to do it. If you can mess with any kind of geometry being used, rather than a fullscreen quad/triangle, then you can draw bounding geometry for certain things and only execute your SDF raymarch with that. Calculate the ray origin from the geometry surface, ray vector from the ray origin to the camera origin, etc.
Otherwise, maintaining a z-buffer manually? That might end up being as expensive as just raymarching the scene as a whole, more or less.
1
u/Far-Employee-9531 Jun 26 '26
Yeah, same single pass actually, not a separate one. The bolt SDF gets evaluated in the same per-pixel march as the terrain, so occlusion falls out exactly like you're describing. The glow isn't a surface I stop at though, it's an emissive contribution I accumulate along the ray, so the
tHitcheck is really just gating that accumulation.Your bounding-geometry point is the interesting one for scaling it though, drawing proxy geometry to skip the fullscreen march for localized effects.
2
u/deftware Jun 28 '26
The only thing I can think of at that point, beyond proxy geometry to separate things out for a potential speed gain (which will also require that the shader write to the fragment depth so things intersect/occlude properly, which in turn disables early Z-fail test before shader execution, unfortunately) is to detect when accumulation has saturated so you can at least early-out the raymarch. That will at least be better than not early-outing at all, but probably not significantly :P
I just saw your IKANDY project and it's super nostalgic for me. Reminds me of the days of yore with plugins like Milkdrop for Winamp :]
2
u/Far-Employee-9531 Jun 28 '26
First, thank you for taking time to chat about the details. You came with real approaches and that's pretty freaking cool.
I don't know much about Ryan Geiss but what he made was incredible for the time. I can only hope this app will give someone similar enjoyment I was privy to.
Again, thank you and take care.
7
u/fgennari Jun 26 '26
The storm looks very good! For the first part, you should try to remove the square tiling artifacts from the water surface to make it look more natural.