World to object is relatively straight forward.
float3 objectDir = mul((float3x3)unity_WorldToObject, worldDir);
Tangent to object is a little more work, and depends on how your shader is written. The short version being the shader needs to have the world space normal, tangent, and bitangent (aka binormal) vectors available in the fragment shader. For Surface Shaders you need to add a few things to the Input
struct to get access to those vectors. Specifically float3 worldNormal;
and INTERNAL_DATA
. Then you can call WorldNormalVector(IN, vector)
to transform a tangent vector into world space. With that you can construct a tangent to world matrix, and from that use the world to object transform above.
struct Input {
float2 uv_MainTex; // etc
float3 worldNormal;
INTERNAL_DATA
};
// inside surf function
float3 worldDir = WorldNormalVector(IN, tangentDir);
float3 objectDir = mul((float3x3)unity_WorldToObject, worldDir);
If you’re writing a vertex fragment shader you will already be creating a matrix to transform the tangent space normal maps into world space for lighting. So you’d use that and then the world to object transform.