Sign in to follow this  
Tree Penguin

Why does sqrt-ing light values give a better result??

Recommended Posts

Hi, i am working on my rendering engine and i just mentioned i am, from the beginning of my project, doing this: Color fcol( sqrt(finalcolor.r), sqrt(finalcolor.g), sqrt(finalcolor.b)); fcol.Clamp(); glColor3f(fcol.r,fcol.g,fcol.b); Is there a common reason i have to sqrtize the values to get the right results?

Share this post


Link to post
Share on other sites
It would depend on how you're calculating the 'finalcolor' variable's value. Point lighting's intensity depends on the distance to the light, which would involve a square root, so maybe that has something to do it?

Share this post


Link to post
Share on other sites
Quote:
Original post by Extrarius
It would depend on how you're calculating the 'finalcolor' variable's value. Point lighting's intensity depends on the distance to the light, which would involve a square root, so maybe that has something to do it?

I divide the emission of the emissive texel/point light by the distance, and it appears i have to do another sqrt on that to get the proper result, else the light is decreasing in strength to 0.0 almost instantly.

BTW, finalcolor is just all lighting added together, which i currently have limited to just the direct lighting.

EDIT: i'm just curious if it's a common thing or if it's my lighting method that causes the need for it.

Share this post


Link to post
Share on other sites
by sqrt-ing you are applying something similar to tonemapping.

obviously lightvalues as encountered in reallife have a huge variety. however, a monitor can only produce a very limited range of intensities. therefore, some sort of nonlinear mapping of lightvalues to your screen gives the best illusion of high contrast (as compared to ugly capping artifacts), certainly when combined with funky postprocessing such as glow and halo effects.

usually a logarithmic mapping is used, however this is what i use in my raytracer, cos its a little faster and produces good results. sqrt also has a similar graph:


Color ToneMap(Vector3 l){
Color col;
float lO, lTM;
lO = 0.27*l.x + 0.67*l.y + 0.06*l.z;
lTM = lO / (lO + HalfLight);
l.x = l.x / lO * lTM * 256; if(l.x>255) l.x = 255;
l.y = l.y / lO * lTM * 256; if(l.y>255) l.y = 255;
l.z = l.z / lO * lTM * 256; if(l.z>255) l.z = 255;
col(cast(ubyte)l.x,cast(ubyte)l.y,cast(ubyte)l.z);
return col;
}

Halflight is a sort of constant you can compare with a shutter value. you can make it so that it adapts to the brightness of the overall scene as to provide a pupil effect.

anyway, i dont think im very good at explaining, but googleing tonemapping might open up a whole new world of graphics programming for you.

Share this post


Link to post
Share on other sites
Quote:

and it appears i have to do another sqrt on that to get the proper result, else the light is decreasing in strength to 0.0 almost instantly.

youre hitting the nail on the head here. this is also the case in reallife: if you look at a lamp brightness a meter away from the lamp in orders of magnitude lower than the lamp itself.

therefore, a linear mapping wont suffice. either you have to cap a lot, or make the room pitchblack except for one spot. irl your eyes take care of this, but in the case of a monitor you have to simulate these effects before outputting to your monitor, cos your monitor cant handle really bright things.

i find it very cool how a picture with good postprocessing producing glow effects and such, really makes you squint your eyes, while infact the pictuer is less bright than the white explorer page around it :)

as for the reason a logarithmic mapping (or something that looks like it) should be used, compare it to a photo. photos are also able to deal with quite high contrast ranges. this is because the chemicals that are in the film decay logarithicly when exposed to light: the less there is left the less there is to decay. it tends to 0 as the amount of light goes to infinity, but in general it doesnt decay as much anymore when dealing with already high luminance values, while still bringing out the more subtle details.

Share this post


Link to post
Share on other sites
I got it (after a few times of looking at lights and placing lights next to my monitor i think i truly got the idea), i think i will mess around with it a bit and see what i can do with the actual 96 bpp image.

Share this post


Link to post
Share on other sites
You should always keep in mind the fact that monitors are different from our eyes. Monitors can only display colours up to a finite brightness. Our eyes, on the other hand, can handle very, very bright colours (even so bright as to make us blind).

In this sense monitors are more similar to "film" than to our eyes (the difference is that film paper only reflects light, whereas a monitor emits light, I think here could be some good grounds for design of future, eye-convenient displays btw!).

Therefore, when doing computer graphics, I see it better trying to go for a "film look" (because it's possible) rather than "eye look" (because it's impossible).

Stepping a little side, from this I argue that lens flares aren't that bad in computer games, given that they should emulate actual cameras (afaik, in most camera work, lens flares are avoided, but they can be a powerful effect sometimes).

OK, then to the point: given the fact that monitors can only show a finite brightness, you need to convert your light values (0...infinity) to a definite range (0...1). You, for example, use clamping. Many different options are available. As others have pointed out, this process of mapping the simulated color spectrum to screen colors is called tone mapping.

- Mikko

Share this post


Link to post
Share on other sites
as for the square rooting, it's very simple.


You have a light source, lets say it's a Sealed Beam off a car or spotter (these are the round ones that don't burn out like most modern headlights - something you would find on a military vehicle or an older model good/high quality car).

Anyway.
Lets say it spits out n photons of light.

This amount of photons (n) acts on an area.

So what you have is an intenisity of n/area.

Since light travels in a straight line in a closed system, it means that the diametre of the area increases in a linear fashion.

So at lets say 1 metre, it's 1 metre wide.
at 2 metres it will be 2 metres in diametre.

And since we are dealing with area it is at a factor times the diametre to the power of 2.

So that gives us

intensity=n/area

and lets give us a function for area (lets assume it is a circular beam that comes from a point).
d = diametre (equally proportional to distance)
area=Pi·d²/4

so that all gives us

intensity=(n·4)/(Pi·d²)

or

(density of photons)/intensity @ (distance D)=(n·4)/(Pi·D²)

for a more general equation

intensity @ D=n·F/D²
where F is a factor (in the example it was Pi/4


That's the reason why light intensity looks better (and is realistic) following a square root function. It's area.

Share this post


Link to post
Share on other sites
no thats something else i assume he has taken care of earlier in his code, and that is that lightintensity falls off with distance with the inverse square of the distance, ie 1/D^2.

tonemapping partly reverts (to the eye) this rediculous high falloff rate, you could say.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this