trick for 1k raymarchers :: lighting

category: code [glöplog]
I wanned to share something I found today when size-optimizing some code:

Given a potential function "float f(vec3 p)" one tends to do lighting by computing a gradient/normal at point "p" for later doing a dot product with the light vector "vec3 l" for getting some diffuse lighting. Like

Code: vec3 n; vec3 e=vec3(0.1,0,0); n.x=f(p)-f(p+e.xyy)); n.y=f(p)-f(p+e.yxy)); n.z=f(p)-f(p+e.y yx)); //n = normalize(n); float d=dot(n,l);

I think you probably want replace all that code with this one:

Code: float d=f(p+0.1*l);

The original code/method produces:

BB Image

while the new one, produces:

BB Image

I fyou are still unconfortable with the second method and want to stick to the first, remember that f(p)=0 anyway (or almost, as p is on the surface), so you can at least remove those...
added on the 2010-07-31 05:15:21 by iq iq
That is an impressive little size optimization. The only differences I can spot with my naked eye is some contrast differences and a single missing edge in the lower left corner.
Actually the bottom image is a bit smoother aswell. Anal coders will hate this but it's quite the nice little optimization :) Thanks for sharing.
added on the 2010-07-31 07:06:16 by ferris ferris
hey, I recognize those blobs :) that's a huge size improvement with minimal fidelity loss, thanks iq!
Ferris is right about the smoothness, look at the color banding in the top right corner on the top image :P
I have never coded a shader, but why do you multiply with 1 ?

float d=f(p+0.1*l);

oh, great, the code tag uses a font where L and 1 is pixel to pixel identical.

added on the 2010-07-31 15:48:39 by Oswald Oswald
the "l" is one pixel difference...but yes, i read a "1" first aswell :/

nice size-optimization, iq :)

i have all the lighting in one line for my 4ks but its still more like the first version, gives more control about light-position, but for 1k its ofcoz very usable :)
"l" is the light position, so there.
added on the 2010-07-31 20:32:58 by iq iq
not your fault anyway, iq ;)
maybe garg should change the font for code-boxes !
( if i read sth about code i always just sloppy watch over it, so ofcoz i didnt recognize the 1 being an l on first sight...doing code oneself rulez ! guess Oswald just had an half eye for the code aswell..hehe )
no difference here:

BB Image
added on the 2010-08-01 06:25:33 by Oswald Oswald
l and I has always been bad as variable names :-D
added on the 2010-08-01 10:34:38 by thec thec
Nice code snippet. But that shouldn't just be smaller code if I get that code correctly so is it also a major speed optimization. Going from 6 evaluations of the potential function down to 1 could clearly make a positive performance impact!
added on the 2010-08-01 10:50:45 by Xetick Xetick
Change your browser's default font settings, people.

(Pouet's CSS doesn't specify a font for code blocks, and even if it did, it would have to guess which fonts people have installed, because Courier is probably the only standard monospace one across all platforms.)
added on the 2010-08-01 12:59:29 by gasman gasman
At least enable cleartype ;)
Xetick: The performance boost isn't as big as it might seem at first, as you're already evaluating the distance functions shit-loads of times to find the surface. The lighting is generally done once per pixel, not per ray-step.
added on the 2010-08-01 17:17:10 by kusma kusma
"Change your browser's default font settings, people."

I guess pouet should use a default font which doesnt suck.
added on the 2010-08-01 17:34:33 by Oswald Oswald
As I view the first post, the first picture has noticeable color banding, while the second does not. Is this just my monitor being crappy, or what?
added on the 2010-08-01 19:06:06 by shuffle2 shuffle2
i guess its due to missing dithering, i.e. most (cheaper) monitors will show color banding for such 'smooth' gradients, as the monitor cannot display full 24bit colors..
added on the 2010-08-01 19:26:30 by toxie toxie
Toxie, I think that isn't the case. The theoretical-epsilon in the distance field function is actually not as small as it should be for a pixel-perfect sampling of the field. Hence the distance between two sampling points which is then used to deduce the normal might not be forming a perfect gradient hence creating the banding :).
added on the 2010-08-01 19:46:04 by decipher decipher
it is, just take a look at the picture values in a gfxprog.. all smooth (f.e. on the right, an almost perfect gradient), but on my monitor: 'stripes'..
added on the 2010-08-01 20:20:07 by toxie toxie
it's true, MOST modern LCD monitors use 16bit colour. Unless you bought a more expensive, higher-end screen, chances are you're looking at 64k colours right now. I have one of each, a decent IPS/24bit screen and a cheapo TN/16bit thing, it's a big difference.
added on the 2010-08-01 22:23:57 by psonice psonice
added on the 2010-08-01 22:35:41 by Zplex Zplex
The first render gradients are banded... its not your monitor, its the gradient.

By value its like 10,10,10,10,10,11,12,13,14,15,16,17,17,17,17,17,17

So you see smooth band transition. Even with the best monitor the first image will look really banded.

BTW. 24bit == 256 shade ... Even the best monitor show banding with 256 shades.
And 6bit monitor use trick to render > 64 shades , if they didn't they would look like total crap. and amazingly even the cheapest of the cheapest render 8bit gradient well (Its usually a user error in the monitor calibration when 6bit HW can render 8bit data without banding)

There you have it: Image 1 is banded, and its not your cheap monitor unless you calibrated it badly.
added on the 2010-08-01 22:48:36 by T21 T21
They use tricks to render >64 shades, but not always successfully. On my decent, 24 bit monitor the 2nd image looks better, very little visible banding.

On the cheap 16bit monitor, the 1st image actually looks better. Both show visible banding, not so bad as "true" 16 bit would look, but it's there. The 1st image now looks about the same as the 2nd image looks on my good screen. The 2nd image looks the same, but now there's visible flickering where pixels are swapping between two 16bit colours to make a colour between. It's like the old interlace tricks, but nowhere near so bad fortunately.

And btw, the flickering effect is truly horrible when you set the screen background to the wrong colour ;)
added on the 2010-08-01 23:30:13 by psonice psonice
Oh, and back on topic.. awesome bit of optimisation there. Much smaller and much faster.. but why? I don't get why it works at all :) (And I probably won't follow the answer, but I'll still ask)
added on the 2010-08-01 23:32:33 by psonice psonice