Tuesday 4 March 2014

MatCap Materials, and Smooth Soft Shadows for Away3D


Today I'm going to introduce a couple of techniques for improving realism, while reducing the load in real-time 3D scenes using Away3D 4.0.

You might be surprised to learn there are no lights in this scene whatsoever. Neither are the materials "baked" in any way. In fact this nice shiny plastic material can be applied to any object with mapping coordinates, though curvy, organic shapes work best.

It is known as a "MatCap" material, and was developed for Away3D by Przemek. (props!)
http://away3d.com/forum/viewthread/5255/

This type of material has long been available in Z-brush, among other packages.
The material consists of a single bitmap of a sphere and a shader that reads values from the bitmap and apply them to the object dependent on a faces angle to the view.

Here's the map used, plus a couple more examples.


You'll find more on MatCap, or Material Capture shaders all over the web. Here's a nice intro vid.

Here's the source, including the version of MatCapMaterial available at time of posting.

Apart from the actual material, take a look at the soft subtle shadow under the teapot. To get such a soft shadow I would normally render the scene using a raytracing renderer such as Mental Ray and attach it to a plane below the object, as it's just about impossible, and extremely processor intensive to do in real-time.

Currently I'm working with objects that are created in real-time, so rendering the shadow in MAX is simply not an option. To get around this I made a class called SuperSoftShadow (also provided in the source download, together with a FlashDevelop project file)



In the examples above and below the shadow is drawn dynamically when the scene initializes, and from then on uses no processor at all, it is a simple plane with the shadow TextureMaterial attached, and a BlendMode.MULTIPLY to blend it in with the background.

A couple of Gotchas there. The background here is an actual plane in the scene. If you try to use BlendMode.MULTIPLY on a background using the view3D.background, the whole screen turns black(!). Another thing I've discovered is the alpha value appears to be ignored when using blend modes.

What the SuperSoftShadow class does, is given an ObjectContainer3D such as a Loader3D, takes a snapshot using an Ortographic camera placed above, and then uses AS3's built in BlurFilter to soften it as much as you like. The resulting bitmapData is then applied to a texture on a plane, also created dynamically to match the size of the container.

Here's how to use it:

shadow = new SuperSoftShadow(container, this.stage, blur, size, yoffset, shadowColor, distance);

A look at the constructor describes the parameters.

container - The container to apply the dropshadow to. This can be a loader3D.

stage - Reference to stage required for creating stage3D instance.

blur - The blur amount for the shadow. Note that using larger bitmap sizes requires using large blur values.

size - The size of the bitmap to use. This can be any power of 2 dimension (512 x 512, 1024 x 1024, 2048 x 2048...etc.) The bigger the bitmap the better the quality.

yoffset - This is the y position within the container, which the shadow will be attached to. The class attempts to place the shadow directly underneath the container (minY) though this may not be the desired position.

shadowColor - A hexadecimal code for the colour of the shadow. This can be useful for radiosity effects for glowing objects, glass objects, etc.

distance - An optional value to control the cross-section of the object container to use. This controls the near plane of the camera that takes the snapshot. 

Another example using dynamic text...


(if you don't have the patience to watch it turn slowly, try the arrow keys :)
You can enter your own text to see the dynamic shadow in action. You can also adjust the extrusion depth of the text with up and down arrows, but you need to press ENTER to update the shadow, or the text.

The material for the text uses yet another technique, image based lighting, a bit more tricky, but worth the effort :)

Enjoy!