pouët.net

Sphere Tracing and Materials

category: code [glöplog]
Let's discuss techniques.

How would you apply two different colors to two different objects?
added on the 2011-03-24 01:59:07 by Danguafer Danguafer
err.....

Code: if( objectID==0 ) color = cuteColor1; else if( objectID==1 ) color = cuteColor2; else color = black;


????????

what's the question really? How to optimize it?

Code: color = niceTableOfColros[ objectID ];


how to make it GPU firendly?

Code: color = texture1D( paletteTexture, float(objectID)/256.0 );


or what is it?

Of course, if you don't care aesthetics and go for codecolors yo can always go for

Code: color = randomMagic( objectID );


You probably want to lookup for specular, diffuse, bump, sss and all other sort of other parameters too, not only a color, though.

But again, what is the question here?
added on the 2011-03-24 02:56:05 by iq iq
inouts ;)

initialize and declare colors in main() and set em accordingly to your desireness in the dist(), so it´ll have the correct value once you need it in the getNormal()
...yes you need to have an inout in every func/dist()
... in the getNormal() you can set it to whatever you want tho ;) ( no inout here! just call the dist() with a "0" for color there )

dunno shit about oGL, so if you dont know what i mean with "inout", google it against oGL-instruction-set :p

Code: pseudo: dist(float3 p, inout colorSwitch) { colorSwitch = 0; // needs to be set in every dist()-func atleast once, better just set it just once you know which sort of object got hit accordingly ;) the hit object is to be found via the dist-Function itself, depends on every object tho, so no deeper insights here, sorry ;) makes no sense, but if you know what you are doing you know how to set this flag for your distance-function!! [...] } getNormal(float3 p) { int colorSwitch = 0; // doesnt matter, no changing inout used, just here to call dist() 4-6 times ;) --> dist(p, colorSwitch); [...] } main() { float4 colors[2]; colors[0] = float4(1. ,0. ,0., 1.); colors[1] = float4(0. ,1. ,0., 1.); int colorSwitch = 0; float n, d=1.; [...] d = dist(p, colorSwitch); [...] n = getNormal(p); [...] // finalColor = colors[colorSwitch]... return colors[colorSwitch]... }
Gargaj: can we has [PseudoCode][/PseudoCode] already?
its a lot of pseudo-code to be written here ;)
i think you win the price for longest rant in a code comment.
Sorry if it wasn't clear. I was looking for techniques for getting obj ids using dist fields.
added on the 2011-03-24 08:11:05 by Danguafer Danguafer
I've just been returning a packed vector from the field funtion. I currently only use three elements to return four values, so there's scope for more material data to be packed in there.

// return: result.x = distance, result.y = shininess.hue, result.z = diff_lightness

This lets you do more funky things than just one material per object. It also doesn't seem to impact the frame rate on my (simple) scenes. It does make my field function more complex though.

BB Image


BB Image
added on the 2011-03-24 09:22:15 by evilpaul evilpaul
I think the main thing is to know which object you hit, then there's all kinds of ways to handle it. For now I'm just returning a vec2 from the field function, with distance and material id.

Instead of something like:

Code: float f(vec3 p){ return min( cube(cubePos, p), sphere(spherePos,p) ); }


i do something like:

Code: vec2 f(vec3 p){ float c = cube(cubePos, p); float s = sphere(spherePos,p); return c < s ? vec2(c, 0.) : vec2(s, 1.); }


Then you have both distance, and a material/object id. I've just used it for colour so far. But it's quite easy to use it to change lighting, or turn on/off shadows/reflections/SSS/etc too, which might even help with speed.

On the downside, it could be faster.. I've not optimised much yet.
added on the 2011-03-24 10:25:05 by psonice psonice
evilpaul: the fps counter is telling you to use a shader :D
added on the 2011-03-24 10:26:31 by psonice psonice
I do something like psonice too...
But I use a global float.

Code: float m; // <-- contains the final ID float f(vec3 p) { m = 0.; // <-- init R(p.yz, pi/6.); p.y+=1.9; vec3 q=p; R(p.xz, t); float d = spikeball(p)+fsn(p*100.0)*0.01; float nd = dot(q+vec3(0.,3., 0.), vec3(0., 1.,0.)); m = mix(m,1.,step(nd, d)); // if nd closer, set to 1. else keep previous value, for this case m = step(nd, d)... return min(d,nd); }


