pouët.net

Raymarching Toolbox Thread

category: code [glöplog]
xD
added on the 2011-08-19 11:00:19 by Mewler Mewler
not complete (missing blobs, general distortions, bvh, luts), but a compact visual reference guide to the very basics of procedural modeling for raymarching: http://iquilezles.org/www/articles/distfunctions/distfunctions.htm
added on the 2011-08-21 06:42:26 by iq iq
that's good reference material... IQ. thank you. :)
added on the 2011-08-21 06:49:44 by yumeji yumeji
They told me this:
BB Image
added on the 2011-08-21 09:28:50 by w00t! w00t!
Great, iq!
You made a nice overview of the basic methods.
I would like to add domain clamping.

This can be called right before the domain repetition, to limit the
count of objects in any dimension. We don't want always infinite fields. ;-)
Code: /** useful with domain repetition. shapes are only rendered between min and max limits using abs makes this symmetric (left/right and front/ back) */ vec3 clamp_abs_xz( vec3 p, vec3 min , vec3 max ) { vec3 q = p; q.x = clamp( abs(q.x), min.x, max.x); q.z = clamp( abs(q.z), min.z, max.z); return q; }

An interesting aspect of domain clamping is clamping
inside the boundary of an object.
For example, if you clamp a sphere field, the truncated spheres at the outer border will be extruded to a cylinder.

As can be seen here:
http://www.youtube.com/user/directscene?feature=mhee#p/a/u/0/wC5xD8cdJc8
added on the 2011-08-21 10:40:22 by rotwang rotwang
Very nice work IQ!

Some little things I noticed:
+ For the plane - n.xyz must be normalized - not n(.xyzw).
+ What you call bend - is not a real "bend" operator. The real thing is the one from Barr - and there you need the inverse transform - which in the original text has a typo.
What you do is some kind of rotational domain distortion.

Just ask if you need more contributions for that page - you know where to find us.
added on the 2011-08-21 10:47:44 by las las
Wow, that truly is a practical toolbox there, iq.

But what is the "smoothcurve"-function you use for blending?
added on the 2011-08-21 10:58:10 by urs urs
hey las!

if you have a plane n.xyzw, and you want it to have a unit length normal, you have to divide all x, y, z and w by |xyz|, otherwise you are "moving" your plane. if you don't "normalize" w, it is a different plane, that's why i meant.

not sure what Barr is. Bend and Twist are both rotational domain distortion indeed, just in different axes.

in the world of distortions and deformations one could go forever, there is no limit. i only added two, but if you guys there is any other which is used a lot, i can add it too. same for primitives - i didn't add metaballs or julia sets or recursive primitives (sierpinski sponges and the like). but if you think there is some other basic primitive i forgot, i'm happy to add it!
added on the 2011-08-22 20:37:13 by iq iq
vec3 n, float d (which is n.w in your stuff) with length(n) = 1 defines a plane in the direction of n with the distance d from the origin. iff d = 0 you define a plane through the origin. d = 1 moves the plane with the normal n (length(n) = 1) along the normal with the distance 1.
Now we can use either dot(n.xyz, p) + n.w - where n.xyz should be the normalized position of your plane and n.w the distance of the plane to the origin. Given that d.w is a distance - it should not be normalized in any way.

We can even apply a little "optimization" - dot(n, float4(p,1)) - not a major opt, but this might be better under certain circumstances. There might be +- errors in my explaination.

Barr defined basic mesh operators: Twist, Bend, Taper and so on... Cool stuff from the 80ies - contact me via email please :).
BB Image
As you can see the bottom/top of the cylinder is still in a plane and not deformed - that is a "linear" barr bend op.
added on the 2011-08-22 23:51:14 by las las
dot(n', float4(p,1)) - of course with float4 n' = float4(n, d). with normal float3 n & length(n) = 1, and distance float d from the origin.
added on the 2011-08-22 23:55:09 by las las
(remove the "either"... I'm tired... exam tomorrow - sorry).
added on the 2011-08-22 23:58:30 by las las
n.w is the distance to the origin measured in |n.xyz| units, or real world units if |n.xz| happens to be 1 - that's why you also have to divide n.w by |n.xyz|, otherwise you are changing the distance to the origin and therefore moving the plane,as i said. i think we are both saying the same thing.

oh, i see what you mean about distorting the top plane in the bend. i'll call it "cheapBend" or something like that instead - i like using proper nomenclature. thx!
added on the 2011-08-23 02:34:06 by iq iq
correction:
Quote:
where n.xyz should be the normalized position of your plane

should be
Quote:
where n.xyz should be the normalized normal of your plane


What I tried to say in a horribly complicated way:
Quote:

float sdPlane( vec3 p, vec4 n )
{
// n must be normalized
return dot(p,n.xyz) + n.w;
}

If you normalize the float4 n you divide the whole thing by length(n.xyzw) - than pretty non intuitive things happen ;)

It's much more intuitive with sth. like:
Quote:

float sdPlane( vec3 p, vec4 n )
{
// n.xyz could be the normalized normal of your plane and n.w the distance of that plane to the origin
return dot(p,n.xyz) + n.w;
//Alternative implementation
//return dot(vec4(p,1), n);
}

Basically it's up to the user what the heck he plugs into the equation for n - As you mentioned - not normalizing n.xyz should just change the scaling of the influence of the n.w by the length of n.xyz.

You can find expensiveBarrBend in this thread btw. ;)
added on the 2011-08-23 03:34:51 by las las
vec4(p,1.) ... DAMN glsl :D
good night.
added on the 2011-08-23 03:37:43 by las las
just read it and saw it has bugs, but well, there it is with source code (in shadertoy), some Cantor-inspired shapes, and an example of iterative primitive composition: http://www.iquilezles.org/www/articles/menger/menger.htm
added on the 2011-08-24 11:49:35 by iq iq
its a nice and well explained article iq, thanks.

