2008-11-05

The Joy of a little "Ambience"...

As usual, when the same question pops up in multiple places, I tend to turn this into a blog post. The question I was asked recently was how to use ambient light in mental ray (specifically, in mental ray in 3ds Max), because people were confused about the lack of an "ambient" slot in, say, the mia_material (Arch & Design) shader.

I will try to explain this here.

THEORY: "Ambient Light" and "Occlusion" - a primer



Back in the day...



Traditional computer graphics, with no indirect lighting of any kind, would by default look like this; here's a scene lit with a single shadow-casting directional light:



I.e. shadows are pitch-black, with no realism whatsoever. You can't even tell that the yellowish rectangular thing at the bottom is a table that has legs!

So a couple of tricks were introduced. One ugly, unrealistic hack was "shadow density", i.e. the ability to say "when light from this light is in shadow, only x% of it actually disappear". So you could set things like "Shadow Color" and "Shadow Density", which you all understand is completely absurd and totally contrary to any form of sanity and logic.

An opaque object either blocks light, or it doesn't - it doesn't just randomly go "Oh I block 47% of the light". That can't happen (outside of actually transparent objects).

RULE#1: Never, ever, no matter how "old-school" your rendering techniques are, use "shadow color" or "shadow density" settings. Ever. Trust me on this.

Enter "Ambient" light



"But", these early CG people said, "outdoors shadows from the sun is slighlty blue, shouldn't I set a shadow density and color to get my blue shadows"?

NO!!

The reason "shadows are blue" is because they are filled in by blue light from the sky.

Now, our early CG pioneers understood this, of course, so rather than the horrendeos hack of "shadow color", they introduced a nearly-as-horrendous hack: Ambient Light.

But the problem was, this "Ambient Light" was ever-present and uniform, and yielded a totally unrealistic and unsatisfactory result when used on it's own, something like this:



That looks about as horrible as the original: Sure, you can see something in the shadows - but it's all totally uniformly lit. The "legs" of our table can now be seen... but as totally uniformly colored blobs, with nothing to reveal their shape.

Are these round legs, or are they flat oval things, or what are those? Does the legs touch the floor, or are they hovering above it? The purple teapot looks almost flying, because the shadow behind the green teapot is just a flat color.

The problem here is that light is hitting every point uniformly, with no regard to the position or angle of the surfaces. But if we are trying so simulate "blueish light from the sky", then a point that is exposed to a lot of the sky will receive more light, than a point that is beind a bunch of other objects that are blocking (i.e. "occluding") the skylight.

Enter "Occlusion"



Luckily, some bright people at ILM back in 2002 when they were working on "Pearl Harbor" invented (using mental ray, I should add) something called "Ambient Occlusion". Basically, they wrote a shader that figure out how "occluded" a certain point was, i.e. how much stuff was "blocking light from arriving" at that point. This "Occlusion" on it's own looks like this:



Combining "Ambient" and "Occusion"



Now, if you apply this to the Ambient term, you get this very much nicer image:



See how beautifully the details resolve; the legs of the table now correclty reads as "contacting" the floor; the shape of the legs can be perceived. The area between the teapots is properly darkened, and the teapots have nice contact shadows.

The above is how it should be done!

Doing it the WRONG way



However, unfortunatly, many people have read and misunderstood the original ILM documents on Ambient Occlusion, and apply the Occlusion pass across the entire rendering. This is W R O N G!!

I.e. people make "plain" render (including ambient light and everything), make an occlusion pass, and just multiply the two in post!

The result is that you get a deceptively-sort-of-okay-but-somwhat-wrong looking result like this:



Notice how this has a "dirty" feel. This is because the occlusion pass (pictured above) was applied on top of the entire image, affecing the "ambient" light as well as the directional light.

But this makes no sense; the "occlusion" of the directional light is already taken into account - that's what the shadow of the light is. Ambient occlusion isn't called "ambient occlusion" for no reason; it's supposed to be applied to the "ambient" term, i.e. the "omnidirectional surrounding light", not to any direct lights.

But in the above image you will see darkening on floor in front of the objects, making it appear "dirty". Similarly, there is a bad looking "dirt-shadow" of the teapots spout on the front of the teapots. And so on.

SO: Globally multiplying occlusion on top of the beauty pass (including reflections, direct light, etc) is WRONG. Don't do it.

