The constant ambient factor - how to use it to your advantage - and why you shouldn't

The constant ambient factor

The constant ambient factor (or sometimes referred to as simply "ambient lighting") is an older and simpler solution to handle an issue with direct lighting - that being that any of the scene not being directly lit is completely dark 

So, let's try to write down whats happening and what indirect lighting actually does to handle it? 

Ok so lets write up a basic lighting equation: 

Lighting = albedo x (direct + indirect) 

(this is an oversimplification, and is only for demonstrative purposes!) 

Cool, now we can write up what the issue is when we dont have indirect lighting!

lighting = albedo x direct = 0

Ok, so hopefully you can see whats actually happening here - the light reflected into our eye is black - or 0. Now this can only happen if either albedo or direct is equal to 0. Now, the albedo should never equal 0, so we can assume that it's the direct lighting that results in it equaling 0! 

So, in order to avoid this we can add the ambient factor! This results in the following equation 

lighting = albedo x (direct + ambient)

Which means that the total lighting factor can never be less than albedo x ambient, which means that the issue with all of the scene not being directly lit is gone! 

Awesome! So now everything is swell and all our lighting is awesomely awesome right! No, of course not

As some readers probably already understand, the ambient factor is a constant - meaning that the amount of lighting is going to be constant in all of the areas of the scene not being directly lit. This means that all of the parts of the scenes not being directly lit are going to look incredibly flat! 

Using the constant ambient factor properly

So, we now have one big issue - everything in your scene that isn't directly lit now looks incredibly flat. Fortunately - this issue can be addressed! We could try using the normals for the objects in our lighting equation! 

lighting = albedo x (direct + (normal*ambientdirection x 0.5 + 0.5)ambient)

Now, the ambient direction is for you to decide, you might choose for it to be the direction of your primary light source, maybe the inverse of that, or anything inbetween! Point of is that now your constant ambient factor isn't as constant anymore, and the problems constant ambient factor is gone!... right? 

Why you shouldn't


Unfortunately one issue still remains. Let us consider a completely isolated box, where no lighting is let through. Now, with the direct + indirect solution; we would get this

Lighting = albedo x (direct + indirect) = 0

if our direct + indirect lighting is calculated properly, this is what would result in this scene (because like we covered before no lighting is let through the box

So, let's plug the same scene into our more advanced constant ambient factor

Lighting = albedo x (direct + (normal*ambientdirection x 0.5 + 0.5)ambient) = albedo x (normal*ambientdirection x 0.5 + 0.5)  

This means that the lighting in the scene is directly dependent on that dot product between normal and ambientdirection which means that very rarely is the result going to be 0 (as normal and ambientdirection have to be opposing each other)

The reason this happens is that the constant ambient factor doesn't change depending on the scene geometry, it is only dependent on the normal and ambientdirection. This means that sorrounding geometry isn't taken into count when calculating the ambient lighting. 

Is there anything I can do about this?

The simple answer is yes, all you have to do is switch to the other calculation with direct + indirect lighting. However, this might not be a good solution for your case as calculating the indirect can be very costly. Fortunately we can still be a bit more clever about this - here is a more advanced constant ambient factor setup that; while it still is a far cry from the direct + indirect solution it's still miles ahead of what we had previously 

Lighting = albedo x (direct + cubemapsample x ambientocclusion)

Now, the cube map sample can be collected by sampling from a low frequence cube map (which can be done by taking a high mip factor from a regular cube map) from the direction of the normal. Ambient occlusion can be calculated by a number of different methods - the primary one being screen-space ambient occlusion first introduced in the original crysis back in '07.




Comments

Popular posts from this blog

Update on Mirage

An introduction and whats to come

The primary problem with realistic rendering, and how mirage aims to solve it