I’m trying to get worldNormal to work in a surface shader together with a normal map, but it’s proving difficult.
The documentation mentions you need to use worldNormal; INTERAL_DATA if writing to o.Normal, and then access it using WorldNormalVector, like so:
struct Input {
float3 worldNormal; INTERNAL_DATA
};
float3 worldNormal = WorldNormalVector(IN, o.Normal);
However, the result of doing this isn’t what I’m expecting.
Here are two simple fresnel surface shaders - one writing to o.Normal and using WorldNormalVector, the other one does not. This is what you get:

As you can see, the starting right sphere behaves very oddly.
Here are the two shaders:
Writing to o.Normal and using WorldNormalVector (not working)
Shader "Custom/NormalTest" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_BumpMap ("Normalmap", 2D) = "bump" {}
_FresnelPower ("FresnelPower", Range(0,1)) = 0.5
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
sampler2D _BumpMap;
struct Input {
float2 uv_MainTex;
float3 worldNormal; INTERNAL_DATA
float3 viewDir;
};
half _FresnelPower;
fixed4 _Color;
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * 0;
o.Albedo = c.rgb;
o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_MainTex));
// Metallic and smoothness come from slider variables
// o.Metallic = _Metallic;
// o.Smoothness = _Glossiness;
o.Alpha = c.a;
float3 worldNormal = WorldNormalVector(IN, o.Normal);
float fresnel = pow(abs(1 - dot(IN.viewDir, worldNormal)), _FresnelPower * 10);
o.Emission = fresnel;
}
ENDCG
}
FallBack "Diffuse"
}
Not writing to o.Normal (working as expected):
Shader "Custom/NormalTest 1" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
// _BumpMap ("Normalmap", 2D) = "bump" {}
_FresnelPower ("FresnelPower", Range(0,1)) = 0.5
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
// sampler2D _BumpMap;
struct Input {
float2 uv_MainTex;
float3 worldNormal;
float3 viewDir;
};
half _FresnelPower;
fixed4 _Color;
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * 0;
o.Albedo = c.rgb;
// o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_MainTex));
// Metallic and smoothness come from slider variables
// o.Metallic = _Metallic;
// o.Smoothness = _Glossiness;
o.Alpha = c.a;
// float3 worldNormal = WorldNormalVector(IN, o.Normal);
float fresnel = pow(abs(1 - dot(IN.viewDir, IN.worldNormal)), _FresnelPower * 10);
o.Emission = fresnel;
}
ENDCG
}
FallBack "Diffuse"
}
What am I doing wrong?