But isn't this all fake? Why are we doing it?



Now... all we are doing with our "ambient" light and the "occlusion" is simulating "omnipresent light" (i.e. light from the environment) as well as "bounce light" (from other objects). Lets compare the result with actually calculating omnipresent light and bounce light; i.e. use Final Gathering and calculate it FOR REAL:



The above image uses FG and a 3ds Max "Skylight" (i.e. light from the environment in XSI or Maya) to introduce the same kind of light we tried to "fake" with the "ambient" light - but correctly. And with true indirect bounces!

So this results begs the question; when we so easily can get the correct result, why would we still want to go the "fake" route?

There are a couple of answers:


  • FG is an interpolated technique. This means that the indirect lighting is sub-sampled (calculated less than for every pixel) and the values between those are interpolated. However, if you are doing an animation, and the result between two frames are slightly different (for whatever reason), this may - hypothetically - cause not one pixel to change, but a large area of pixels to change (i.e. all pixels influenced by the interpolation of that FG point).

    The result, in a final animation, will be visible flicker. Visible, because it is "macroscopic", i.e. larger than a pixel, and perceived as "scintillation" or "flicker", which is visually unappealing.

    Contrast this with using the occlusion technique: It is calculated for every pixel (every sample, even), and hence, any noise in this calculation is of sub-pixel size. I.e. a difference from one frame or another will only affect at most one pixel, and mostly just a fragment of a pixel.

    The result is that this perceived more as "film grain", and is much less visually objectionable.



  • We may actually want to combine both "real" and "fake"; this is a method I often advocate.

    You use FG at a low density and with high interpolation, and you apply your occlusion on top of this indirect light, rather than some homemade, arbitrarily invented "ambient" light. This relieves you of the responsibility of having to figure out the proper intensity and color of this mythical "ambient light" - it is calculated for you.

    And of course, this combo method is a built in as a feature in Arch&Design/mia_material...


PRACTICE: How do we actually do this?



Since the original questions was in a 3ds Max context, I will answer (for now) in a 3ds Max context, but also mention the methods for XSI and Maya in the text.

There are three basic methods to apply ambient light:

  1. Use the built in AO of Arch&Design/mia_material and utilize it's "Ambient" parameter
  2. Use a light set to "Ambient Only"
  3. Use a light with the Ambient/Reflective Occlusion shader as light shader.


Method #1: Arch&Design (mia_material) ambience



This method allows you either per-material or global ambient light levels, and you can easily modify the ambient occlusion radius from the rollout:


  • Open the material in the material editor
  • Go to the "Special Effects" rollout.
  • Turn on the "Ambient Occlusion" and...

    • ...EITHER put in a given ambient light color in the material...
    • ...OR: switch to the "global" mode, which will use the "ambient" color and intensity from the Environment dialog box:




In XSI and Maya this means enabling the built in AO of mia_material, and setting the "ao_ambient" parameter to the color of your desired ambient light.

Method #2: "Ambient Only" light



(AFAIK, this specific method only works in 3ds Max. Correct me if I am wrong.)


  • Create an Omni
  • In it's Advanced rollout, set the light to "Ambient Only"



This gives you plain (flat) ambient light with no occlusion.

To get the occlusion effect by adding the Ambient/Reflective Occlusion shader as the "Projector Map" of the light.

BUT - There is a big BUT - For this to work, you MUST have the light with it's transformation reset, i.e. it must be placed at 0,0,0 in the top viewport, or the ambient occlusion shader will be confused.

Doing this manually is tricky; so it can be done much easier with a script:


myLight = Omnilight()
myLight.AmbientOnly = true
myLight.projectorMap = Ambient_Reflective_Occlusion__3dsmax()


To run this script:


  • Go to MaxScript menu
  • choose "New Script"
  • paste the above snippet in
  • hit CTRL-E


You will now have a set up light, where you can modify it's intensity and color etc. w. the normal 3ds max light features. The only thing you need to look out for is if you wan to set the distance for the ambient occlusion rays, you must


  • take the Ambient/Reflective Occlusion shader that is in the projector map
  • drag-and-drop it into the material editor
  • choose "Instance"
  • ...and modify the settings from the material editor


Method #3: "Ambient Only" light w. occlusion shader as light shader



