mirror of
https://github.com/maxartz15/VolumetricLighting.git
synced 2024-11-14 02:35:36 +01:00
250 lines
4.8 KiB
Plaintext
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
|
|
}
|