I recently started writing on my first shader ever.
It’s a 2D texture + normal map sprite shader. In a first pass it handles ambient lighting and the scene’s single directional light and afterwards it does an additional pass for each other light in the scene.
The additional passes function exactly as intended. The first pass also functions exactly as intended if only one object using the materal exists in the scene.
However, if more than one object using the material exists, the illumination for the directional light doesn’t change with the object’s rotation anymore.
If you change the direction of the light, the object illumination still reacts accordingly, but a 90° rotatet sprite will still have the same pixels illuminated as a 0° rotated one and I have absolutely no idea what might cause this.
This is the code for the shader’s first pass:
Pass
{
Tags{ "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
uniform float4 _LightColor0;
// User-specified properties
uniform sampler2D _MainTex;
uniform sampler2D _Normal;
uniform float4 _CustomColor;
uniform float _Shininess;
uniform float4 _SpecColor;
struct VertexInput
{
float4 vertex : POSITION;
float4 vertexColor : COLOR;
float4 uv : TEXCOORD0;
};
struct VertexOutput
{
float4 pos : POSITION;
float4 vertexColor : COLOR;
float2 uv : TEXCOORD0;
};
VertexOutput vert(VertexInput input)
{
VertexOutput output;
output.pos = UnityObjectToClipPos(input.vertex);
output.uv = input.uv;
output.vertexColor = input.vertexColor;
return output;
}
float4 frag(VertexOutput input) : COLOR
{
float4 diffuseColor = tex2D(_MainTex, input.uv);
if (diffuseColor.r > 0.5 && diffuseColor.g <0.1 && diffuseColor.b <0.1)
{
diffuseColor.xyz = input.vertexColor.xyz;
}
diffuseColor.a *= input.vertexColor.a;
float3 ambientLighting = UNITY_LIGHTMODEL_AMBIENT.rgb;
float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz);
float3 normalDirection = (tex2D(_Normal, input.uv).xyz - 0.5f) * 2.0f;
normalDirection = mul(float4(normalDirection, 1.0f), unity_WorldToObject);
normalDirection.z *= -1;
normalDirection = normalize(normalDirection);
float normalDotLight = dot(normalDirection, lightDirection);
float specularLevel;
float diffuseLevel;
if (normalDotLight < 0.0f)
{
specularLevel = 0.0f;
diffuseLevel = 0.0f;
}
else
{
float3 viewDirection = float3(0.0f, 0.0f, -1.0f);
specularLevel = pow(max(0.0, dot(reflect(-lightDirection, normalDirection),viewDirection)), _Shininess);
diffuseLevel = normalDotLight;
}
float3 diffuseReflection = diffuseColor *_LightColor0 * diffuseLevel * diffuseColor.a + diffuseColor*ambientLighting;
float3 specularReflection = _LightColor0 * _SpecColor * specularLevel * diffuseColor.a;
return float4(diffuseReflection + specularReflection, diffuseColor.a);
}
ENDCG
}