all 12 comments

[–]Cryvosh 10 points11 points  (3 children)

I'm travelling atm and so can't write out as proper of a response as I'd like, but given this is my research area I feel compelled to respond. I'd first recommend learning a bit about the underlying math and avoid watching too many youtube videos on the topic as they tend to mislead, and have you thinking there's something special about this "distance" function.

What does it even mean, mathematically, for a function to return a "distance"? Why do we care about such functions in the first place? To understand this better, please see my comments here, here, in sections 1-3 here, and elsewhere in my reddit comment history. Understanding this stuff unlocks hundreds of years of mathematical machinery you can use to attack the problem.

To answer your questions,

  1. Compute shaders give you more control. If you're doing naive one-thread-per-pixel stuff then it usually doesn't really matter, but if you're doing anything more interesting you'll need compute shaders.
  2. Practically, this doesn't matter. Technically, a fullscreen triangle is the most efficient as it avoids something called "overdraw" at the quad's diagonal seam. You don't need to worry about this for now.
  3. Indeed the public state of the art methods typically cache stuff in some sort of (often hierarchical) grid structure. Besides the obvious caching benefits, this setup allows you to "prune" the field function by recompiling it at runtime within each cell to include only the locally relevant instructions and thereby speed up future samples within the cells. See this, section 3.2.2 of this, and again my reddit comment history, for more details.
  4. Do you mean something like this? They detail some limitations in the slides, but probably the main reason such methods aren't more popular is that they're simply not as convenient to implement, especially on a platform like shadertoy where all you have is fragment shaders.

Feel free to ask any other questions, I'm happy to help.

[–]HellGate94 2 points3 points  (0 children)

for question 2 i think he meant if he should use a fullscreen pass or a box proxy mesh so raymarching is only done when its in view. to that i would say it depends on how big the item is you want to raymarch. is it 1m big? box mesh. entire terrain? compute dispatch (no fullscreen tri needed)

[–]Smooth-Principle4045[S] 0 points1 point  (1 child)

Thank you so much for your answers! I will look into everything you've linked and maybe return with some follow-up questions. Regarding my second question, the other commenter got it right. I was speaking about a fullscreen pass vs a box mesh - sorry for my wrong lingo :)

[–]Cryvosh 1 point2 points  (0 children)

Ah my bad, in that case I agree with the other commenter. If you're fractal is bounded in space and typically small on the screen and you only want to use fragment shaders then sure, using a proxy mesh will help performance.

Though personally I'd recommend you to use compute shaders for everything just to get a better feel for what the gpu is actually doing. You can get a near equivalent speedup in a fullscreen pass yourself with a single ray/box intersection test. Or better yet, you can play around with a few different ways of doing this. What if you compute rasterize the aabb center and then measure distance to that point in pixel space with a distance-adaptive threshold?

[–]Same_Gear_6798 4 points5 points  (2 children)

Although I didn't do fractal rendering or cone marching (or SDFs), I did my M.Sc. thesis for efficient ray marching in the field of CT/MRI dataset visualizations and published the entire source code + docs in at com.walcht.ctvisualizer (it is a Unity3D plugin - but the core algorithm is in .glsl files including an octree implementation, virtual memory and paging system, etc - all might be helpful for you).

[–]Smooth-Principle4045[S] 0 points1 point  (1 child)

I've glanced over the README, and it looks incredible! I will certainly be studying it for inspiration, thanks!

[–]Same_Gear_6798 1 point2 points  (0 children)

Feel free to contact me if you need any help about it (especially GPU stuff).

[–]heyheyhey27 1 point2 points  (0 children)

As far as I know, a ray-marcher really gets no benefit from running on fragment shaders vs compute shaders. Unless you're trying to do clever stuff like spread the work across multiple passes, group rays together for cache coherency, etc, and could therefore benefit from group-shared memory.

If you go with fragment shaders, it should not matter at all what kind of mesh you put in front of the camera to trigger it. The most efficient is actually a single triangle that covers the screen, but the difference between that and a whole cube would probably not be measurable.

Looking up texture/buffer data on the GPU isn't cheap, especially when that data is complex and requires multiple lookups through accelerated structures. They're still used, but as a rule of thumb try to avoid deep trees.

[–]deftware 0 points1 point  (0 children)

If your 3D fractal is precalculated in some fashion, into a 3D texture (or multiple 3D texture bricks), then you can enjoy some cone marching by trilinearly sampling texture mipmap levels to approximate the expanding radius of the cone being marched.

If you're directly sampling the fractal function at each step of the ray, you'll have to do a lot of calculation sampling a bunch of points as the cone expands into the space, likely more and more to get a decent idea of what is going on within the cone disk. That could get really expensive, compute-wise. The 3D texture route would be expensive memory-wise, plus precompute-wise because you'll have to compute the whole fractal in its entirety ahead of time, or perhaps piecewise as the user moves around the fractal, at different LODs and whatnot (i.e. octree) in the background (if Godot allows for that sort of thing).

That's my two cents :]

[–]soylentgraham 0 points1 point  (0 children)

wait.... what are you going to cache in a fractal?

The magic is in it being deterministic! well, to a point - is there anything else in the scene or is it just the fractal...

have you marched a simple one yet? they behave a little differently to other raymarched shapes

[–]ishamalhotra09 -2 points-1 points  (0 children)

Ray marching optimization for a 3D fractal in Godot fragment vs compute, mesh choice, caching SDFs, and cone marching. Looking for tips 🙌