- Home /

# WorldNormalVector(IN, o.Normal): how is it calculated?

Hi all, I'd like to know how does unity create the normal vector resulting from the world space normal vector and the tangent space normal map: where can I find any documentation?

Thanks

ilya_ca

### People who like this

The reason you are not getting an answer might be because it's not very clear what you're asking. At least I have no clue. What are the world space normal vector and tangent space normal map you're talking about?

Same here, I think only god (that you begged for help) can hear what you mean.

yea, sorry if I did not write all the infos

So, in the cg shader language there's a function : link text

float3 worldNormal; INTERNAL_DATA - will contain world normal vector if surface shader writes to o.Normal. To get the normal vector based on per-pixel normal map, use WorldNormalVector (IN, o.Normal).

just how is this computed? I ask this because I noticed it reduces a lot the number of variables I can use

You could take a look at the compiled shader... I can't see the code in any of the includes.

yes, I searched it in the compiled shader and in the cginc files, but it's not here. I think this is a internal function :(

However, does someone know how to create a inverse matrix given one?

Thanks :D

**Answer** by Bas-Smit
·
Feb 24, 2014 at 10:18 PM

So I know Im late to the party, but maybe t$$anonymous$$s will help someone someday. WorldNormalVector is a define that applies a rotation matrix to a vector, you can find it by opening a compiled shader:

```
#define WorldNormalVector(data,normal) fixed3(dot(data.TtoW0,
dot(data.TtoW1,normal), dot(data.TtoW2,normal))
```

The TtoW values come from the vertex program output when you use INTERNAL_DATA, it is calculated as follows:

```
TANGENT_SPACE_ROTATION;
o.TtoW0 = mul(rotation, ((float3x3)_Object2World)[0].xyz)*unity_Scale.w;
o.TtoW1 = mul(rotation, ((float3x3)_Object2World)[1].xyz)*unity_Scale.w;
o.TtoW2 = mul(rotation, ((float3x3)_Object2World)[2].xyz)*unity_Scale.w;
```

TANGENT_SPACE_ROTATION is a define that can be found in UnityCG.cginc:

```
// Declares 3x3 matrix 'rotation', filled with tangent space basis
#define TANGENT_SPACE_ROTATION \
float3 binormal = cross( v.normal, v.tangent.xyz ) * v.tangent.w; \
float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal )
```

frogsbo

neginfinity

ilya_ca

glitchers

yesiyuan

PrimalCoder

### People who like this

**Answer** by OP_toss
·
Sep 10, 2013 at 08:55 PM

I learned a bit answering t$$anonymous$$s :)

So basically you can do it almost the same way you'd do it for vertices. There's an _ObjectToWorld matrix.

```
float3 worldPosition = mul( _Object2World, float4( v.vertex, 1.0 ) ).xyz;
```

The problem is we're dealing with vectors and not positions, so we don't want to account for the translation component of the matrix. So we need to ignore the 4th columns of the matrix or the vector. So all you do is cast your vertex normal to a float4 with zero as its w component.

```
float3 worldNormal = mul( _Object2World, float4( v.normal, 0.0 ) ).xyz;
```

So a full test shader looks somet$$anonymous$$ng like t$$anonymous$$s:

```
Shader "Custom/Display Normals" {
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float3 wNormal : COLOR0;
};
v2f vert (appdata_base v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.wNormal = mul( _Object2World, float4( v.normal, 0.0 ) ).xyz;
return o;
}
half4 frag (v2f i) : COLOR
{
return half4 (i.wNormal, 1);
}
ENDCG
}
}
Fallback "VertexLit"
}
```

Credit to Patapom for the answer on a Unity forum.

Thanks for the information, but I already knew that. I am trying to understand the code beghind the function worldnormalvector( IN, o. Normal)

**Answer** by GearKlik
·
Jul 14, 2017 at 06:49 PM

Unity 5.6 Update

In UnityCG.cginc you'll find:

```
// Transforms direction from object to world space
inline float3 UnityObjectToWorldDir( in float3 dir )
{
return normalize(mul((float3x3)unity_ObjectToWorld, dir));
}
// Transforms direction from world to object space
inline float3 UnityWorldToObjectDir( in float3 dir )
{
return normalize(mul((float3x3)unity_WorldToObject, dir));
}
// Transforms normal from object to world space
inline float3 UnityObjectToWorldNormal( in float3 norm )
{
#ifdef UNITY_ASSUME_UNIFORM_SCALING
return UnityObjectToWorldDir(norm);
#else
// mul(IT_M, norm) => mul(norm, I_M) => {dot(norm, I_M.col0), dot(norm, I_M.col1), dot(norm, I_M.col2)}
return normalize(mul(norm, (float3x3)unity_WorldToObject));
#endif
}
```

Using normals in a vertex shader:

```
struct app2vert
{
...
float4 normal : NORMAL; // Use Fixed4?
...
};
...
float3 worldNormal = normalize(mul(v.normal, (float3x3)unity_WorldToObject));
float localSpaceMask = dot(v.normal, float4(myVector.xyz,0));
float WorldSpaceMask = dot(worldNormal, float4(myVector.xyz,0));
```

### Your answer

### Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.