Why does the default specular from surface lightning examples produce blocky specular? Is some vector not being interpolated per fragment but instead per vertex? or is there a lack of precision on some vector? Could not find any docu on this. Ref image shows left custom surface shader and right standard ggx.
Code (CSharp): SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf SimpleSpecular half4 LightingSimpleSpecular (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) { half3 h = normalize (lightDir + viewDir); half diff = max (0, dot (s.Normal, lightDir)); float nh = max (0, dot (s.Normal, h)); float spec = pow (nh, 48.0); half4 c; c.rgb = ( _LightColor0.rgb * spec) * atten; c.a = s.Alpha; return c; } struct Input { float2 uv_MainTex; }; sampler2D _MainTex; void surf (Input IN, inout SurfaceOutput o) { o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; } ENDCG } FallBack "Diffuse"
Try normalising your normals in the fragment shader. In your lighting function, before the lighting is calculated, add this line: Code (csharp): s.Normal = normalize(s.Normal); s.Normal contains your per-pixel world-space normals, which is essential for lighting. Normalising them will help "smooth out" the interpolation you get from the vertex shader, which is why it looks so blocky. Keep in mind, if you're using Unity 2017.2+ and a tangent-space normal map (o.Normal in your surf function), all surface shaders will automatically normalise your world-space normals in the fragment shader, so you shouldn't need to do this in those circumstances.
Yes, thankfully. Surface shaders that write to o.Normal will now generate this: Code (csharp): fixed3 worldN; worldN.x = dot(IN.tSpace0.xyz, o.Normal); worldN.y = dot(IN.tSpace1.xyz, o.Normal); worldN.z = dot(IN.tSpace2.xyz, o.Normal); worldN = normalize(worldN); o.Normal = worldN; However, this has created a new bug, because surface shaders that use the Standard lighting model are now normalising their world-space normals twice per-pixel, once in the surface shader above, and again in the Standard lighting function found in UnityPBSLighting.cginc. Not exactly great for performance.