Keith Newton

Hello, I am currently working on my deferred shading engine and have run into an interesting problem concerning the usage of normal maps. At the moment I am storing the normal for each pixel in world space during the geometry pass. All of my lighting calculations are also being done in world space. The problem I am having is it seems more people seem to do normal mapping in tangent space. In fact I've only ever read 1 article on doing it in anything other than tangent space. To address this problem I was thinking I'll just store all of my normals in tangent space instead of world space when I do the geometry pass. This seemed like an even better idea once I realized I would need the normals in tangent space for parallax occlusion mapping anyway. The problem is when I render my lights as a post process I have to convert them into tangent space as well. Since the tangent space matrix is per-vertex I saw no way of doing this without storing the binormal and tangent for each pixel as well (ack!). My second thought was to simply continue storing normals in world space by multiplying the normal map normals by the inverse of the tangent space matrix. Unfortunately this would be an extremely expensive operation as I would have to calculate the inverse in the pixel shader (unless I am missing something). I am wondering does anyone have any recommendations on this problem or should I start encouraging my art team to produce all of our normal maps in world space

P.S. It's the 11th now w00t *dances a little jig*. Can't wait to start running this stuff on the 360 =D

Re: XNA Framework Question on deferred shading with normal mapping

Michael Hansen

sorry for my typos bu i am word blind

it a bit triggy

but lets say you render your mesh to a floting point buffer (surface.single or vector4) you have all  the height values of the deffuce texture map (no nead for normal map-tanget-binormal) you just mul the ypos wdth a height factor let say 4.0 max

then you take the final result of the height values and postprocess ( blend ) with the raw deffuce map(the same texture just before it was render into the depth buffer) then you have the the same effect.

and apply this texture to the mesh

just doing realtime fake normal mapping. ( looks mucth better )

remember light shall be render to all the vertex and pixels in the scene.


Re: XNA Framework Question on deferred shading with normal mapping


If I remember Shawn Hargreaves's had the thesis at GDC2004.

Re: XNA Framework Question on deferred shading with normal mapping

Michael Hansen

yes you are right

take a look at my other post PostID=1003759&SiteID=1

look at the pdf from crytek

you can allso see a video of my engine

gameshot video the stones is doing the above thing

best regards


Re: XNA Framework Question on deferred shading with normal mapping

Shawn Hargreaves - MSFT

Do you mean your actual normalmap textures store normals in worldspace, or just that your deferred shading output buffers do this

For a general purpose engine it is important that the actual texture data hold normals in tangent space. Otherwise it becomes impossible to reuse a texture on surfaces with different orientations, for instance there would be no way to reuse a single brick normalmap across a whole level.

When it comes to the actual lighting, it doesn't really matter whether you do this in world space or tangent space. One way you have to transform your lights, the other way you have to transform your normal the other way, and it's really up to you which way you want to go.

On early (shader 1.1) hardware you pretty much had to do it in tangent space, and these days that might be slightly more efficient for some shaders, but I personally prefer to do world space lighting just because it is so much easier to visualise and debug.

For deferred shading specifically, you don't really have any option here: you have to get your normals in world space in order to write them to your output buffer!

You don't need to invert a matrix for this: just multiply by the transpose. That is the same thing as an inverse for 3x3 rotation matrices (ones that don't contain any scaling, shears, etc), and will usually work just fine for tangent space transforms. If you have very distorted UV mappings (textures that are extremely stretched or slanted) you might see some minor errors from this: if that turns out to be a problem you could apply a proper matrix inverse during the build stage, modifying your vertex data to hold tangent space matrices going in whatever direction you prefer. I bet it won't be a problem though.

Re: XNA Framework Question on deferred shading with normal mapping

Keith Newton

Thanks for the reply Shawn. My deferred shading output normals are in world space (type HalfVector4) whereas my normal maps were in tangent space. Your recommendation on using the 3x3 transpose worked like a charm. I've written a little tool that converts normal maps from tangent space to world space and havn't noticed anything more than 1 or 2 minor differences. Thanks again!