Shader float value weirdness

Shader “Shader Tuts/Lambert” {
Properties {
_Color (“Color”, Color) = (1.0,1.0,1.0,1.0)
_MainTex (“Main Tex”, 2D) = “white” {}
_BumpMap (“Bump Map”, 2D) = “bump” {}
_BumpDepth (“Bump Depth”, Range(-2.0, 2.0)) = 0.0
_SpecColor (“Specular Color”, Color) = (1.0, 1.0, 1.0, 1.0)
_Shininess (“Shininess”, float) = 0.0
}

	SubShader {
		Pass {
			Tags {
				"LightMode" = "ForwardBase"
			}

			CGPROGRAM
				// pragmas
				#pragma vertex vert
				#pragma fragment frag

				// user defined variables
				uniform sampler2D _MainTex;
				uniform float4 _MainTex_ST;
				uniform sampler2D _BumpMap;
				uniform float4 _BumpMap_ST;
				uniform float4 _Color;
				uniform float4 _SpecColor;
				uniform float _Shininess;
				uniform float _BumpDepth;

				// inbuilt variables
				uniform float4 _LightColor0;

				// base input structs
				struct vertexInput {
					float4 vertex : POSITION;
					float3 normal : NORMAL;
					float4 texcoord : TEXCOORD0;
					float4 tangent : TANGENT;
				};

				struct vertexOutput {
					float4 pos : SV_POSITION;
					float4 tex : TEXCOORD0;
					float4 posWorld : TEXCOORD1;
					float3 normalWorld : TEXCOORD2;
					float3 tangentWorld : TEXCOORD3;
					float3 binormalWorld : TEXCOORD4;
				};

				// vertex program
				vertexOutput vert(vertexInput v) {
					vertexOutput o;

					o.posWorld = mul(_Object2World, v.vertex);
					// convert normal from object space to world space and normalize
					o.normalWorld = normalize(mul(float4(v.normal, 0.0f), _World2Object));
					o.tangentWorld = normalize(mul(_Object2World, v.tangent));
					o.binormalWorld = normalize(cross(o.normalWorld, o.tangentWorld) * v.tangent.w);
					o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
					o.tex = v.texcoord;
					return o;
				}

				float4 frag(vertexOutput i) : COLOR {
					// direction calculations
					float3 lightDir = normalize(_WorldSpaceLightPos0).xyz;
					float3 viewDir = normalize(_WorldSpaceCameraPos - i.posWorld);
					float atten = 1.0f;

					// texture calculations
					float4 tex = tex2D(_MainTex, i.tex.xy * _MainTex_ST.xy + _MainTex_ST.zw);
					float4 encodedNormal = tex2D(_BumpMap, i.tex.xy * _BumpMap_ST.xy + _BumpMap_ST.zw);

					// unpack normals, Unity has inbuild function but we will create our own since its more efficient
					float3 localCoords = (2.0 * encodedNormal.ag - float2(1.0,1.0), 0.0);
					localCoords.z = 1.0 - 0.5 * dot(localCoords, localCoords);

					// normal transpose matrix
					float3x3 local2WorldTranspose = float3x3(i.tangentWorld,
															i.binormalWorld,
															i.normalWorld);

					float3 normalDir = normalize(mul(localCoords, local2WorldTranspose));
					float3 reflectedDir = reflect(-lightDir, normalDir);

					// light calculations
					float3 diffuseReflection = atten * _LightColor0.xyz * max(0.0, dot(normalDir, lightDir));
					float3 specularReflection = diffuseReflection * _SpecColor.rgb * pow(max(0.0, dot(reflectedDir, viewDir)), _Shininess);
					float3 finalLight = diffuseReflection + specularReflection + UNITY_LIGHTMODEL_AMBIENT;

					return float4(tex.xyz * finalLight * _Color.rgb , 1.0);
				}

				// fragment program
			ENDCG
		}
	}

	// Fallback "Diffuse"
}

In the above shader, if I set the value of _Shininess to 0 from the editor I get this result

Instead, if I replace the value of _Shininess to 0 manually in the shader at this line:

float3 specularReflection = diffuseReflection * _SpecColor.rgb * pow(max(0.0, dot(reflectedDir, viewDir)), 0.0);

then I get this result:

What exactly is going on here!? Why does it behave differently when the value is set in the editor and when its hardcoded! Any help would be appreciated. Thank you.

It’s result of pow(x,0) always being 1 and due to how pow(x,y) is compiled. If y is not known at compile time, it is compiled as exp(y*log(x))otherwise it’s compiled as several multiplications. So if you exchange your pow(max(0.0,dot(reflectedDir,viewDir)), 0) to exp(0*log(max(0.0,dot(reflectedDir,viewDir)))) you will get same effect as when you use pow(x,y) with y not being constant. It gets black when that max(…) statement returns 0 and log(0) is defined as -INF if I remember right (shader default, not mathematical).