Raymarching Beginners' Thread
category: code [glöplog]
rare: if you just use it for DOF, yeah. You could do other things though. Bend the ray, reflect it. Increase the distance step after passing the only twisted object in the scene. Maybe it's not something widely useful, but I think it could be good in odd cases at least.
las: maybe that's it. I'll have a look, see what happens if I set my steps to full length + the bailout to 0. Where I saw the problem worst was in the distance, after travelling nearly parallel to a surface, so possibly it was just running out of iterations before hitting the surface.
las: maybe that's it. I'll have a look, see what happens if I set my steps to full length + the bailout to 0. Where I saw the problem worst was in the distance, after travelling nearly parallel to a surface, so possibly it was just running out of iterations before hitting the surface.
psonice: I do:
That's probably why it works for me...
Code:
if (l < 0.001) {
//calc normal
}
That's probably why it works for me...
is that to break from the rm loop? what do you do if l>0.001?
If you need the branch, does it not make more sense to just use the longer normal calculation?
If you need the branch, does it not make more sense to just use the longer normal calculation?
I just tested it... High stepsize (i.e. 1) - low threshold -> f(p) -> 0. = everything is fine.
But us soon you lower the precision and or the stepsize... And with rotations and stuff I need to lower the stepsize.
But us soon you lower the precision and or the stepsize... And with rotations and stuff I need to lower the stepsize.
*as
I've poste my rm loop already, but:
...works for me(tm)
Code:
vec3 grad(vec3 p) {
vec2 e = vec2(0.001, 0.0);
return vec3(field(p+e.xyy), field(p+e.yxy), field(p+e.yyx)) / e.x;
}
vec4 rm(vec3 p, vec3 d, float maxSteps){
vec3 startPos = p;
float i, l=1.;
for(i =0.; i<1. && l>.00001; i+=1.0/maxSteps) {
l = field(p);
p += (l * d *.5);
}
float dist = length(startPos - p);
if (l < 0.001) {
vec3 n = grad(p);
float r = max(-dot(n,d), 0.0);
float fog = 1.6 / dist;
return vec4(mix(n, vec3(1,1,1), vec3(r,r,r)), dist);
}
else {
return vec4(0, 0, 0, dist);
}
}
...works for me(tm)
d
I tried using unc's smooth iteration glow code (http://www.pouet.net/topic.php?which=7931), but whatever I do I still get banding when I use low max iterations. I don't even... :/
try
a+=smoothstep(.0,.0001,f(p));
a+=smoothstep(.0,.0001,f(p));
Mewler: that things is heavily scene depended, you have to play with ALL values until you get somewhat smooth results.
Tried making a spiral from a cube:
Small step size is required.. is there a good "general solution" for a spiral like this, rather than modifying the x/y coords of the cube/sphere based on z?
Small step size is required.. is there a good "general solution" for a spiral like this, rather than modifying the x/y coords of the cube/sphere based on z?
Nice spiral :)
Hmm... Your solution seems to work fine, so why try harder? ;)
That should be the most simple way to do a spiral like that.
Hmm... Your solution seems to work fine, so why try harder? ;)
That should be the most simple way to do a spiral like that.
Yeah, it works.. just thinking that a solution that allows a bigger step size would be better.
psonice: calculate a conservative distance first (distance to the spiral itself) with bigger steps?
i guess i could calculate the intersection of the ray with the 'tube' the spiral is inside. Then take the maximum of that and the actual distance function. That would give fast + error free stepping to the boundary of the spiral, then there is just the spiral itself to worry about.
Which raises a question, thinking about it: say the distance function could return two values, the distance, and a 'safe stepping distance'. If you have a twisted cube, you know it's safe to step by say 0.9 * l when you're far away, and 0.25 * l when you get close.
If all your functions return a safe step, you can pass the minimum safe step to the raymarcher and move forward much faster without losing accuracy.
Worth trying for extra speed in some cases perhaps? Of course it won't help size optimisation ;)
Which raises a question, thinking about it: say the distance function could return two values, the distance, and a 'safe stepping distance'. If you have a twisted cube, you know it's safe to step by say 0.9 * l when you're far away, and 0.25 * l when you get close.
If all your functions return a safe step, you can pass the minimum safe step to the raymarcher and move forward much faster without losing accuracy.
Worth trying for extra speed in some cases perhaps? Of course it won't help size optimisation ;)
I'm dreaming of a sampler_backbuffer and fast branching and arbitrary array indices in shaders...
You're dreaming of cpu rendering ;)
true. :D And a white christmas ;)
What is the cheapest way to set up an FBO (bytewise)?
For that postprocessing stuff I mean...
rare: if you can get away with it, it's probably cheaper just to do glCopyTexImage2D to texture 0.
glTexImage2D with RGBA8 and then glCopyTexImage2D the framebuffer to texture 0? But then I have no depth and only 8 bits... :/
you could write depth to alpha. It'll still be 8 bit though
Just cause: Isn't there any GL extension or code available that renders the depth at full precision and an independant format into a second rendertarget?
BTW. lol. This also barely works in DX with bogus additional code. -.-
BTW. lol. This also barely works in DX with bogus additional code. -.-
You COULD use FBOs. I was just asking for a cheaper method.
Apparently you can use glCopyTexImage2D with GL_DEPTH_COMPONENT to a float texture. Makes 2 textures then...
Apparently you can use glCopyTexImage2D with GL_DEPTH_COMPONENT to a float texture. Makes 2 textures then...