pouët.net

Raymarching Toolbox Thread

category: code [glöplog]
I applaud.
added on the 2015-12-16 13:12:22 by Zavie Zavie
Thanks Mercury!
added on the 2015-12-16 16:00:52 by Virgill Virgill
Amazing stuff! Thankyou.
added on the 2015-12-16 22:51:00 by drift drift
Just by cursory glance, is it nvidia only? It's full of invalid glsl statements (like float x; return x<0?-1:1).
added on the 2015-12-16 23:40:34 by reptile reptile
Let me rephrase it before someone thinks im flaming mercury (thanks for releasing it!): although implicit type conversion is not invalid from version 120, wouldn't it make sense to change the literals thus making it more compatible? (like with opengl es and webgl)
added on the 2015-12-16 23:54:37 by reptile reptile
Great! Thank you a lot for sharing this. There are some nice things in there.
added on the 2015-12-17 00:17:22 by glow glow
reptile: here it compiles (and works) without warnings on latest nvidia, amd, and the khronos reference compiler (glslang). which #version string are you using? maybe we should state a minimum #version in the faq, sorry. 430 should be enough.
added on the 2015-12-17 01:00:01 by cupe cupe
(I hate typing 1.0 instead of 1 so much I always give up on shadertoy after 5.0 minutes)
added on the 2015-12-17 01:05:11 by cupe cupe
Oh, apparently I did miss there is a separate thread;)
So again,
here quick ST port (not fully tested) of the lib.
Also its not ShaderToy problem - its just passing stuff directly to WebGL shader translator that obviously sucks (and has more issues, i.e.couldn't make multi-line defines working as well?!).
added on the 2015-12-17 02:30:35 by tomkh tomkh
Yes, angle is a real problem. Having your shader go though yet another layer of compilation makes debugging way harder when strange things happen. To be fair, the HLSL compiler are probably better than their GLSL counterparts. Still, every added layer just makes for more guesswork about what's really going on and when you hit the driver weirdness one layer is bad enough.

tomkh, thanks for the port! Might I suggest naming the last function fField instead of dField to keep the lib's (and the papers') naming convention? I don't really care about what letter we use as long as it is consistent. I'm just so tired of shadertoy's "map()" functions...
added on the 2015-12-17 11:29:42 by cupe cupe
cupe: <3<3<3<3
added on the 2015-12-18 05:23:24 by ferris ferris
thanks!
very interesting read so far..
added on the 2015-12-18 11:54:11 by toxie toxie
cupe: naming convention fixed.
I have also rewritten GDF platonic primitives to fully unrolled macro version as constant array initialization is not working in WebGL/ES 2.0. I just hope GLSL compiler can optimize constant expressions with function calls, i.e. normalize(vec3(0,1.,PHI+1.)).
added on the 2015-12-18 16:03:36 by tomkh tomkh
cupe: fantastic initiative, great presentation!
added on the 2015-12-18 22:15:09 by quisten quisten
Was asked for it, so I got over myself and made a shadertoy of the scale-invariant distance meter thingy we use for debugging distance fields: https://www.shadertoy.com/view/ldK3zD
added on the 2016-01-28 00:12:32 by cupe cupe
Hey! no post here for 2 years

Comparative screenshots from one of those days with/without the prepass optimization. Red: primary ray iteration count, Green: shadow ray iteration count. 1.0 = 50 iterations.
BB Image
BB Image
(scene mask bits for this scene are ground, trees, houses and skis)

And a shadertoy showing how it's one.

The main observation is the use of sufficently negative sdf values to say that the whole cone/beam is now inside the object, meaning we have total occlusion / a maximum trace length for the cone.
That means that our tile optimization is no longer limited to primary rays but can do even better for the shadows.
added on the 2018-04-07 20:26:46 by Psycho Psycho
Psycho: awesome stuff.
I stumble upon the similar problem with my 8k, where I wanted to place around hundreds of objects in arbitrary positions. My solution was to raymarch inside bounding boxes, but it caused quite a bit of slowdown when many objects were overlapping (you have probable seen this write up).
In your method, I can see you are storing a bit mask for 8x8 screen-space regions, where every bit encodes in fact a class of objects; not really an individual object, as you would quickly ran out of bits ;)
Using this you obviously have to use other tricks to place individual objects. But I see you have found simple work-around for that, e.g. tree positions reveal usual grid+hash pattern :) I guess you also have to lookup terrain texture to find individual object elevation?

