XNA 4.0 Light Pre-Pass: shedding the light

After my last post, I decided to continue with the z-reconstruct approach and to use light-meshes where possible. I’ve implemented two more light types: directional and spot. You can get the source code here.

Here is a screenshot of the lights in action, in the game editor I’m working on:

Some models are from Crytek Atrium Sponza Palace, and others from the XNA samples.

Directional Lights

The directional light is the easiest one: just render a full-screen quad and do the math. We don’t need to compute attenuation or light to pixel vectors (assuming our directional light only has parallel rays), so the shader is very simple. The only problem is the fill-rate: as directional lights usually don’t have attenuation, we always draw a full-screen quad for each directional light. To make it less expensive, I’m using depth test to reject fragments that only contains background values and thus don’t need to be lit. My fullscreen quad outputs z = 1, the farthest distance possible, and I set the depth test to Greater.

Here is a screenshot with a single directional light:


Spotlights are basically lights with a cone-shaped attenuation, like a desk lamp. In my code, I assume it behaves like a point light (has a world position) and also a direction. I don’t use the correct formulas to compute cone attenuation, falloff etc, like described here. Instead, I’ve developed my own (crazy) formula that works fine and doesn’t need pow or div and still gives a customizable falloff on cone’s border.

To render the spotlights I’ve created a cone mesh, with length = 1 and radius ~= 1. It is very coarse, about 30 triangles. I had to expand the radius to more than 1 unit, because the tessellation makes the distance between the edges and the center smaller than 1. With this mesh in hands, I could scale the length by light radius and the cone radius by light radius * tan(spot angle). All the math is in the source code, both the mesh scaling and the shading formula.

Here is a sequence of optimizations to reduce pixel processing:

From left to right, top to bottom:

  • Final image, single spot light;
  • Using a screen-aligned quad;
  • Using a sphere mesh;
  • Using a cone mesh (good);
  • Using z-test (better!);
  • Using clip() after attenuation: it saves the specular computing (two normalizes).

As you can see its a HUGE win to use the cone mesh, we save one order of magnitude of pixels in that case. We could even use a frustum-cone intersection to skip the light in the culling stage, or even a frustum-frustum (built-in on XNA) instead of the frustum-bounding sphere that I’m doing in the code.

Here are some screenshots of the sample I’m releasing:

What’s next?

I’m slowly importing my engine code into this project, so probably the next topic will be about skinned meshes and alpha masked objects, and then shadows or SSAO. Comments and replies are welcome.

Thanks to Crytek for making the Atrium Sponza Palace mesh and textures available to the public, and to the guys at Gamedev.net and App Hub forums.

See ya!



About jcoluna

Game developer and musician
This entry was posted in XNA and tagged , , , , , , . Bookmark the permalink.

11 Responses to XNA 4.0 Light Pre-Pass: shedding the light

  1. Evan says:

    Have you given any more thought to a 360 version? I’m in the middle converting our project to light pre-pass, and one one problem I’ve run into on the 360 is what to use for the light accumulation buffer. HdrBlendable on the 360 is a 1010102 format so there’s not really any room in the alpha channel to accumulating the specular lighting. It’s looking like MRT might be the only option.

  2. jcoluna says:

    I think you can go with Rgba64: it’s not a floating point format, it supports blending (http://forums.create.msdn.com/forums/p/5005/26302.aspx) and you have lots of precision, even in the alpha channel. I don’t know how it would behave on the 360, though.

  3. Shaitan says:

    Nice work man!
    It would be nice to see an example of this technique rendering transparent/translucent surfaces….

    Keep on!!

  4. Pingback: Windows Client Developer Roundup 059 for 2/14/2011 · All About Computer

  5. Steve says:

    i agree with shaitan, but i am more interested in seeing this with shadows. would be good to compare the performance with shadowing to the deferred rendering engine i implemented.

    look forward to the next post

  6. Kris says:

    I’m more curious about shadows than SSAO, if that makes any difference to you 🙂

  7. Amer says:

    Do you plan to do shadows implementation?
    Are you still working on this?


    • jcoluna says:

      Hi there
      I’m still working on this, I will put the spotlight + cascade shadows next week. Thanks for visiting!

      • Steve says:

        That would be great to see. would make it one of the most complete rendering demos built with XNA that i have seen on the web. can’t wait to see the result

  8. pratama bayu says:

    nice work man 🙂

  9. Pingback: Dozens of point lights with forward rendering. | Olhovsky

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s