There is actually a Method#3 which is similar to Method #2, except rather than placing the Ambient/Reflective Occlusion shader in the "Projection Map" slot, you use that shader as the light shader of the light itself.

A quirk of this methods is that now the shader completely replaces all the settings of the light; all controls for color, intensity, etc. stop working, and you need to do all changes to the light intensity and color by modifying the color of the "bright" slot of the occlusion shader itself (by putting it in material editor, as above).

This method has the benefit of not requiring the strange "light has to be in 0,0,0" requirement, plus that it is a method that works as well in Maya and XSI. To do this in XSI or Maya:


  • Create an area light
  • Set it's area light type to "User" and 1 sample
  • Use the mib_amb_occlusion shader as the light shader of the light


Similar to 3ds Max, changes to the "ambient light level" will now have to be done entirely from inside the occlusion shader.

Hope this helps.

Mo' later.

/Z

41 comments:

Jordi Bares said...

Thanks Zap for your explanation, I have a few little questions related to the subject;

1) Isn't having a ambient_color per material a way to promoting the wrong approach that every material is not balanced against the others? I would obviously choose by default global but happens that the XSI implementation does not have it in the material

2) Also, embedding the ambient occlusion seems very sensible approach but let's say you define a library of materials all nicely setup with AO and then you want to use that material on a spacecraft where there is no ambient. What would be your take, would you define all the materials with ambient occlusion or without?

3) Also, could you develop further on the "Detail enhancement" in the AO tab in XSI? the manual says it is for short distance AO and multiplying by the indirect illumination. Isn't this going to bring a double AO effect?

Thanks and kudos for the blog, you have all the beer you can drink in London.

Master Zap said...

1) Agree, but the "global" thing is purely an UI trick in max. The underlying shader (on the mental ray level) has one ambient setting per material, only when you set it to "global", max simply under-the-hood copies the global one there. So there is nothing really stopping XSI people from doing the same - in theory.

2) As luck would have it, the AO feature is smart enough such that if the AO receives black as it's light color, it will do nothing.

Besides, everyone knows there is ambient light in space, didn't you see Star Wars? ;)

3) It will be "double AO" if your FG is set to such a high detail that it, by itself, will resolve every nook and cranny. But if you instead set a relatively low FG density, with a high number of points for interpolation, it will "smear out" the FG contribution, with no details. The AO on top of this regains the details.

Jordi Bares said...

Thanks Zap, very useful help.

Glacierise (a.k.a. Hristo Velev) said...

MasterZ that's a totally awesome post how could I have missed that workflow! Thanks a lot!

Ino said...

Glad to see you're back on this blog.
Keep it up!

furbit said...

I was wondering how you got the AO to affect the image only in the shadowed areas.

Did you do this in post?
Or per one of your techniques 'in the render'.

Thanks

Wilbert van den Broek said...

Thanks zap for yet another kick ass post. Very helpful.

Kslay said...

"I was wondering how you got the AO to affect the image only in the shadowed areas."

Same question here Zap.
How do you implement this?

Also when using an arealight with 1 samples and an occ shader as a light shader the result looks totally different than a "normal" occ pass
like when creating it with the layer preset in Maya.
Which will automatically create a surface shader and put the mib_amb_occ into the outColor slot.

Can you give us some hints?

best regards

Master Zap said...

I was wondering how you got the AO to affect the image only in the shadowed areas.

Did you do this in post?


Only the "wrong" image was done in post.

The thing is, there IS occlusion both in the lit and shadowed area, but only for the ambient term. In the lit area, the directional light is so much stronger that it overpowers this slight darkening - you don't see it.

(The fact that I am rendering with a proper gamma correction, so light "adds up" correctly makes this even more evident).

Also when using an arealight with 1 samples and an occ shader as a light shader the result looks totally different than a "normal" occ pass

If you have no other lights, and a white lambertian materials, it should actually look pretty much the same.

/Z

James Barnette said...

confused can some one correct the XSI workflow being listed here I know you can make any light an area light or use the light box but I don't see "user" under light type

James Barnette said...

Actually both the Maya and XSI workflows do not seem to work. Prolly just as you are used to MAX. There seem to be many missing steps. perhaps someone could post some example scene files.

joshpurple said...

Thank You Zap!

Jason Huang said...

