- Home /
Why is my shader showing hard edge artifacts on mesh planes?
My shader is being used on all of the objects in my scene and all of them with one exception are showing up fine. However, if the light is small enough that its range can be escaped from view, the ground (a unity mesh plane, no textures applied) has hard edges depicted where the light's range ends. I've verified that this issue is singular to a flat plane by importing a plane from maya (same issue) and replacing the plane with a terrain (uses different terrain shader, no more hard edge). I'm at a loss why this issue only happens for flat planes.
I have a pictures below with two point lights with small range; as you can see the buildings and environmental props are unaffected by the same edge maligning the ground. The shader code is also included below.
Shader "UnityQuestionShader"{
Properties {
_Color ("Color Tint", Color) = (1.0,1.0,1.0,1.0)
_MainTex ("Diffuse Texture", 2D) = "white" {}
_BumpMap ("Normal Texture", 2D) = "bump" {}
_BumpDepth ("Bump Depth", Range(-2.0,2.0)) = 1
_SpecColor ("Specular Color", Color) = (1.0,1.0,1.0,1.0)
}
SubShader {
Pass {
Tags {"LightMode" = "ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 4.0
#pragma exclude_renderers flash
#include "UnityCG.cginc"
//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 _BumpDepth;
//unity defined variables
uniform float4 _LightColor0;
struct vertexOutput{
float4 pos : SV_POSITION;
float4 tex : TEXCOORD0;
float4 posWorld : TEXCOORD1;
float3 normalWorld : TEXCOORD2;
float3 tangentWorld : TEXCOORD3;
float3 binormalWorld : TEXCOORD4;
};
//vertex Function
vertexOutput vert(appdata_tan v){
vertexOutput o;
o.normalWorld = normalize( mul( float4( v.normal, 0.0 ), _World2Object ).xyz );
o.tangentWorld = normalize( mul( _Object2World, v.tangent ).xyz );
o.binormalWorld = normalize( cross(o.normalWorld, o.tangentWorld) * v.tangent.w );
o.posWorld = mul(_Object2World, v.vertex);
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.tex = v.texcoord;
return o;
}
//fragment function
float4 frag(vertexOutput IN) : COLOR
{
float3 viewDirection = normalize( _WorldSpaceCameraPos.xyz - IN.posWorld.xyz );
float3 lightDirection;
float atten;
if(_WorldSpaceLightPos0.w == 0.0){ //directional light
atten = 1.0;
lightDirection = normalize(_WorldSpaceLightPos0.xyz);
}
else{
float3 fragmentToLightSource = _WorldSpaceLightPos0.xyz - IN.posWorld.xyz;
float distance = length(fragmentToLightSource);
atten = 1.0/distance;
lightDirection = normalize(fragmentToLightSource);
}
//atten = 1.0 / (1.0 + 25.0*distance*distance);
//Texture Maps
float4 tex = tex2D(_MainTex, IN.tex.xy * _MainTex_ST.xy + _MainTex_ST.zw);
float4 texN = tex2D(_BumpMap, IN.tex.xy * _BumpMap_ST.xy + _BumpMap_ST.zw);
//unpackNormal function
float3 localCoords = float3(2.0 * texN.ag - float2(1.0, 1.0), 0.0);
localCoords.z = _BumpDepth;
//normal transpose matrix
float3x3 local2WorldTranspose = float3x3(
IN.tangentWorld,
IN.binormalWorld,
IN.normalWorld
);
//calculate normal direction
float3 normalDirection = normalize( mul( localCoords, local2WorldTranspose ) );
//Lighting
float3 ambientLighting = UNITY_LIGHTMODEL_AMBIENT.xyz * _Color.rgb;
float3 diffuseReflection = atten * _LightColor0.xyz * saturate(dot(normalDirection, lightDirection));
float3 specularReflection = diffuseReflection * _SpecColor.xyz * pow(saturate(dot(reflect(-lightDirection, normalDirection), viewDirection)) , tex.a*128.0);
float3 lightFinal = ambientLighting + diffuseReflection + specularReflection; //UNITY_LIGHTMODEL_AMBIENT.xyz
float4 litColor;
litColor.rgb = tex.rgb * lightFinal * _Color.rgb;
litColor.a = 1.0;
return litColor;
}
ENDCG
}
Pass {
Tags {"LightMode" = "ForwardAdd"}
Blend One One
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 4.0
#pragma exclude_renderers flash
#include "UnityCG.cginc"
//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 _BumpDepth;
//unity defined variables
uniform float4 _LightColor0;
struct vertexOutput{
float4 pos : SV_POSITION;
float4 tex : TEXCOORD0;
float4 posWorld : TEXCOORD1;
float3 normalWorld : TEXCOORD2;
float3 tangentWorld : TEXCOORD3;
float3 binormalWorld : TEXCOORD4;
};
//vertex Function
vertexOutput vert(appdata_tan v){
vertexOutput o;
o.normalWorld = normalize( mul( float4( v.normal, 0.0 ), _World2Object ).xyz );
o.tangentWorld = normalize( mul( _Object2World, v.tangent ).xyz );
o.binormalWorld = normalize( cross(o.normalWorld, o.tangentWorld) * v.tangent.w );
o.posWorld = mul(_Object2World, v.vertex);
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.tex = v.texcoord;
return o;
}
//fragment function
float4 frag(vertexOutput IN) : COLOR
{
float3 viewDirection = normalize( _WorldSpaceCameraPos.xyz - IN.posWorld.xyz );
float3 lightDirection;
float atten;
if(_WorldSpaceLightPos0.w == 0.0){ //directional light
atten = 1.0;
lightDirection = normalize(_WorldSpaceLightPos0.xyz);
}
else{
float3 fragmentToLightSource = _WorldSpaceLightPos0.xyz - IN.posWorld.xyz;
float distance = length(fragmentToLightSource);
atten = 1.0/distance;
lightDirection = normalize(fragmentToLightSource);
}
//atten = 1.0 / (1.0 + 25.0*distance*distance);
//Texture Maps
float4 tex = tex2D(_MainTex, IN.tex.xy * _MainTex_ST.xy + _MainTex_ST.zw);
float4 texN = tex2D(_BumpMap, IN.tex.xy * _BumpMap_ST.xy + _BumpMap_ST.zw);
//unpackNormal function
float3 localCoords = float3(2.0 * texN.ag - float2(1.0, 1.0), 0.0);
localCoords.z = _BumpDepth;
//normal transpose matrix
float3x3 local2WorldTranspose = float3x3(
IN.tangentWorld,
IN.binormalWorld,
IN.normalWorld
);
//calculate normal direction
float3 normalDirection = normalize( mul( localCoords, local2WorldTranspose ) );
//Lighting
float3 ambientLighting = UNITY_LIGHTMODEL_AMBIENT.xyz * _Color.rgb;
float3 diffuseReflection = atten * _LightColor0.xyz * saturate(dot(normalDirection, lightDirection));
float3 specularReflection = diffuseReflection * _SpecColor.xyz * pow(saturate(dot(reflect(-lightDirection, normalDirection), viewDirection)) , tex.a*128.0);
float3 lightFinal = ambientLighting + diffuseReflection + specularReflection; //UNITY_LIGHTMODEL_AMBIENT.xyz
float4 litColor;
litColor.rgb = tex.rgb * lightFinal * _Color.rgb;
litColor.a = 1.0;
return litColor;
}
ENDCG
}
}
//Fallback "Specular"
}
Did you found any solution for that, cause i am having the same problem.