I picked up this great tutorial Unity Grass Shader Tutorial and tried to add some customizations. I’ve been struggling to get lighting and shadows right and still don’t fully grasp the math.
What I want: uniform light intensity compared to ground and NOT pitch black shadows (see terrain shader part in the end). Here’s the grass fragment shader so far looks
sampler2D _MainTex;
float _Cutoff;
float4 _TranslucentColor, _BottomColor;
float _ShadowIntensity;
float4 frag (geometryOutput i) : SV_Target
{
float4 col = tex2D(_MainTex, i.uv);
clip(col.a - _Cutoff);
float3 normal = float3(0, 1, 0); //trying to achieve uniform light
float shadowIntensity = (1 - _ShadowIntensity); // to soften the shadow
float shadowAttenuation = SHADOW_ATTENUATION(i);
float NdotL = saturate(dot(normal, _WorldSpaceLightPos0)) + shadowIntensity;
float4 ambient = float4(ShadeSH9(float4(normal, 1)), 1);
float4 lightIntensity = NdotL * shadowAttenuation + ambient;
col *= lerp(_BottomColor, _TranslucentColor, i.uv.y) * _LightColor0;
col *= lightIntensity;
return col;
}
With correct _ShadowIntensity and Directional light angle it looks just fine but the results vary ridiculously between different light settings. Examples:
X-axis 15d and _ShadowIntensity 0.2
X-axis 30d and _ShadowIntensity 0.6
Desired result would be this.
I’m starting to feel like running in circles: some _ShadowIntensity value works in daylight, some in night but never both. Can anyone point out what calculation would keep lighting same as ground?
If it’s any help here’s the terrain shader’s lighting function, it’s basically from Unity docs ramp lighting without ramp texture (yes, i tried to imitate these calculations in grass fragment but still no avail)
inline half4 LightingRamp (SurfaceOutput s, half3 lightDir, half shadowAttenuation) {
float NdotL = dot(s.Normal, lightDir);
float lightIntensity = smoothstep(_LightThreshold - _LightSmoothness * 0.25, _LightThreshold + _LightSmoothness * 0.25, NdotL);
lightIntensity *= shadowAttenuation;
//calculate shadow color and mix light and shadow based on the light. Then tint it based on the light color, shadow intensity is 0.6
float3 shadowColor = lerp(s.Albedo, fixed3(0, 0, 0), _ShadowIntensity);
float4 color;
color.rgb = lerp(shadowColor, s.Albedo, lightIntensity) * _LightColor0.rgb;
color.a = s.Alpha;
return color;
}