- Home /
Shadow distance rendering in a custom shader
Hello everyone!
I have a custom shader with shadows. The main problem which I have a shadow distance rendering. Please take a look at the image below:
As we can see, in the default mobile/diffuse shader shadows ends smoothly. Is it possible to achieve the same effect in the custom shader? Maybe someone is able to give me some help in this.
Here is the shader which I'm using:
Shader "Test/Mobile Diffuse Colored"
{
SubShader
{
Pass
{
Tags {"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
// compile shader into multiple variants, with and without shadows
// (we don't care about any lightmaps yet, so skip these variants)
#pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap novertexlight
#pragma multi_compile_fog
// shadow helper functions and macros
#include "AutoLight.cginc"
struct v2f
{
SHADOW_COORDS(1) // put shadows data into TEXCOORD1
UNITY_FOG_COORDS(2)
fixed3 diff : COLOR0;
fixed3 color : TEXCOORD2;
fixed3 ambient : COLOR1;
fixed4 pos : SV_POSITION;
};
v2f vert (appdata_full v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.color = v.color;
fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
fixed nl = max(0, dot(worldNormal, _WorldSpaceLightPos0.xyz));
o.diff = nl * _LightColor0.rgb;
o.ambient = ShadeSH9(fixed4(worldNormal,1));
// compute shadows data
TRANSFER_SHADOW(o)
TRANSFER_VERTEX_TO_FRAGMENT(o);
UNITY_TRANSFER_FOG(o, o.pos);
return o;
}
fixed4 frag (v2f v) : COLOR
{
fixed4 col;
// compute shadow attenuation (1.0 = fully lit, 0.0 = fully shadowed)
fixed shadow = SHADOW_ATTENUATION(v);
// darken light's illumination with shadow, keep ambient intact
fixed3 lighting = v.diff * shadow + v.ambient;
col.rgb = lighting;
col.rgb *= v.color;
UNITY_APPLY_FOG(v.fogCoord, col);
return col;
}
ENDCG
}
// shadow casting support
UsePass "VertexLit/SHADOWCASTER"
}
}
Thank you for any response.
Answer by Namey5 · May 03, 2017 at 01:51 AM
Try using the following;
Shader "Test/Mobile Diffuse Colored"
{
Properties {
_Dist ("Fade Distance", Float) = 20.0
_Fade ("Fade Intensity", Float) = 1.0
}
SubShader
{
Pass
{
Tags {"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
// compile shader into multiple variants, with and without shadows
// (we don't care about any lightmaps yet, so skip these variants)
#pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap novertexlight
#pragma multi_compile_fog
// shadow helper functions and macros
#include "AutoLight.cginc"
half _Dist;
half _Fade;
struct v2f
{
SHADOW_COORDS(1) // put shadows data into TEXCOORD1
UNITY_FOG_COORDS(2)
fixed3 diff : COLOR0;
fixed3 color : TEXCOORD2;
float3 worldPos : TEXCOORD3;
fixed3 ambient : COLOR1;
fixed4 pos : SV_POSITION;
};
v2f vert (appdata_full v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.color = v.color;
fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
fixed nl = max(0, dot(worldNormal, _WorldSpaceLightPos0.xyz));
o.diff = nl * _LightColor0.rgb;
o.ambient = ShadeSH9(fixed4(worldNormal,1));
o.worldPos = mul (unity_ObjectToWorld, v.vertex);
// compute shadows data
TRANSFER_SHADOW(o)
TRANSFER_VERTEX_TO_FRAGMENT(o);
UNITY_TRANSFER_FOG(o, o.pos);
return o;
}
fixed4 frag (v2f v) : COLOR
{
fixed4 col;
// compute shadow attenuation (1.0 = fully lit, 0.0 = fully shadowed)
fixed shadow = saturate (lerp (SHADOW_ATTENUATION(v), 1.0, (distance (v.worldPos.xyz, _WorldSpaceCameraPos.xyz) - _Dist) * _Fade));
// darken light's illumination with shadow, keep ambient intact
fixed3 lighting = v.diff * shadow + v.ambient;
col.rgb = lighting;
col.rgb *= v.color;
UNITY_APPLY_FOG(v.fogCoord, col);
return col;
}
ENDCG
}
// shadow casting support
UsePass "VertexLit/SHADOWCASTER"
}
}
You do have to manually set the shadow fade distance property, although you can pass Unity's default value through a script, i.e. "Shader.SetGlobalFloat ("_Dist", ..."
Thank you for your resonse. I tried to check it and looks like it changes the shadow color. I tried to find out solutions but looks like it's a global problem. For example, there is: https://forum.unity3d.com/threads/getting-to-the-bottom-of-point-light-attenuation-squares.442757 a lot of things with the same problem and looks like it requires completely replacing Unity's lighting system which is unbelievable for me..
Not necessary. I just made some weird choices in writing the original. The above has been edited and now works properly (actually checked it myself).
Wow, it realy works! I spent so much time on this.. Thank you so much for your help!