Thank you, Zap. You made me read the ILM paper the third time. :)
I am a bit confused on 3 different approaches with your “advocate” way.
So, when having blurred HDRI as light source in the scene, should we just use your “advocate” way (low-density, high-interpolation FG, then multiply AO on top) or resort to the method 3 (as Maya or XSI user) using AO shader as the area light’s shader?
In my POV, the “low-density FG multiplied by AO” is like a “do-it-in-post” way and the 3 methods are like “no-post” way to see the result in application’s render view, am I getting it right?

In terms of ILM’s Production-Ready GI paper, if I get it right, their formula is somewhat like:
Final image = Key light pass + (ref. pass * ref. occlusion) + (ambient env. light pass * AO) (correct me if I get it wrong)
1. the paper mention achieving blurry reflection occlusion (per material base) by jittering secondary rays around the main reflection vector, as well as integrate “bent normal” into occluded ambient environment light pass to have accurate lookup into the Ambient Environment map. How we actually do this two things in mental ray?
2. Is this paper’s approach still used nowadays in effects movie production or it is now just an approach for 2002’s renderfarm specification? If scene-complexity and render time are both OK, should we just go with true raytraced IBL for better result?

Casey James Basichis said...
This comment has been removed by the author.
Harry Bardak said...

For AO and bent normals with Mr you can have a look to this page.

http://www.harrybardak.co.uk/TDlove2006.htm

It's a bit old still there :)

David said...

Thanks a lot for the post. I just have one question.. If using method 2 with the mr sun/sky should you disable the skylight? Otherwise it would seem to give double ambient light.

-fc

Jignesh said...

Great post Mr.Zap! Also I found and read ILM papers about production ready GI workflow... I understand now how to use ambient lighting in with ambient occlusion and also image based lighting is possible there... cool stuff! Thanks!

Torbjörn said...

Hi!
Thank you for your enlightening blog and for the information about gamma in MR that you've shared on CG society.

A curious question - in maya 2009, with the new MR renderpasses, is it possible to set the other AO settings in the mib_amb_occlusion settings somehow (most importantly the max distance setting)?

Best wishes!

athos said...

Thank you for these great posts.
There´s an old one explaining the SSS fast skin shader that is great also.

Best regards.

dev said...

Thank you very much for this nice article, I have few queries regarding AO:
Is it possible to reder AO with diffuse texture so that we could fake gi.I mean i m getting nice result with AO and i want to render them as it is within 3dsmax but with textures on.Also, if thats possible how can i add light(only for highlights and a bit shadow rather than usually completely black shadow) into them so that it would create a fake gi where all the indirect light +soft diffuse shadows are taken care by AO and highlighting and a bit shadowing can be done by lights .
Thus, without using any gi solution we can clay look.

Hannes Drossel said...

Hi Zap!

Thanks for this wonderful explanation.

I have a problem however with the Method #3. I set it up and it works as expected, but im getting specular highlights from the area light. Is there any way to turn this off in Maya?

Manish Kashyap said...

Hi Mr. Zap

ur information about mental ray has alwas been useful to me. I have some query regarding reflecton raytracing

since i have never worked with dgs shader because arch shaders has always been more handy with me for any kind of finish i want to achieve but my renderings takes time. can u just tell me that if dgs can make my renderings work more faster in a scene which is quite geometry intensive because of trees and landscaping in it.

Thanks and regards
Manish

furbit said...

Thanks Zap,

I guess that image at the bottom of the post didn't apear when i first viewed the article.

Thanks for the quick reply, your explantion helped a lot.

Jude said...

Thank you very much Master Zap!!!

I have been rendering those passes for years (Occlusion, Ambient and Key light)... and nobody ever explained me the right way to comp them.
I use the physical sky and sun. To do the ambient pass, I unchek the physical sun and to do the ambient I unchek the physical sun, but I keep the FG in both pass. Then I do an occlusion pass separatly.
That way even in the shadow, my occlusion is "colored" by the FG from the screened key pass.
The end result is absolutly stunning!

I work for an architectural visualisation compagnie and Mental Ray is prety much my bread and butter. (www.alpha-vision.com)

Again, thanks a lot for that occlusion 101 course.

(ps: sorry for my poor english... we speak french here in quebec!)

James said...

"To do the ambient pass, I unchek the physical sun and to do the ambient I unchek the physical sun, but I keep the FG in both pass. Then I do an occlusion pass separatly.
That way even in the shadow, my occlusion is "colored" by the FG from the screened key pass.
"

