This is fascinating. Can someone help me understand why SDF-only techniques are valuable (aside from being interesting in their own right)? I know very little gfx but so far I mostly saw SDFs used for accomplishing stuff in fragment shader that would otherwise be done with geometry, kind of as a workaround for limitation of shadertoy environment
I believe the reason is because they allow for efficient raytracing via a technique called raymarching, which requires a way for it to tell what's the minimum distance from a surface given any arbitrary point, hence the need for a SDF. Quilez has many examples of this technique on his site
SDF Fractal Noise
31–40 of 44 posts
Re: SDF Fractal Noise
#32Earlier quoted context omitted.
I believe the reason is because they allow for efficient raytracing via a technique called raymarching, which requires a way for it to tell what's the minimum distance from a surface given any arbitrary point, hence the need for a SDF. Quilez has many examples of this technique on his site
Ah, thank you!
The problem that classic primitive raytracing has had was that it never scaled well for complex primitives since you needed to solve the equations that could have many intersection points for a ray.
A plane (and triangle) has 0 or 1 intersection point, this is quite trivial to solve.
Insert the ray equation ( x'=x0+dxt, y'=y0+dyt, z'=z0+dzt) into the plane equation ( Ax+By+Cz = D) and solve for [t] that is the intersection distance as seen from the ray origin [x0,y0,z0] in delta units.
A sphere has 0, 1 or 2 intersections. You again insert a ray equation into a sphere equations and after solving you end up with a classic second degree equation with a square root.
A donut can have 0, 1, 2, 3 or 4 intersections.
All these are fairly trivial shapes, but you see how the code complexity goes up very quickly even here with more intersection cases to handle even for these fairly simple shapes.
Raytracing was used with triangle-meshes (with acceleration structures) in offline renderers since it still allowed for better lighting models with free-er ray sampling than normal rendering (and now RTX has put this ability in hardware for triangle soups)
Now, for something simple as a sphere and plane, raytracing is faster than raymarching.
The difference however is that since distance field raymarching only relies on a single value (the distance to the nearest surface) and SDF functions are trivially composable there really isn't any bounds on how complex shapes you can render with the technique, as long as the combination and core distance functions are at least somewhat conservatively "correct" in producing a single distance value (raymarching is can be forgiving for inaccuracies as long as they don't over-shoot).
So while raymarching isn't really super-fast, it's fast enough that most GPU's eats them up, since it can all be run in parallel without almost any data bandwidth. (and the fact that raymarching often converges on "big" surfaces within a few iterations only needing more iteration in areas like borders that only take a small bit of the screen estate)
Re: SDF Fractal Noise
#33Earlier quoted context omitted.
Ah, thank you!
To elaborate(and just slightly correct on this point). The problem that classic primitive raytracing has had was that it never scaled well for complex primitives since you needed to solve the equations that could have many intersection points for a ray. A plane (and triangle) has 0 or 1 intersection point, this is quite trivial to solve. Insert the ray equation ( x'=x0+dx t, y'=y0+dy t, z'=z0+dz t) into the plane equ…
Re: SDF Fractal Noise
#34> So, when adding a regular fBM, sine wave or any other displacement function to a "host" SDF, we don't get a valid SDF anymore (we violate the principle that the gradient of an SDF must have length 1.0). Can someone elaborate or point to an elaboration of this point? I guess there must be a good reason why the gradient cannot just be normalised, but I don't know what it is.
Re: SDF Fractal Noise
#35> So, when adding a regular fBM, sine wave or any other displacement function to a "host" SDF, we don't get a valid SDF anymore (we violate the principle that the gradient of an SDF must have length 1.0). Can someone elaborate or point to an elaboration of this point? I guess there must be a good reason why the gradient cannot just be normalised, but I don't know what it is.
Because you're displacing the existing gradient. The existing SDF is by definition valid but now being transformed. It's been a while since I dabbled in this but I'm not sure how you'd normalize and maintain the transform. If you naively normalize then you lose all the smooth continuity of the function, which is no bueno.
Re: SDF Fractal Noise
#36I can't think of how a Simplex-noise equivalent might work, as displacing spheres by a vector might have the same issues as naive noise in terms of continuity.
Re: SDF Fractal Noise
#37Earlier quoted context omitted.
Because you're displacing the existing gradient. The existing SDF is by definition valid but now being transformed. It's been a while since I dabbled in this but I'm not sure how you'd normalize and maintain the transform. If you naively normalize then you lose all the smooth continuity of the function, which is no bueno.
Could you naively compose the distance functions and then use automatic differentiation to compute the gradient? As long as the distance functions are differentiable, so should their composition be.
Re: SDF Fractal Noise
#38Earlier quoted context omitted.
Could you naively compose the distance functions and then use automatic differentiation to compute the gradient? As long as the distance functions are differentiable, so should their composition be.
Possibly but I suspect that is more complex than it seems at first glance.
Re: SDF Fractal Noise
#39Earlier quoted context omitted.
To elaborate(and just slightly correct on this point). The problem that classic primitive raytracing has had was that it never scaled well for complex primitives since you needed to solve the equations that could have many intersection points for a ray. A plane (and triangle) has 0 or 1 intersection point, this is quite trivial to solve. Insert the ray equation ( x'=x0+dx t, y'=y0+dy t, z'=z0+dz t) into the plane equ…
Nontrivial renderers always make use of acceleration structures, and that’s actually much harder to implement with SDFs. At least with polygons, you can very precisely divide up your space or your objects and know exactly in which region what it is you’re hitting. You don’t get that benefit so easily with complex SDFs and thus many optimizations are not available.
Other than that you can actually re-use many simpler SDF's to work as bounding spheres,etc. For example I did a kind of skinned character rendering that kinda started turning expensive and a simple way to accelerate it was to first do a sphere calculation that bounded it, if the sphere calc was producing a large enough value it was output directly instead of the "detail" value of the actual character. Now for a GPU that isn't ideal if one of the "threads" enters the character, but I think most GPU's do triangles one-tile-at-a-time so these threads will most of the time have converging calculations within each tile.
Re: SDF Fractal Noise
#40> So, when adding a regular fBM, sine wave or any other displacement function to a "host" SDF, we don't get a valid SDF anymore (we violate the principle that the gradient of an SDF must have length 1.0). Can someone elaborate or point to an elaboration of this point? I guess there must be a good reason why the gradient cannot just be normalised, but I don't know what it is.
We don't use this gradient for anything much. What we use is the knowledge that the gradient is of unit length.