Raymarching Toolbox Thread
category: code [glöplog]
xD
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
that's good reference material... IQ. thank you. :)
They told me this:
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. ;-)
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
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
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.
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.
Wow, that truly is a practical toolbox there, iq.
But what is the "smoothcurve"-function you use for blending?
But what is the "smoothcurve"-function you use for blending?
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!
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!
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 :).
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.
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 :).
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.
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.
(remove the "either"... I'm tired... exam tomorrow - sorry).
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!
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!
correction:
should be
What I tried to say in a horribly complicated way:
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:
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. ;)
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. ;)
vec4(p,1.) ... DAMN glsl :D
good night.
good night.
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
nice!
This might also be worth reading: http://blog.hvidtfeldts.net/index.php/2011/08/distance-estimated-3d-fractals-iii-folding-space/
This might also be worth reading: http://blog.hvidtfeldts.net/index.php/2011/08/distance-estimated-3d-fractals-iii-folding-space/
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) :
if you want to see it running in full script you can check "tigrou/menger tower.pss" in this archive here
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
tigrou, that's nice!!! can you post an image, please??
las, super cool link!
las, super cool link!
the goold old soft shadows with penumbra, with one single ray (with some explanations here http://www.iquilezles.org/www/articles/rmshadows/rmshadows.htm
resulting in this shadows:
vs the old style hard shadows:
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:
vs the old style hard shadows:
Your on a roll IQ! +10 scenepoints! xD
\o/
@iq : here is screenshots, as requested
same scene but with some sphere intersection...
a screenshot showing how it is rendered (tons of small little spheres...) :
i am just wondering which method (mine or iq) is faster ?
same scene but with some sphere intersection...
a screenshot showing how it is rendered (tons of small little spheres...) :
i am just wondering which method (mine or iq) is faster ?
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.
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:
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
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.
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
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.
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:
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
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.
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
That's hot. Nicely lit too!