Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I've got an object in HLSL and I'm using hardware instancing to render multiple copies. But I've come a bit of a cropper when it comes to the vertex normals. Currently I am not using normal mapping (although planning to implement it soon), I'm just putting the normals inside the vertex structure. I can put the world matrix and get it out in HLSL just fine, but I need the inverse transpose if I want the world position of the vertex normal from object space. How can I invert a matrix in HLSL? Or am I going to have to send the matrix and it's inverse in the instance buffer?

Or is this somehing that normal mapping doesn't require?

share|improve this question

3 Answers 3

up vote 5 down vote accepted

Or is this somehing that normal mapping doesn't require?

That's right, normal mapping doesn't require this.

In most cases the best way to do normal mapping is to store the normal map normals in tangent space. That is, a normal in the normal map pointing in the same direction as the surface normal is <0,0,1>. (This is why many normal maps are mostly blue, since they are stored in tangent space.)

Instead of transforming every normal in the normal map into world space (as you're about to do), you can just transform the lights and camera into tangent space on the CPU before the draw call. Then no transformation of the normal map normals is needed.

This means that you will do perhaps 2-10 matrix multiplications on the CPU, saving thousands or millions of transformations on the GPU.

See this article for a more in depth explanation of normal mapping and tangent space: http://www.gamasutra.com/view/feature/1515/messing_with_tangent_space.php

share|improve this answer
    
I also came to this conclusion- that it would be easier to transform the lighting parameters into object space on the CPU, and then into tangent space on the GPU. After all, the object space is the same for each instance. –  DeadMG Apr 29 '11 at 15:20

HLSL does not provide a function for invert but it does provide for transpose. So if your matrix is orthogonal you can just use transpose.
Also if you have scaling and is uniform you won't need the inverse transpose matrix. You can just use the world matrix to rotate your normal and then normalize it.
I apologize If I haven't understand your problem correctly.

share|improve this answer
    
So basically the only way to achieve this is to not have non-uniform scaling, or to hardware instance both the world matrix and the world inverse transpose. –  DeadMG Apr 25 '11 at 20:07
3  
Or to calculate your inverse transpose matrix on the CPU with D3DXMatrixInverse() and send it to the shader –  mayatrone Apr 25 '11 at 20:09
    
Or don't perform any transform on the normal map normal at all, store it in tangent space, and transform the (very few) lights and camera into tangent space instead. –  Olhovsky Apr 27 '11 at 23:22

Don't - you'll have to do it for each vertex for a regular vertex shader and this is a massive waste of GPU time. Anything complex like this that can be pre-calculated should be pre-calculated.

share|improve this answer
    
So I should hardware instance the world matrix and the world inverse transpose? –  DeadMG Apr 27 '11 at 12:35
    
@DeadMG: No. See my answer for the typical way to avoid these transforms. –  Olhovsky Apr 27 '11 at 23:21

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.