Ambient Lighting

Started by
5 comments, last by zedzeek 19 years, 3 months ago
Any ideas on how to calculate the overall light "direction" for ambient lighting? For outdoor scene you would just use the sun as the primary direction. However if you are in a room with a few lights, possibly varying in elevation, but are not near any of the lights or the closest light is being obstructed, textures will not appear to have depth. Light is the key to bumpmapping. For awhile I was just creating a fake light at the camera origin to partially illuminate surfaces so ambient surfaces were bumpmapped. What I'd like to do is calculate the light vector dynamically based on x lights. Any ideas? Its pretty late so my brain is kinda fried, but I was thinking maybe calculating the light direction for each "visible" light, and then doing repeated CrossProduct for each light. then normalize then throw it into a modified phong equation that clamps specular highlight to the ambient value.
Advertisement
I could easily be wrong, but isn't ambient lighting designed specifically not to have a direction? Ambient illumination is applied to all objects whether shadowed or not, it is the lowest possible value for lighting in a given scene. The ambient colour that is given to materials in the traditional material shading pipeline then specifies the degree to which a given material is lit by this ambient lighting. i.e. dark grey ambient illumination and full yellow ambient material colour give dark yellow when combined (assuming all other colour components are black). Diffuse lighting takes care of the more traditional directional lighting (dark when facing away from light, bright when facing towards light). I realise that this might look a little strange if it meant that unlit things weren't bumpmapped - for that case all I can suggest is giving the player/camera some kind of headlight, which sounds like what you were doing. Any kind of averaging of the light directions in a scene and applying it as ambient would be quite odd as it would ignore light occlusion. I had a quick look at Doom 3 while writing this reply and in it if something is completely shadowed and none of the lights in a scene are active on it, the area is made completely black. Works well for their shady environments, I suppose. Good luck.
Ambient Light is really just a hack to make realtime illumination look better.

Traditional realtime per-vertex or per-pixel lighting usually only models "direct" illumination, i.e. the light rays from the light source that directly hit the object that illumination is being computed for. Additionally, traditional realtime lighting assumes the light source to be an infinitely small point or ray.

In the real world, much of what we see is illuminated by *indirect* light, i.e. once light from the light source has directly hit objects in the scene, some of the energy left over bounces those objects off and provides illumination for other objects. The colour of the light can also change depending on the material of the object(s) the light hits (most materials absorb various wavelengths of light in varying amounts). Finally, real world light sources have an area/volume, many have shades which absorb some of the light and scatter it more, some (such as car headlights) have lenses which refract and direct the light; even sunlight gets scattered by the atmosphere, etc

"Ambient light" is really just "fudge value to make up for the indirect illumination things we can't model in realtime".


Techniques such as radiosity and ray tracing to compute the indirect illumination "properly" aren't really [currently] very practical in realtime.


There are better ambient hacks/approximations available though [smile]. For example:

- hemisphere lighting: imagine an outdoor scene with grass on the ground and a blue sky above. For an object in this scene, the under side of the object would have more of a green tint (indirect light reflected from the grass), and the top side of the object would have more of a blue tint (sunlight hitting the earths atmosphere and being scattered, turning it into a big blueish "area light"). With hemisphere light, you assume the object is surrounded by two hemispheres which form a sphere - the top one is sky coloured and the bottom one grass coloured; from the normal of a vertex, you can determine whether it points towards the sky or towards the ground - the ambient colour you choose for that vertex is then an interpolation between the sky colour and the floor colour with the direction of the normal controling how much of each (if the normal points straight up, it gets 100% sky, down for 100% ground, out to the side 50% of each. Most of the indirect colour will usually come from the second bounce of the light ray, so this generally looks ok (much better than a single ambient term).

- "Hemisphere Lighting With Radiosity Maps" : http://www.gamasutra.com/features/20030813/hargreaves_01.shtml

- Spherical Harmonics

- Ambient cube maps (use the normals to look up a cube map of the local environment to do a sort of per-pixel version of hemisphere lighting)

It could even be feasible to ray trace in a few basic directions per object (i.e. cast, say, 8 rays out from an object, per light).


Regarding dot3 bumpmapping (aka normal mapping), if the light doesn't move with respect to the object, then for diffuse illumination is not really much more than a posh version of detail texturing with per-pixel correct highlight and shadow - it'll add more detail, but won't really help make the feeling of depth much. Improving your ambient lighting still won't really help make it look any more bumpy. Specular bumpmapping OTOH will change with respect to the camera/viewer, even if the object/lights don't move - sticking a light to the camera is essentially doing a kind of [incorrect] specular anyway [with careful choice of exponent, it needn't look like shiny plastic].




Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Here is a presentation where I mention a technique I came up with to handle a similar situation.

http://developer.nvidia.com/docs/IO/9078/Modern-Graphics-Engine-Design.pdf

In my case it was to have bump mapping from a single 'averaged L' direction, rather than ambient light, but you could certainly apply the same technique.
Another neat "better ambient" trick is ambient occlusion with bent normals. For each vertex on the object (or texel in some sort of per object unique texture) cast a number of rays outwards scattered over the hemisphere centered on the local normal and count the number that hits the model itself. The amount of hits determines the occlusoin factor and thus the amount of light you apply, less hits means less light. If you combine this with replacing the normal with the average of the rays that passed (the "bent" normal) and use that for one of the previously mentioned ambient approximations, things can look pretty good. And since it's all done pre process it's really cheap.
ive done something like (i forget exactly but it may give u an idea)
lerp( dot( light, bumpmap )*diffuse_color, dot( -light, bumpmap )*ambient_color, dot( light, bumpmap ) )
actually now i think about it that equation is terrible
lerp( dot( light, bumpmap ), diffuse_color, ambient_Color )
(edit i mean)
lerp( dot( light, bumpmap )*0.5+0.5, diffuse_color, ambient_Color )

[Edited by - zedzeek on January 3, 2005 1:09:22 PM]

This topic is closed to new replies.

Advertisement