Anyway, big thanks for sharing this. I will surely play around with this technique!
added on the 2018-04-07 22:13:21 by tomkh tomkh
yes, part of the fixes for the new version of the intro is also looking up ground gradient (it's in the ground texture) for the tree center positions - trees can't grow where it's too step, but that shouldn't be determined pr evaluation position as it was ;)

For doing less obvious grids I would usually layer several grids on top of each other to get possible cell overlap and thus much better variation. Marching through grids is also quite slow (you'll never have a decent distance) and there the coarse depth + masking helps a lot. I would definitely have done your rocks as layered grids.

For doing many objects of the same kind I did a singlepass compute shader solution in traskogen where each pixel in a threadgroup test against primitive and then they syncronize and share their findings before each marches the primitives touching the tile.
added on the 2018-04-07 23:09:22 by Psycho Psycho
Since these functions of mine have already been adopted, used and spread by a certain group of people I figured I might just as well post them here:

Octahedron:
Code:float so(vec3 p,float s) { return dot(p,normalize(sign(p+1e-6)))-s; }

Note that s is the distance of the faces from the center point, so with s=1 the vertices of the octahedron will be at sqrt(2), the epsilon value(1e-6) is there to combat artifacts for GPUs whose sign function returns a zero vector for zero vector inputs.

Chamfered box:
Code:float sbc(vec3 p,vec3 d,float c) { p=max(abs(p)-d,0.); return so(p,c); }

Enjoy!
added on the 2018-04-09 11:06:09 by LJ LJ
Neat. About that epsilon, shouldn't it maybe be
Code:sign(p)+1e-6
instead? That would avoid the corner case where p == vec3(1e-6). I tend to define my own sgn(x) functions to avoid the zero-case (which is specified in the respective APIs and should behave "bad" across all recent GPU/Driver combinations. If you happen to have something that doesn't do sign(0) = 0 - their implementation probably doesn't adhere to the specification).
added on the 2018-04-09 16:57:32 by las las
Typo, the corner case is obviously p == -vec3(1e-6).
added on the 2018-04-09 18:04:09 by las las
Despite it being specced to behave like that I only experienced it on Intel cards so far, maybe thats due to precision though, since thinking about it I can see people relying on the (imho pretty inconvenient) zero case. I agree that moving the epsilon out is cleaner, that being said having it in the sign already does "the trick" for me, probably due to my "standard" projection setup and marching epsilon not getting close enough.
added on the 2018-04-09 18:23:35 by LJ LJ
Damn, i didn´t even know shadercode acccepts exponents like "1e-6", i still use "0.000001" instead.
Having just admitted i am a lamer, i do wonder if my standard-way of doing it ain´t the better one, considering we want the cruncher to have some yummy repetitions! ;) 4 completely different asciis vs. 3 (very often used across the complete shader) different asciis. maybe i´ll test this later...
well first of all you could drop that leading zero, then I think once you're at the stage where its 1e-6 vs .000001 you might just as well begin to move stuff around hoping that it gives you that one byte more or less :)
added on the 2018-04-09 19:08:22 by LJ LJ
Sure, you are right! The same i keep telling people myself! (shifting random lines to gain many bytes by chance/luck)
But then i find myself using only numbers like 999. or .777 all over my introcodes again...i guess i had some luck finding missing bytes that way in the past and now i can´t stop looking for minimal byte-winning repetitions! ;) I just like the idea of writing crunch-friendly-code if possible...i guess i think like a cruncher myself pretty often by now, haha!
"Please, the cruncher thing" - The Cruncher Monster 2018

login