Care has to be taken then in the "main", you have to save your "m" locally before calling e.g. calcNormals.
Another possible ways:
- Encode the material in the lower 3 bits of the mantissa of the distance.
- Generate a second field function for material determination (you only need that one time after you have found your hit).
added on the 2011-03-24 12:14:43 by las las
that's the prettiest YMCA-cube i've ever seen, paul!
added on the 2011-03-24 12:32:15 by maali maali
i probably should have removed the hud, the fps counter isn't accurate..

psonice: what makes you think that i'm not using a shader?
added on the 2011-03-24 13:13:13 by evilpaul evilpaul
Your stuff is too slow ;)
added on the 2011-03-24 13:31:09 by las las
paul: all your processing stuff from twitter, and the framerate? :D Or is that something else, and the fps is a lie? Or is it just running on a bad GPU? (I've tried my own stuff on my intel based laptop... i gave up waiting for the first frame to render)
added on the 2011-03-24 13:34:39 by psonice psonice
yeah, as i said above, the fps isn't accurate in those shots and this is all standard-ray-marching-on-the-gpu stuff. i'm not really seeing any difference in speed when i'm using this technique but i do have fairly simple scenes. the last picture gives me about 10-20fps on a hig-spec but old laptop. that's better than most of the ray marching demos i've run from the past couple of years but, again, these are simple scenes

the processing stuff i've done is something else completely - it's just something i did for kicks
added on the 2011-03-24 13:48:44 by evilpaul evilpaul
ah right. Just assumed it was the same stuff :)

Anyway, you'll hate me for this, but somebody just left a 3ds on my desk :D Strange thing to happen at work. I didn't order it, and it had somebody else's name on the box, but he didn't order it either. So now we have a 3ds and no idea who its for or why it's here.

Still, cool 3d effect :D Not sure I'd want to use it for any period of time, but I'd love to code demos on it!
added on the 2011-03-24 13:56:59 by psonice psonice
Danguafer look @:
http://www.opengl.org/resources/faq/technical/color.htm#0040

More than two object here.
Qui peut le plus peu le moins.
added on the 2011-03-24 16:07:01 by Orace Orace
orace: we're talking sphere tracing, not regular rasterised objects.

In fact there is only one 'object' on the opengl side that you could assign a colour to, a single quad. The scene gets rendered entirely inside the shader, and it's not simple to separate the objects.
added on the 2011-03-24 16:14:35 by psonice psonice
for primary rays you could trace each object for its own and let the zbuffer make the occlusion.. that way for instance you could use boundingrectangles to get more performance and could do several optimizations per object.
added on the 2011-03-24 20:53:38 by mad mad
Using the zbuffer is an interesting suggestion.

For bounding boxes - I already do something like this. If I have a 'ground' with some stuff on it, and I know nothing is higher than say 2, I start the ray at the intersection with that. And if the ground itself is at 0, I find the length of the ray to that, and use that as a bailout point. That saves a ton of iterations in some cases, especially when the camera is parallel to the ground (which it usually is).
added on the 2011-03-24 22:43:47 by psonice psonice
I can't see how to gain anything from the depthbuffer.
added on the 2011-03-25 00:56:58 by raer raer
You could render all bounding boxes of objects to the depthbuffer in the first pass and then use that in the second pass to get a safe "first step distance". I don't really know if that's worth the effort as you could also check bounding boxes first when raymarching...
added on the 2011-03-25 15:12:44 by raer raer
Is it possible to write to depth and read back again? Might be possible to save some min() functions ( but what about max(a, -b)?)
added on the 2011-03-25 15:45:37 by psonice psonice
Possible with FBOs, but needs special extensions.
added on the 2011-03-25 16:39:34 by raer raer
if you render every "object" for its own you can easily give every object a different material at no costs in the renderer (like the topic suggested).. but i didn't understand iqs post, i mean how to easy get an objectid with the normal approach?
added on the 2011-03-25 19:23:47 by mad mad

login