Jump to content
  • Advertisement
Sign in to follow this  
MrSparkle

Convert Normal from Tangent to World space

This topic is 4444 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, in my pixel shader, I have the normal of a fragment in world space that is passed from the vertex shader (vNormalWS), and I have a normal in tangent space that I read from the NormalMap texture (vNormalTS). How can I convert the vNormalTS to world space so I can do a cube map texture lookup? Thanks, Christian

Share this post


Link to post
Share on other sites
Advertisement
Eric Lengyel's book covers the maths behind it, but from a quick glance you can just transpose the matrix to get a Tangent->Object transformation:


| Tx Bx Nx |
| Ty By Ny |
| Tz Bz Nz |


Presumably a regular inverse transpose world transform should take it from Object->World.

hth
Jack

Share this post


Link to post
Share on other sites
Thank you, I also thought about using a tangent-to-world-space matrix. But it seems very expensive for a pixel shader operation. I have to compute the tangent and the binormal first, because they are not provided by the vertex shader. Then I have to create a matrix and multiply the normal with the matrix. Isn't there any easier way, where the tangent-space normal is used to alter the world-space normal?

Share this post


Link to post
Share on other sites
Quote:
it seems very expensive for a pixel shader operation
Agreed - but thats probably why most people implement it in the opposite direction and at a coarser level (the VS) [smile]

You can convert a few vectors from world->tangent (relatively cheap) or you can convert every pixel from tangent->world (relatively expensive) - just depends which direction on the one:many mapping you want to go.

I'm sure you must be able to do some, or part, of the transformation at the vertex level. Determine the cube-map coordinate each each vertex and then pass this off to the PS for interpolation, then use the normal to perturb the interpolated coordinate (or something to that effect).

hth
Jack

Share this post


Link to post
Share on other sites
Quote:
Original post by jollyjeffers
Quote:
it seems very expensive for a pixel shader operation
Agreed - but thats probably why most people implement it in the opposite direction and at a coarser level (the VS) [smile]


Yes, I also do calulate the vNormalWS (normal in world space) in the vertex shader in order to use hardware interpolation.
But the vNormalTS (tangent space normal) is read from a normal map texture in the pixel shader. I need to combine them to do the environment map lookup. So, to restate my original question, is this possible without knowing the tangent and the binormal?

Share this post


Link to post
Share on other sites
I found a solution in this Gamasutra article: Let There Be Light!
They transform the tangent space normal to world space just like you said:


Is this really the way to go? It's a pretty time-consuming calculation and I have to additionally pass the tangent from the vertex shader to the pixel shader.

Share this post


Link to post
Share on other sites
It would seem that you may have to do it the long-way as I suggested and the article backed up.

The main alternative is to "think outside the box" - try and determine which parts of the equation are really necessary, possibly try and write out all the calculations long-hand and see if you can simplify/approximate/factorise.

A while back I was using procedural/cubic equations in a VS and spent a bit of time multiplying out all the equations on paper and managed to elminate a few duplicate terms and knock a fair number of instructions off my shader. Same with when I manually implemented bilinear filtering.

You could also look at cube-maps. Is there any way that you can use vNormalWS and/or vNormalTS to index into a 1D/2D/3D map that then provides you with the correct lookup into the environment map? Doing this might allow you to offload some of the expensive calculations to the CPU and trade it in against a bit of added storage and a dependent texture read.

One last thing that you could consider - look into gradient instructions in ps_3_0 if possible. I've not checked it out, but it was suggested to me a couple of days ago as a way of skipping TBN generation entirely.

hth
Jack

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!