In|Framez® Papers

Shadow Mac!

By Homam Bahnassi


This tutorial is divided into the following sections:


Skill Requirements

Pretty much nothing! You just need to know how to get a sphere, and attach some shaders in the render tree.



Introduction

OGLShadowMap is another mysterious real-time shader that's really great and helpful; only if you know how it can be used! So here comes this hacky tutorial that shows you how to use this important shader in your daily work.
The OGLShadowMap covers a very common case of shadows rendering, which is useful for everyday use. Unfortunately, for more advanced cases you'll need to use more advanced shader systems or write your own shadow map shader (to learn how you can use and write custom real-time shaders for advanced shader systems take a look at the X-tasy (ecstasy) with Real-Time Shaders tutorial).
Anyways, even if this shader is not that flexible for true real-time work, it is still useful for fast pre-viewing and pre-visualizing. And here we go…


Shadows play an important role in eerie scenes


Explaining the shader’s concept

As the name of this shader implies “Shadow Map”, this shader uses intermediate 2D generated maps to render shadows, which is a well-known technique (especially for those who are involved in the game industry) to compute shadows in 3D.
In short, what the shader does is generate a 2D image that contains per-pixel depth information about the scene you're rendering with regard to the light’s point of view, and stores it in a custom buffer (P-Buffer). Then, it projects this image back to the scene. Something like what mentalRay does when rendering shadow maps.
Because of this technique, we’ll find a bunch of parameters in the shader’s PPG that control the 2D map generation and projection properties. We’ll discuss these more in the following sections.


Preparing the scene

Before we deal with this shader, we need to prepare a couple of things in the scene, so we get the results we expect.
First of all, you should have 3D geometry in your scene that will cast shadows on each other (very intuitive, huh?). Get a small sphere and a grid for example (or any objects that you find interesting) and position them so the sphere lies over the grid.
Put all of your 3D geometry in a group, and assign a new material to this group. This will override all objects’ materials, which is required for controlling the OGLShadowMap shader. The group contains both transmitter and receiver objects simultaneously.

Ok, now you need to add a light source that will cast the shadows in your scene. Grab a spot light and position it so it is focused on your main objects.
It's preferable also to delete the default scene light to make sure that you will not use it accidentally as a shadow caster instead of your new light.

That’s it! all what is left now is to add the shadow shader.

Group all your shadow-related objects under one material




Adding the shader and explaining its properties

Open the render tree for the group material and get a shadow map shader from the ‘RealTime > More…’ menu.
Plug the node into the ‘Realtime’ input port in the material's node, and switch your camera shading to ‘Realtime Shaders’.
You’ll see a constant white surface, with a black shadow area. Orbit your camera and reposition your light until the black shadow area is viewed clearly.

First look, black or white

Now let's open the shader’s PPG and see what’s there for us to play with: The rest of the properties are for controlling and outputting the map used to render the shadows. We’ll leave these to their defaults now.

ShadowMap PPG, along with some spelling errors!




Extending the shader tree with shading and texturing nodes

Clearly, the result we've achieved until now is useless, since there’s no shading and texturing on the objects! We gotta fix this...
So back in the render tree, grab the following nodes OGLDraw, OGLShade and OGLTexture. Connect them in the same order they're listed here, then reconnect the OGLShadowmap after your last node (i.e. OGLTexture).
As you connect the OGLDraw node, you'll lose the rendered shadows. Don't worry though, we'll manage this after a while. Now set the surface and texture properties from the OGLShade and OGLTexture nodes.
Finally, to retrieve back our shadows, we need to activate alpha blending in the OGLDraw shader. In its PPG, just check Enable Blending and choose ONE from the Source list, and SRC_COLOR from Destination list. This will take the rendered shadow color information and multiply it with the surface’s color.
The final effect will be a nicely blended shadow. Give yourself time to mess with the blending modes to see how different combinations affect the result.

Knock on the wood... Nice real-time shadows!

Sample Scene and good bye

Here’s my sample scene that I tested shadow maps with. Notice how the shader improves feeling of the scene mood, and as usual, in real-time!

Enjoy.