Implicit function to distance function
category: general [glöplog]
It's all a fancy way of saying, "ah, Fibonacci numbers".
BTW, this is probably kind of obvious, but i never saw it.
For calculating the gradiend vector is only necessary evaluate 4x the distance function instead of 6x.
For calculating the gradiend vector is only necessary evaluate 4x the distance function instead of 6x.
Code:
float3 grad(float x,float y,float z){
const float n_er=0.001;
/*
//cube way 6x
float3 n=float3(
v(x+n_er,y,z)-v(x-n_er,y,z),
v(x,y+n_er,z)-v(x,y-n_er,z),
v(x,y,z+n_er)-v(x,y,z-n_er));
return n;
*/
//tetrahedron way 4x
float v1=v(x+n_er,y-n_er,z-n_er);
float v2=v(x-n_er,y-n_er,z+n_er);
float v3=v(x-n_er,y+n_er,z-n_er);
float v4=v(x+n_er,y+n_er,z+n_er);
float3 n=float3(
((v4+v1)/2)-((v3+v2)/2),
((v3+v4)/2)-((v1+v2)/2),
((v2+v4)/2)-((v3+v1)/2));
return n;
}
Is also necessary to divide by n_er*2, and normalize to obtain a normal.
sure. i usually center it at x,y,z and use a cube thou
float vo=v(x,y,z);
float vx=v(x+eps,y,z);
float vy=v(x,y+eps,z);
float vz=v(x,y,z+eps);
return normalize(vec3( vx-vo, vy-vo, vz-vo ));
Of course no need to divide by eps*2 cause you are gonna normalizing anyway.
Is the tetrahedron giving better results than the cube? Better sampling or something?
float vo=v(x,y,z);
float vx=v(x+eps,y,z);
float vy=v(x,y+eps,z);
float vz=v(x,y,z+eps);
return normalize(vec3( vx-vo, vy-vo, vz-vo ));
Of course no need to divide by eps*2 cause you are gonna normalizing anyway.
Is the tetrahedron giving better results than the cube? Better sampling or something?
(replace "eps*2" by "eps")
No, tetrahedron gives probably less accurate results, because instead of a direct evaluation is used an average of two points. But in practice using a very small eps the cube way using 6 evaluations, or your cube way using 4, or the tetrahedron way give the same results.
Raycasting with distance function it's just wonderful :)
The possibilities are endless, I'm feeling like an explorer discovering new worlds in 3d graphics :)
I use HLSL and RenderMonkey to create stuff in real-time.
Right now i create an object rotating a 2d distance function. And it works 100% beautiful :)
To do this it is just necessary to deform space using this function:
x=sqrt(z*z+x*x);
y=y;
z=0;
A torus it's just a rotated circle :)
Actually papers about sphere tracing, have a formula for calculating the distance function to a torus
( (r1-sqrt(x^2+y^2))^2+z^2-r2^2 ) that is less acurate than this method.
Because Lipschitz const is 2 instead of one.
Also it is possible to do a lot of tweaks to create some really interesting objects ;)
The possibilities are endless, I'm feeling like an explorer discovering new worlds in 3d graphics :)
I use HLSL and RenderMonkey to create stuff in real-time.
Right now i create an object rotating a 2d distance function. And it works 100% beautiful :)
To do this it is just necessary to deform space using this function:
x=sqrt(z*z+x*x);
y=y;
z=0;
A torus it's just a rotated circle :)
Actually papers about sphere tracing, have a formula for calculating the distance function to a torus
( (r1-sqrt(x^2+y^2))^2+z^2-r2^2 ) that is less acurate than this method.
Because Lipschitz const is 2 instead of one.
Also it is possible to do a lot of tweaks to create some really interesting objects ;)
Whats really cool is that now we are moving back to software rendering there are much fewer limitations - who knows where all this will go? The effects should be amazing.