Skip to main content
GameDev.net gamedev.net
🔒 Locked

How occlusion works?

Started by Ruggostein Apr 20, 2010 at 1:28 PM 8 replies 1.9k views
Original Post
Ruggostein
Ruggostein
I'm implementing static occlusion maps. My idea about occlusion is that it represents the ammount of ambient light at a given point. So in the shader, I do something like this color = ambient * occlusion color += diffuse * NdotL + specular etc The result was this, doesnt look good. Then the shader was changed to color = occlusion * diffuse * NdotL + specular etc And this is the result, way better, but now, its like I'm using the occlusion map as a lightmap. Can someone explain to me if I'm doing something wrong?
Krypt0n
Krypt0n
ambient occlusion has not really a logical definition, there are several ways people generated it, so there are as well several ways to apply it and you should just care about what looks best for you.

color = ambient * occlusioncolor += diffuse * NdotL + specular

that is not uncommon, but I've also seen that one
color = (ambient + diffuse * NdotL)* occlusion + specular etc
(similar to yours but you missed the ambient in your 2nd sample.

I've also seen some shaders that used a lerp too blend between ambient and diffuse using the ambient a lerp-factor.
color = ambient * (1.f-occlusion) + diffuse * NdotL * ambient + specular

In that case the ambient was quite dark'ish.


One version I've seen was calculating
ambient=ambient*ambient;//ambient [0.0-1.0]

first and the guy that was doing that said it's done cause saving it in none-linear form would show off artifacts due to dxt compression.

Applying it as a lightmap would mean to use it additive to all the other light sources, I wouldn't do it that way. The more light sources you have, the less you'd notice it and imo that would look less good.

[Edited by - Krypt0n on April 21, 2010 2:43:58 AM]
Hodgman
Hodgman
Quote:
Original post by Krypt0n
color = ambient * occlusioncolor += diffuse * NdotL + specular
Yeah I use this one - the AO map only has an effect on the ambient lighting. If you use your second one it's technically an "Ambient and Diffuse Occlusion map" (not just AO).

Also, there's another form of lightmapping which is more like:
color = (lightmap + diffuse) * NdotL + specular etc
which is different from your 2nd function again.
Quote:
One version I've seen was calculating
ambient=ambient*ambient;//ambient [0.0-1.0]
first and the guy that was doing that said it's done cause saving it in none-linear form would show off artifacts due to dxt compression.
That's a really cheap approximation for decoding a gamma-space texture to linear-space. Alternatively you can make use of any available sRGB hardware or use pow( 2.2 ) instead of squaring (assuming your textures are in gamma-space).
Ruggostein
Ruggostein
Thanks you both, now I understand this better.
However, I have another question. When the faces of the object are facing away from the sun light, the dot product for lighting is zero, and now the only color used for lighting is the ambient term.
However this makes all of the building looks entirely the same color, and of course this is not what happens in real life, I think. What else can I add so it looks better, more lights? I though about that, but I'm doing an outdoor city enviroment, during the day, so the only lightsource should be the sun, or not?
Simon_Roth
Simon_Roth
Quote:
Original post by Relfos
Thanks you both, now I understand this better.
However, I have another question. When the faces of the object are facing away from the sun light, the dot product for lighting is zero, and now the only color used for lighting is the ambient term.
However this makes all of the building looks entirely the same color, and of course this is not what happens in real life, I think. What else can I add so it looks better, more lights? I though about that, but I'm doing an outdoor city enviroment, during the day, so the only lightsource should be the sun, or not?


You are correct, add more lights!

3 point lighting would be the place to start. A fill Light, and backlight and a key light in photography/vfx terms. It will bring out the details and add variation to your scene.

Of course then you want to think about light emitting or reflecting surfaces... radiosity etc.
Hodgman
Hodgman
Quote:
Original post by Relfos
I'm doing an outdoor city enviroment, during the day, so the only lightsource should be the sun, or not?
In real life, the buildings across the street reflect some sunlight, which essentially makes them act like huge area-light sources. You can fake this with "fill" lights - make some point lights with large radii and small light levels, just to add some variation and bring out the shape of things in the scene.
Helicobster
Helicobster
Quote:
Original post by Relfos
When the faces of the object are facing away from the sun light, the dot product for lighting is zero, and now the only color used for lighting is the ambient term.
However this makes all of the building looks entirely the same color


You should consider your ambient light as a directionless diffuse term, which is also affected by the colour of the surface. For example, if the ambient light is white, and the bricks are brown, the bricks should still appear brown under ambient light alone.

Your current ambient term is:
color = ambient * occlusion

What you want is:
color = ambient * diffuse * occlusion
...and then add your diffuse & specular stuff.
Krypt0n
Krypt0n
Quote:
Original post by Relfos
Thanks you both, now I understand this better.
However, I have another question. When the faces of the object are facing away from the sun light, the dot product for lighting is zero, and now the only color used for lighting is the ambient term.
However this makes all of the building looks entirely the same color, and of course this is not what happens in real life, I think. What else can I add so it looks better, more lights? I though about that, but I'm doing an outdoor city enviroment, during the day, so the only lightsource should be the sun, or not?

The trick is to improve your ambient term, instead of just adding one simple color, it's common to use several ambient colors and blend them based on the normal.

FunkyAmbient = saturate(normal.x)*AmbientCubeColor0+               saturate(-normal.x)*AmbientCubeColor1+               saturate(normal.y)*AmbientCubeColor2+               saturate(-normal.y)*AmbientCubeColor3+               saturate(normal.z)*AmbientCubeColor4+               saturate(-normal.z)*AmbientCubeColor5;

you can give artist control over those ambient colors (the artist of the last company I worked for loved it).
They will probably setup something blue'ish from the backside (in respect to sun) cause of the sky illumination, something green'ish if on grass or dark blue'ish if on road for the ambient faces pointing down. sides are usually slightly more red'ish than the forward faces and forward and upward pointing faces are yellow'ish.
In combination with that, the sun color can be white (not yellow like usually made), that leads to nicely white speculars, which are not really correct, but when seen on car chassis or other metalic surfaces, look still better than some yellow.

And best of all, while staying quite cheap (1mul+5mads and saturate is usually for free, so that's cheaper than one extra back-light), it shows of your normalmap everywhere, while the issue with a simple ambient is that you won't see anything related to normals at all (so that doesn't make just boring lighting, but looses surface details).
Hodgman
Hodgman
Quote:
Original post by Krypt0n
The trick is to improve your ambient term, instead of just adding one simple color, it's common to use several ambient colors and blend them based on the normal.
...code...
That's a neat way of doing it =D In HL2 they use a 1px cube-map to do the same thing, but I'd never thought of just using 6 constants.

In our last project we used 64px cubemaps for ambience, but our lighting artist actually wanted to use SH-probes like in Killzone 2 (pdf somewhere, can't find the link atm).
Krypt0n
Krypt0n
Quote:
Original post by Hodgman
Quote:
Original post by Krypt0n
The trick is to improve your ambient term, instead of just adding one simple color, it's common to use several ambient colors and blend them based on the normal.
...code...
That's a neat way of doing it =D In HL2 they use a 1px cube-map to do the same thing, but I'd never thought of just using 6 constants.

I have to disagree, they use constants to my knowledge.
taken from their shading paper
http://www2.ati.com/developer/gdc/D3DTutorial10_Half-Life2_Shading.pdf page 59
float3AmbientLight( const float3worldNormal){  float3nSquared= worldNormal* worldNormal;  int3isNegative= ( worldNormal< 0.0 );  float3linearColor;  linearColor= nSquared.x* cAmbientCube[isNegative.x] +  nSquared.y* cAmbientCube[isNegative.y+2] +  nSquared.z* cAmbientCube[isNegative.z+4];  returnlinearColor;}

But it's kinda old, maybe they changed that?

They use that just for dynamic object, static objects auf anyway radiosity bumpmaps. The nice "extra" they have is that they raycast from the object to 6directions, picking the radiosity color from the static geometry they hit and use that for the six-side cube.
I've used the six-side cube for all objects, we had no prebaked lightmaps tho.


Quote:

In our last project we used 64px cubemaps for ambience, but our lighting artist actually wanted to use SH-probes like in Killzone 2 (pdf somewhere, can't find the link atm).

I was testing that as well (seen that in another engine), but it added just complexity without adding noticeable quality, so I kept the simple solution.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.