Hey all,
This is NOT a rant, but rather a request for help to spot the flaws in my understanding and where I need to go and study more.
So, yes, this is a noob question, however it’s one I haven’t been able to find and answer for on Google. They say that the Normal Maps are in tangent space, and they need to be converted… but aren’t Albedo textures ALSO in tangent space, and yet we don’t convert those…
So why do we need to convert from tangent space?
Allow me to illustrate my question:
I have this normal map (from a wiki site):
And I’m applying it to a quad using this shader (Stripped right back to help illustrate my question):
Shader "DiffuseNormalMap"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_BumpMap("Normal Map", 2D) = "bump" {}
}
SubShader
{
Tags { "LightMode" = "ForwardBase" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float3 normal: NORMAL;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
float3 worldNormal : TEXCOORD1;
};
uniform sampler2D _MainTex;
uniform sampler2D _BumpMap;
uniform float4 _MainTex_ST;
uniform float4 _LightColor0;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// Simply unpacking the normal and adding it the the vertex normal (normalized for interpolation)
float3 normalNormal = UnpackNormal(tex2D(_BumpMap,i.uv));
float4 diffuse = _LightColor0 * max(0.0, dot((normalize(i.worldNormal)+normalNormal), _WorldSpaceLightPos0.xyz));
diffuse += UNITY_LIGHTMODEL_AMBIENT;
fixed4 col = diffuse * tex2D(_MainTex, i.uv);
return col;
}
ENDCG
}
}
}
And here’s the result (You can see the direction of the light source):
So, it lights up okay. I rotate the quad or the light source and it seems to light up okay. So, why do I need to perform any more calculations? What problems would be encountered if not converted from tangent space?
I have looked into several pages and have tried to wrap my head around the ‘why’, but they just seem to jump straight into the ‘how’ - unfortunately I learn better when I know the why first… ![]()
I’m learning shading from Unity’s reference and the awesome WikiBooks site (Cg Programming/Unity/Lighting of Bumpy Surfaces - Wikibooks, open books for an open world) but still can’t find an answer to my question, I’ve even tried LearnOpenGL - Normal Mapping but still no luck ![]()
As always I appreciate any and all help - many thanks! XD
NOTE: the lighting of the bump map seems to be reversed, is THIS the reason for the tangent space conversion?


