Raymarching Toolbox Thread
category: code [glöplog]
to get rid of the artifacts you should try replacing the taylorinvsqrt calls by 1.0/sqrt(), as i said earlier.. helped for me..
apart from that the 3D texture version should really be the fastest.. but there you suffer from the resolution of the tex and/or mem usage/cache issues.. i still prefer the original simplex version (but slightly tweaked, as simplex always looked much uglier than the (refined) perlin for most scenes)..
apart from that the 3D texture version should really be the fastest.. but there you suffer from the resolution of the tex and/or mem usage/cache issues.. i still prefer the original simplex version (but slightly tweaked, as simplex always looked much uglier than the (refined) perlin for most scenes)..
@toxie thats where perlins approximation comes in. It does a quaternion rotation using a lower resolution noise. By doing this he creates a seamless noise but that can be computed in about 15 clocks and at just about any resolution.
I did a simple test using distance fields just to see how it holds up in that scenario
100 steps, 5 octave turbulence at 1300x900
Perlins gpu version avg 65fps the noise las showed 14fps
But as you state the even faster one is just one 3d texture. Problem is you run into the issue with seams or repetitions. You can do a quite ok fireball using just one 3d noise texture though
I did a simple test using distance fields just to see how it holds up in that scenario
100 steps, 5 octave turbulence at 1300x900
Perlins gpu version avg 65fps the noise las showed 14fps
But as you state the even faster one is just one 3d texture. Problem is you run into the issue with seams or repetitions. You can do a quite ok fireball using just one 3d noise texture though
Quote:
the noise las showed 14fps
Which one compared exactly with which one? Code/url please.
+ iq: you've got mail.
@las
The last one you showed
The last one you showed
Quote:
float perlin(vec3 p) {
vec3 i = floor(p);
vec4 a = dot(i, vec3(1., 57., 21.)) + vec4(0., 57., 21., 78.);
vec3 f = cos((p-i)*acos(-1.))*(-.5)+.5;
a = mix(sin(cos(a)*a),sin(cos(1.+a)*(1.+a)), f.x);
a.xy = mix(a.xz, a.yw, f.y);
return mix(a.x, a.y, f.z);
}
replace acos(-1.) with pi ;)
You compared that one with a LUT noise? great.
You compared that one with a LUT noise? great.
as xetrick pointed out, the advanced gpu version that perlin published is more than your standard LUT based noise.. and its far less regular than the trickery that is shown above..
Just thinking in general, if we're defining pi in the shader:
pi = acos(-1.) might be less bytes than pi = 3.142etc, and more accurate. The compiler should optimise the acos() out too. Not sure how it would impact the compressor though.
pi = acos(-1.) might be less bytes than pi = 3.142etc, and more accurate. The compiler should optimise the acos() out too. Not sure how it would impact the compressor though.
Quote:
The compiler should optimise the acos() out too.
should.
Hmm considering LUT approaches then Xetricks method combined with a texture shader generating a perlin noise base texture would be size and speed wise an very good idea.
Nice russian blog with some interesting articles about noise http://blog.wonderville.ru
I'm curious what iq was/is about to do. We are waiting!
Yeah, me too. Maybe he wrote a paper on something and wants it peer reviewing? Or maybe he's forming a raymarching supergroup.
And to keep things on topic:
I just switched everything to signed distance fields. It's given me better speed and accuracy, because I can use much larger steps (in cases where it would step inside an object because of twisting or whatever, it then steps back to the surface. The fact that it steps back also helps with repeated geometry, when the ray sometimes steps to far into the next repeated area.
And to keep things on topic:
I just switched everything to signed distance fields. It's given me better speed and accuracy, because I can use much larger steps (in cases where it would step inside an object because of twisting or whatever, it then steps back to the surface. The fact that it steps back also helps with repeated geometry, when the ray sometimes steps to far into the next repeated area.
ohh damn... You are completely right! Just had to remove the "abs" and booooom ;) +5 fps
I'm more happy to see draw distance increase by about 5x ;)
Did anybody know if it is possible to write a distance function for rendering blobs/metaballs ?
Here is the classic equation :
But for raymarching we need a general distance function so summing distances wont work (division make it even worse, the distance is no more linear). We cannot remove that one because that make the metaball effect.
For simple sphere I would just do s = min(s, sphere(x,y,z) ) several times.
i'm trying to figure out how to do this since several hours, but no success...
Here is the classic equation :
Code:
for each metaball at (x0, y0, z0)
total = total + 1 / ((x − x0)^2 + (y − y0)^2 + (z − z0)^2)
if total <= threshold we hit
But for raymarching we need a general distance function so summing distances wont work (division make it even worse, the distance is no more linear). We cannot remove that one because that make the metaball effect.
For simple sphere I would just do s = min(s, sphere(x,y,z) ) several times.
i'm trying to figure out how to do this since several hours, but no success...
it is. check _the_ paper.
http://graphics.cs.uiuc.edu/~jch/papers/zeno.pdf
http://graphics.cs.uiuc.edu/~jch/papers/zeno.pdf
the paper posted by xernobyl sounds like the better solution, but i made up this metaball code for the gummibears in pacemaker:
i must have fucked up the inverse in mb2d since the result was a bit non-euclidean... but it worked.
Code:
float mb(vec3 p,float size) {
return 0.5-atan(length(p)-size)/pi;
}
float mb2d(float x){
x = -clamp(x,0.0001,0.78);
return (tan((x-0.5)*pi)+1.0);
}
//use it like this:
float dist = mb2d(mb(...) + mb(...) + mb(...) +...);
i must have fucked up the inverse in mb2d since the result was a bit non-euclidean... but it worked.
Thanks guys, i will post the results if i am able to get something interesting
I came up with this in my experiments:
Where m1, m2, m3 are distance to your metaobjects wannabes; r1,r2,r3 are corresponding "radiuses" of "metaobjects"(for cube it's half the height); e is some epsylon to avoid singularities; and magicNumber is something between "radiuses".
It sure is not real metaobjects, but it's pretty cool after all, I think. And you can do all the kinds of meta-anythings.
Code:
float m1 = sphere(...);
float m2 = sphere(...);
float m3 = cube(...);
float srf = 1.0/(m1+r1+e)+1.0/(m2+r2+e)+1.0/(m3+r3+e);
...
float dsrf = 1.0/srf - magicNumber;
Where m1, m2, m3 are distance to your metaobjects wannabes; r1,r2,r3 are corresponding "radiuses" of "metaobjects"(for cube it's half the height); e is some epsylon to avoid singularities; and magicNumber is something between "radiuses".
It sure is not real metaobjects, but it's pretty cool after all, I think. And you can do all the kinds of meta-anythings.
The method of a13X_B is really nice, it works with all kind of objects. i also try cupe formula.
Here is the results :
(metaballs + phong shading)
(same but with some physics)
Here is the results :
(metaballs + phong shading)
(same but with some physics)
Quote:
elevated
yeah nice... functions called "f", "cn", "m1" and so on, no documentation whatsoever. this really is 4k code, intended to be understood only by its author. too lazy to debug that to get how it works.
if, however, someone else would do that for me... ;-)
Noise implementation not using a texture
Did I post that before?
Did I post that before?
Is there a better (fast?) way to get normals from that perlin noise? Sampling a few more points sounds slow looking at the code length.
you get analytic derivatives for noise, it's very easy (hey, it's little more than a cubic function after all)