for those interested with fractals and raymarching, i already play with a menger sponge some months ago. my approach was different (folding space and using spheres for rendering) :

Code: for (n = 0; n < 10; n++) { p = abs(p); if (p.x < p.z) p.xz = p.zx; if (p.y < p.z) p.yz = p.zy; p.x = (s + 1.0) * p.x - s; p.y = (s + 1.0) * p.y - s; p.z = (s + 1.0) * p.z; if(p.z > 0.5 * s) p.z -= s; } float dist = length(p) * pow(s + 1.0, float(-n));


if you want to see it running in full script you can check "tigrou/menger tower.pss" in this archive here
added on the 2011-08-24 12:49:46 by Tigrou Tigrou
tigrou, that's nice!!! can you post an image, please??

las, super cool link!
added on the 2011-08-24 19:33:14 by iq iq
the goold old soft shadows with penumbra, with one single ray (with some explanations here http://www.iquilezles.org/www/articles/rmshadows/rmshadows.htm

Code:float softshadow( vec3 ro, vec3 rd, float mint, float maxt, float k ) { float res = 1.0; for( float t=mint; t < maxt; ) { float h = map(ro + rd*t); if( h<0.001 ) return 0.0; res = min( res, k*h/t ); t += h; } return res; }


resulting in this shadows:

BB Image
vs the old style hard shadows:BB Image
added on the 2011-08-25 06:55:02 by iq iq
Your on a roll IQ! +10 scenepoints! xD
added on the 2011-08-25 07:24:05 by Mewler Mewler
\o/
added on the 2011-08-25 10:31:49 by las las
@iq : here is screenshots, as requested

BB Image

same scene but with some sphere intersection...

BB Image

a screenshot showing how it is rendered (tons of small little spheres...) :

BB Image

i am just wondering which method (mine or iq) is faster ?
added on the 2011-08-25 11:43:00 by Tigrou Tigrou
Menger Building

IQ, thanks again for this valuable article about Menger Sponge fractals.

The Menger is an excellent base to create buildings, towers and the like.
We can get more interesting variations, if we don't apply the same scaled
cutout, but instead apply different translations and rotations at each level.

BB Image

The code is not mine, it's just a little modification of the sources at:
http://www.iquilezles.org/www/articles/menger/menger.htm

just modify the variable r with a transform matrix:

Code: float transxz = 0.0; float transy = (s/3.25)/(fm+1.75) - fm; float roxz= 0.0; float roy= RAD30 + RAD30*fm - RAD45/s; transform( r, vec3( transxz, transy, transxz ), vec3(roxz, roy ,roxz ) );



This video demonstrates a Menger Sponge fractal with
different transformed cutouts per level.
video:
http://www.youtube.com/user/directscene?feature=mhee#p/u/0/hrZR52Apdw8
added on the 2011-08-25 12:07:42 by rotwang rotwang
Menger Building

IQ, thanks again for this valuable article about Menger Sponge fractals.

The Menger is an excellent base to create buildings, towers and the like.
We can get more interesting variations, if we don't apply the same scaled
cutout, but instead apply different translations and rotations at each level.

BB Image

The code is not mine, it's just a little modification of the sources at:
http://www.iquilezles.org/www/articles/menger/menger.htm

just modify the variable r with a transform matrix:

Code: float transxz = 0.0; float transy = (s/3.25)/(fm+1.75) - fm; float roxz= 0.0; float roy= RAD30 + RAD30*fm - RAD45/s; transform( r, vec3( transxz, transy, transxz ), vec3(roxz, roy ,roxz ) );



This video demonstrates a Menger Sponge fractal with
different transformed cutouts per level.
video:
http://www.youtube.com/user/directscene?feature=mhee#p/u/0/hrZR52Apdw8
added on the 2011-08-25 12:20:39 by rotwang rotwang
That's hot. Nicely lit too!
added on the 2011-08-25 12:32:26 by psonice psonice

login