VolumetricLighting/Assets/VolumetricFog/Shaders/BlurShadowmap.shader
2022-04-03 17:47:44 +02:00

250 lines
4.8 KiB
Plaintext

Shader "Hidden/BlurShadowmap" {
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
_Bloom ("Bloom (RGB)", 2D) = "black" {}
}
CGINCLUDE
#include "UnityCG.cginc"
half4 _TexelSize;
struct v2f_tap
{
float4 pos : SV_POSITION;
half2 uv20 : TEXCOORD0;
half2 uv21 : TEXCOORD1;
half2 uv22 : TEXCOORD2;
half2 uv23 : TEXCOORD3;
};
v2f_tap vert4Tap ( appdata_img v )
{
v2f_tap o;
o.pos = v.vertex;
o.uv20 = v.texcoord + _TexelSize.xy;
o.uv21 = v.texcoord + _TexelSize.xy * half2(-0.5, -0.5);
o.uv22 = v.texcoord + _TexelSize.xy * half2( 0.5, -0.5);
o.uv23 = v.texcoord + _TexelSize.xy * half2(-0.5, 0.5);
return o;
}
// TODO: consolidate with the above, but make sure both area and dir shadows work
v2f_tap vert4TapDir ( appdata_img v )
{
v2f_tap o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv20 = v.texcoord + _TexelSize.xy;
o.uv21 = v.texcoord + _TexelSize.xy * half2(-0.5, -0.5);
o.uv22 = v.texcoord + _TexelSize.xy * half2( 0.5, -0.5);
o.uv23 = v.texcoord + _TexelSize.xy * half2(-0.5, 0.5);
return o;
}
float4 _ZParams;
float _ESMExponent;
Texture2D _Shadowmap;
SamplerComparisonState sampler_Shadowmap;
// To get a sampler, which doesn't do comparison
Texture2D _ShadowmapDummy;
SamplerState sampler_ShadowmapDummy;
#define VSM 1
float4 fragDownsampleFromShadowmapFormat ( v2f_tap i ) : SV_Target
{
float4 z;
z.r = _Shadowmap.Sample(sampler_ShadowmapDummy, i.uv20).r;
z.g = _Shadowmap.Sample(sampler_ShadowmapDummy, i.uv21).r;
z.b = _Shadowmap.Sample(sampler_ShadowmapDummy, i.uv22).r;
z.a = _Shadowmap.Sample(sampler_ShadowmapDummy, i.uv23).r;
// The texture contains just 0. But we need to sample it somewhere for Unity to initialize the corresponding sampler.
z.r += _ShadowmapDummy.Sample(sampler_ShadowmapDummy, 0).a;
#if UNITY_REVERSED_Z
z = 1.0 - z;
#endif
// Transform to linear z, 0 at near, 1 at far
z = z * 2 - 1;
z = _ZParams.x * (z + 1.0) / (z + _ZParams.y);
#if VSM
// TODO: this is wrong. We can't average/blur z values before converting to VSM.
// This doesn't affect m, but affects m * m, so I should swap those two lines.
float m = dot(z, 0.25);
return float4(m, m * m, 0, 0);
#else
z = exp(_ESMExponent * z);
return dot(z, 0.25);
#endif
}
sampler2D _DirShadowmap;
float4 fragDownsampleFromShadowmapFormatDir ( v2f_tap i ) : SV_Target
{
float4 z;
z.r = tex2D (_DirShadowmap, i.uv20).r;
z.g = tex2D (_DirShadowmap, i.uv21).r;
z.b = tex2D (_DirShadowmap, i.uv22).r;
z.a = tex2D (_DirShadowmap, i.uv23).r;
// return z.r;
// Transform to linear z, 0 at near, 1 at far
// z = z * 2 - 1;
// z = _ZParams.x * (z + 1.0) / (z + _ZParams.y);
#if 1
// float m = dot(z, 0.25);
// return float4(m, m * m, 0, 0);
float4 z2 = z * z;
return float4(dot(z, 0.25), dot(z2, 0.25), 0, 0);
#else
//z = exp(_ESMExponent * z);
z = exp(40.0 * z);
return dot(z, 0.25);
#endif
}
sampler2D _MainTex;
float4 fragDownsample ( v2f_tap i ) : SV_Target
{
float4 color = tex2D (_MainTex, i.uv20);
color += tex2D (_MainTex, i.uv21);
color += tex2D (_MainTex, i.uv22);
color += tex2D (_MainTex, i.uv23);
return color * 0.25;
}
struct v2f
{
float4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
half2 offs : TEXCOORD1;
};
float _BlurSize;
v2f vertBlurHorizontal (appdata_img v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
//o.pos = v.vertex;
o.uv = v.texcoord;
o.offs = _TexelSize.xy * half2(1.0, 0.0) * _BlurSize;
return o;
}
v2f vertBlurVertical (appdata_img v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
//o.pos = v.vertex;
o.uv = v.texcoord;
o.offs = _TexelSize.xy * half2(0.0, 1.0) * _BlurSize;
return o;
}
float4 fragBlur8(v2f i) : SV_Target
{
//half2 coords = i.uv.xy;
half2 coords = i.uv.xy - i.offs * 5.0;
float4 color = 0;
for(int k = 0; k < 11; k++)
{
color += tex2D(_MainTex, coords);
coords += i.offs;
}
return color/11.0;
}
ENDCG
SubShader {
ZTest Off Cull Off ZWrite Off Blend Off
// 0
Pass
{
CGPROGRAM
#pragma vertex vert4Tap
#pragma fragment fragDownsampleFromShadowmapFormat
ENDCG
}
// 1
Pass
{
CGPROGRAM
#pragma vertex vert4Tap
#pragma fragment fragDownsample
ENDCG
}
// 2
Pass {
ZTest Always
Cull Off
CGPROGRAM
#pragma vertex vertBlurVertical
#pragma fragment fragBlur8
ENDCG
}
// 3
Pass {
ZTest Always
Cull Off
CGPROGRAM
#pragma vertex vertBlurHorizontal
#pragma fragment fragBlur8
ENDCG
}
// 4
Pass
{
CGPROGRAM
#pragma vertex vert4TapDir
#pragma fragment fragDownsampleFromShadowmapFormatDir
ENDCG
}
// 5
Pass
{
CGPROGRAM
#pragma vertex vert4TapDir
#pragma fragment fragDownsample
ENDCG
}
}
FallBack Off
}