- Home /
Shadow artifacts on vertex animation shader
I'm trying to write a simple vertex-animation-surface shader. The animation works fine and I managed to add animated shadows by using pragma: addshadow. However, the shader still produces strange artifacts: I can get rid of them by changing the shader's render queue to "Transparent" but that also disables shadow-receiving. Any ideas?
Here's my code:
Shader "Custom/AnimateTest" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader {
Tags { "RenderType"="Opaque" "DisableBatching" = "True" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard vertex:myvert addshadow
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
void myvert(inout appdata_full v) {
v.vertex = v.vertex + ((sin(_Time.x * 50.0) + 1.0) * 0.5) * 0.50;
}
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
Thanks in advance! :)
Answer by Friedemann_A · Jul 19, 2018 at 07:43 PM
The great @bgolus helped me figure it out on the forums, posting the solution here in case somebody needs it in the future:
The v.vertex is a float4 value, the xyz values of which are the position, but you do not want to modify the w component unless you know exactly what you're doing. For the main forward passes modifying the w component doesn't do anything as the shaders forceably override it to a value of 1.0 (the value it defaults to), but the shadow caster pass used for the camera depth and shadows maps do not, and the side effect of modifying the w component is it scales the object in projection space, which moves it away from the camera on PC and desktop due to the use of a reversed depth buffer. The solution is to only modify the xyz components.
The correct line of code in the vertex shader would be:
v.vertex.xyz = v.vertex.xyz + (sin(_Time.y * 2.5) - 1.0) * 0.25;