2007-11-05

More Hidden Gems: mia_envblur - glossy reflections of Environments

I thought initially I would title this post "Happiness is a Warm Gun", since it could have just as well have been the "black gun metal" tip, but I felt a more "searchable" name would be more useful...



Formulating The Problem



Glossy Reflections in computer graphics is always a headache, since it invariable involves multiple samples, which invariably involves grain. Interpolation helps, but interpolation isn't really working well for complex geometries, and can be "detectable" in animations (i.e. you can often "see" that something fishy is going on w. reflections, so I advice against using interpolated reflections in animations).

But, you say, I need to have my semi-glossy space robot/gunship/whatever and I need to animate it, and I have this really contrasty HDR environment it must reflect... I would need to turn up samples to crazy levels... the animation would never be finished! What can I do!?

The solution: mia_envblur



This shader is another "sort of hidden" (depending on which application you are running, it's hidden away in 3ds Max but not in Maya, and it's existence isn't really marketed heavily... ;) )

What does it do?



Well, the documentation explains this fairly clearly, but in short:

If you have some objects in a scene which largely reflects an environment map (this bit is important; mia_envblur really dosn't do anything useful for, say, an architectural interior where objects reflect other objects, it only does it's job for environment reflections) and your environment is high-contrast, you tend to get grain as a result. Witness here some spheres n' stuff reflecting the good old "Galileo's Tomb" probe from Paul Debevec:



Grusomely Grainy


This is clearly not satisfactory, the grain is very heavy, causing slow renders due to a lot of oversampling happening. We can turn up the sampling in the shaders and get something like this:



Borderline Better


This looks nicer indeed, but the render time was nearly ten times of the above! Not something you'd want to do for an extended animation. And it would still glitter and creep around. Not good.

So... enter mia_envblur. The shader is used to "wrap around" some existing environment shader, i.e. it takes some other environment shader, rasterizes it into an internal mipmap, and can perform intelligent filtered lookups in a special coordinate space which behaves very close to doing actual glossy lookups to that environment with a near-infinte amount of rays!



Soothingly Smooth!

This is much nicer looking, and the environment reflections are smooth (but object-to-object reflections still involve multi-sampling and can have some grain. A trick around that is to limit the reflection distance as mentioned in the manual).

To use mia_envblur, you must follow these steps:

  • Where your existing environment shader is connected, instead connect mia_envblur, and connect your original environment into it's environment input.
  • In your mia_material, turn on it's "single_env_sample" parameter. This is very important or you will gain neither speed nor quality (although you will get a little bit of smoothing, but not supersmoothing of the reflections)
  • Set the "resolution" high enough to resolve the details of your original environment.

As for the actual blur amount, you have two choices; Either you set a fixed amount of blur with the mia_envblur parameter Blur. But that is a bit boring... if you have different materials of different glossiness, you would need separate copies with different blur ammounts applies as environment maps to each materials... very tedious...!

Much better is to turn on the mia_material_blur parameter on!

This will drive the amount of blur from the glossiness setting of the mia_material. This works such, that mia_material "informs" the environment shader which glossiness is used for a certain environment lookup, and hence allows a single global copy of mia_envblur (applied in the global (camera) Environment slot) to follow the glossiness of multiple mia_materials, or even map-driven glossiness on a single material:



Very Visible Variable Varnishness


I can't stress enough how varying the glossiness with a map gives a nice feel of wear, tear and "fingerprintiness" of an object. And with mia_envblur you can do this without being ashamed and fear horrid render times.

Production Shaders?



Yes, mia_envblur works great together with the production shaders. Just "wrap" it around your mip_mirrorball shader, to do glossy lookups into it.



Perfect Production Partner


This spaceship (from TurboSquid) is mapped with a glossy reflection that is heavily varied (A whole "make a spaceship in the backyard" tutorial will probably appear later, if I find time).


Does it move?



Yes it does. Just a word of warning: be certain that the resolution parameter is set high enough to resolve all details in the environment you use. The "Gallileo" probe I use here has too many small lights in it for the default of "200" to be enough (this means the map is rasterized into a 200x200 pixel mipmap). But at 600 it works great. Also note that any non-glossy lookups into the environment map actually bypasses mia_envblur automatically, so these are looked up in the full resolution map!

See for yourself in this DivX test animation, which includes above spaceship hovering over my backyard, the above gun-metal-black battle robot (also from from TurboSquid) and some spheres, including my attempt to do a "gnarly cannon ball".

For the record, these renders also uses the photographic exposure and Lume "Glare" shader. The animations rendered at about 1 minute per frame (on a HP x6400 Quad Core)

Hope this helps your glossy-thing-renders!

/Z