Is there any way to convert a unit length world-space vector to tangent-space inside a shader? I ask because we need a tangent-space up vector for some bump mapped shader effects, because using Unity’s system for converting normal maps to world-space is causing us to run out of shader inputs.
If it’s inside of the vertex shader, it should be ok.
Otherwise I think it’ll end up being just as expensive as tangent to world requirements (possibly a little cheaper on interpolators as you only need one, but then you’re doing all the rotation per-pixel rather than per-vertex).
Using Unity’s macro;
float3 objUp = mul((float3x3)_World2Object, float3(0,1,0)); // Convert world up to object up so it can be converted to tangent up.
TANGENT_SPACE_ROTATION;
float3 tangentUp = mul(rotation, objUp);
Without Unity’s macro;
float3 objUp = mul((float3x3)_World2Object, float3(0,1,0)); // Convert world up to object up so it can be converted to tangent up.
float3 binormal = cross( v.normal, v.tangent.xyz ) * v.tangent.w;
float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );
float3 tangentUp = mul(rotation, objUp);
Also, note that normals and tangents aren’t kept normalized when building for mobile devices (and maybe Ouya?), for skinned meshes, so you’d need to do that manually if that’s something you need to support.
Right, right. If you write in Cg, the auto-generated GLSL will contain normalize instructions that you didn’t explicitly write out. If you write in GLSL, then you have to do it yourself.
Thanks for the tips, they have been most enlightening.
Sadly, I found out that they can’t fix my underlying problem, since I realized I specifically need world space for parts of my shaders. Then I found out the ones that I thought I could get away with it (ie. terrain shaders) have so many TEXCOORDs bound for texture coordinates that they aren’t enough for the rest of my requirements.