That is an interesting approach.

Jude said...

KEY pass = uncheck Physical Sky
Ambient pass = uncheck Physical Sun

miroslav disanski said...

wooooooooww :)
you guys have no idea how long i have been trying to do this. Thank you so much. and i also searched everywhere. thanks again

mixakey said...
This comment has been removed by the author.
mixakey said...

David said
---"Thanks a lot for the post. I just have one question.. If using method 2 with the mr sun/sky should you disable the skylight? Otherwise it would seem to give double ambient light."---

I try to do the trick by lower the color value of Dark slot in mib_occ node to negative value and set the bright color to black,End with a wired result.Want to know solution too.

eran said...

Hi Zap,

Cool post.

Are there any tips for FAST AO pass?
We all know it's cool, but how can I get it down to a managable render time ?

Thanks
Eran

Sean Christian Bellinger said...

First thank you for the EXCELLENT explanation on ambient light and ambient occlusion. I've learn a lot about why AND how to use them.
Unfortunately, I'm having real trouble trying to implement it in 3ds Max. Specifically, your 3rd method. I REALLY need a step by step on how to re-create this method. In my renders, the ambient occlusion is applied to the entire image, instead of being restricted to just the shadows. This, as you already know, is resulting very dirty shadows. I'm not geting the good directional shadows that you have in your renders. Please break it down for me....how do I do this?

Thank you again.

yi said...

Hello, everybody. I am a new hand to be here. So nice to meet you all. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

John said...

I would like to appreciate the great work done by You

fantutu said...

I think its a pretty good idea not that there aren't other sites out there that already do something similar but I think it might catch on here pretty well. chanel chain bags great mall
chanel charm bag
chanel charm bag 2.55

Marcio Nisenbaum said...

hey there, I guess I am having the same trouble as some guys reported. Using the first method seems to be the one that works better.
However, using the omni method, in an interior scene, the fg is adding more fill light on top of the ambient light generated by the omni, so the image gets too much bright..i tried to tweak the interpolation and density but apparently they dont help much!also changing the intensity of the omni can make the scene darker but then i lose the occlusion effect!
Anyone could solve this??
Thanks!

S said...

Hey, Grand Master Z!

Thanks so much for this awesome blog and all the ueful tips and tricks!

Now.. as you can probably guess, i have a question, and here it is:

I was playing around with Mental Ray´s ambient Occlusion node in Maya, and i wanted to try baking out the normals of an object (say, a car) out to texture. Similar to what this guy here has going: http://www.harrybardak.co.uk/TDlove2006.htm

Now, being that i use Maya, i didnt quite know, what mode to set the occlusion-node to, to get my Normals in ObjectSpace. So i googled a little, and in some PDF Paper, i found, that it should be set to mode 4 to achieve this.

Thing being, in Maya (2011) i cannot set it to that... The node only lets me set mode 0 through 3... At first i thought, it was just that "0", of course, counts as a valid mode, too, and thereby "mode 3" would be what i need. But this is not the case, as in said paper, it goes from mode0 through mode4 as well, and setting the node to mode3 will return CameraSpace Normals...

So long story short:

How can i use the ambientOcclusion node in Maya 2011 to bake out the normals of a given object in OBJECT-SPACE...?

Also, just as an idea, you could maybe post a tutorial or a Tip on reflectiveOcclusion... i think, that would be really interesting.

Thanks for reading and keep going =)

Jono said...
This comment has been removed by the author.
Antoine said...

Thanks for the Tut !

However I'm stuck in post.
It may be a silly a question but how you do the addition part. I tried to do it in photoshop but I found no way to make it right. There is indeed no addition mode between layers.

Mick said...

Great article, Zap...thanks for putting this together. I like the ambient/onmni light technique best, since the idea of handling ambient light as a light makes a lot more sense to me than applying it to a material. But in the tests I did, the material-based method (I used #2) allowed me to override the light on a given material if I needed to, so it's also good to know.

Wolfgang Haak said...

In Max 2013, method #2 doesn't seem to work. As in method #3, the shader need to to be in the light's MR Shader Slot, not the Projector Map.

Greeting,
Wolfgang

Johnson Karen said...

Every week-end I used to pay a fast visit this site, because I’d like enjoyment, because this web site conations certainly fussy material.Outdoors