init
This commit is contained in:
commit
2fe6ca2f65
1473 changed files with 251771 additions and 0 deletions
660
gamedata/shaders/d3d11/shadow.hlsli
Normal file
660
gamedata/shaders/d3d11/shadow.hlsli
Normal file
|
|
@ -0,0 +1,660 @@
|
|||
#ifndef SHADOW_H
|
||||
#define SHADOW_H
|
||||
|
||||
#include "common.hlsli"
|
||||
uniform float4x4 m_shadow;
|
||||
|
||||
Texture2D s_smap : register(ps, t0);
|
||||
SamplerComparisonState smp_smap;
|
||||
sampler smp_jitter;
|
||||
|
||||
Texture2D jitter0;
|
||||
Texture2D jitter1;
|
||||
|
||||
#ifndef USE_ULTRA_SHADOWS
|
||||
#define KERNEL 0.6f
|
||||
#else
|
||||
#define KERNEL 1.0f
|
||||
#endif
|
||||
|
||||
float4 sm_gather(float2 tc, int2 offset)
|
||||
{
|
||||
#ifdef SM_4_1
|
||||
return s_smap.Gather(smp_nofilter, tc, offset);
|
||||
#else
|
||||
static const float scale = float(SMAP_size);
|
||||
float2 fc = frac(tc * scale);
|
||||
|
||||
tc -= fc / scale;
|
||||
|
||||
float s0 = s_smap.SampleLevel(smp_nofilter, tc, 0, offset + int2(0, 1)).x;
|
||||
float s1 = s_smap.SampleLevel(smp_nofilter, tc, 0, offset + int2(1, 1)).x;
|
||||
float s2 = s_smap.SampleLevel(smp_nofilter, tc, 0, offset + int2(1, 0)).x;
|
||||
float s3 = s_smap.SampleLevel(smp_nofilter, tc, 0, offset + int2(0, 0)).x;
|
||||
|
||||
return float4(s0, s1, s2, s3);
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// hardware + PCF
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
float sample_hw_pcf(float4 tc, float4 shift)
|
||||
{
|
||||
static const float ts = KERNEL / float(SMAP_size);
|
||||
|
||||
tc.xyz /= tc.w;
|
||||
tc.xy += shift.xy * ts;
|
||||
|
||||
return s_smap.SampleCmpLevelZero(smp_smap, tc.xy, tc.z).x;
|
||||
}
|
||||
|
||||
#define GS2 3
|
||||
|
||||
float shadow_hw(float4 tc)
|
||||
{
|
||||
float s0 = sample_hw_pcf(tc, float4(-1, -1, 0, 0));
|
||||
float s1 = sample_hw_pcf(tc, float4(+1, -1, 0, 0));
|
||||
float s2 = sample_hw_pcf(tc, float4(-1, +1, 0, 0));
|
||||
float s3 = sample_hw_pcf(tc, float4(+1, +1, 0, 0));
|
||||
|
||||
return (s0 + s1 + s2 + s3) / 4.h;
|
||||
}
|
||||
|
||||
#if SUN_QUALITY >= 4
|
||||
#define FILTER_SIZE 11
|
||||
#define FS FILTER_SIZE
|
||||
#define FS2 (FILTER_SIZE / 2)
|
||||
|
||||
static const float W2[11][11] =
|
||||
{
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.2f, 0.2f, 0.2f, 0.2f, 0.2f, 0.2f, 0.2f, 0.2f, 0.2f, 0.0f },
|
||||
{ 0.0f, 0.2f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.0f },
|
||||
{ 0.0f, 0.2f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.0f },
|
||||
{ 0.0f, 0.2f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.0f },
|
||||
{ 0.0f, 0.2f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.0f },
|
||||
{ 0.0f, 0.2f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.0f },
|
||||
{ 0.0f, 0.2f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.0f },
|
||||
{ 0.0f, 0.2f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.0f },
|
||||
{ 0.0f, 0.2f, 0.2f, 0.2f, 0.2f, 0.2f, 0.2f, 0.2f, 0.2f, 0.2f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
};
|
||||
|
||||
static const float W1[11][11] =
|
||||
{
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.2f, 0.2f, 0.2f, 0.2f, 0.2f, 0.2f, 0.2f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.2f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.2f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.2f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.2f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.2f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.2f, 0.2f, 0.2f, 0.2f, 0.2f, 0.2f, 0.2f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
};
|
||||
|
||||
static const float W0[11][11] =
|
||||
{
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.1f, 0.1f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.1f, 1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.1f, 0.1f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
};
|
||||
|
||||
float Fw(int r, int c, float fL)
|
||||
{
|
||||
return (1.0 - fL) * (1.0 - fL) * (1.0 - fL) * W0[r][c] +
|
||||
3.0f * (1.0 - fL) * (1.0 - fL) * fL * W1[r][c] +
|
||||
3.0f * fL * fL * (1.0 - fL) * W2[r][c] +
|
||||
fL * fL * fL * 1.0f;
|
||||
}
|
||||
|
||||
#define BLOCKER_FILTER_SIZE 11
|
||||
#define BFS BLOCKER_FILTER_SIZE
|
||||
#define BFS2 (BLOCKER_FILTER_SIZE / 2)
|
||||
|
||||
#define SUN_WIDTH 300.0f
|
||||
|
||||
// uses gather for DX11/10.1 and visibilty encoding for DX10.0
|
||||
static const float2 poissonDisk[16] = {
|
||||
float2( -0.94201624f, -0.39906216f ),
|
||||
float2( 0.94558609f, -0.76890725f ),
|
||||
float2( -0.094184101f, -0.92938870f ),
|
||||
float2( 0.34495938f, 0.29387760f ),
|
||||
float2( -0.91588581f, 0.45771432f ),
|
||||
float2( -0.81544232f, -0.87912464f ),
|
||||
float2( -0.38277543f, 0.27676845f ),
|
||||
float2( 0.97484398f, 0.75648379f ),
|
||||
float2( 0.44323325f, -0.97511554f ),
|
||||
float2( 0.53742981f, -0.47373420f ),
|
||||
float2( -0.26496911f, -0.41893023f ),
|
||||
float2( 0.79197514f, 0.19090188f ),
|
||||
float2( -0.24188840f, 0.99706507f ),
|
||||
float2( -0.81409955f, 0.91437590f ),
|
||||
float2( 0.19984126f, 0.78641367f ),
|
||||
float2( 0.14383161f, -0.14100790f )
|
||||
};
|
||||
|
||||
#define PCSS_PIXEL 5
|
||||
#define PCSS_STEP 5
|
||||
#define PCSS_PIXEL_MIN 1.0f
|
||||
#define PCSS_SUN_WIDTH 300.f
|
||||
#define PCSS_NUM_SAMPLES 16
|
||||
|
||||
float shadow_extreme_quality( float3 tc )
|
||||
{
|
||||
int3 uv = int3(tc.xy * float(SMAP_size), 0);
|
||||
float zBlock = tc.z - 0.0001f;
|
||||
float avgBlockerDepth = 0.f;
|
||||
float blockerCount = 0.f;
|
||||
|
||||
[unroll] for( int row = -PCSS_PIXEL; row <= PCSS_PIXEL; row += PCSS_STEP )
|
||||
{
|
||||
[unroll] for( int col = -PCSS_PIXEL; col <= PCSS_PIXEL; col += PCSS_STEP )
|
||||
{
|
||||
float shadowMapDepth = s_smap.Load( uv, int2( col, row ) ).x;
|
||||
float b1 = ( shadowMapDepth < zBlock ) ? 1.f : 0.f;
|
||||
blockerCount += b1;
|
||||
avgBlockerDepth += shadowMapDepth * b1;
|
||||
}
|
||||
}
|
||||
|
||||
if( blockerCount < 1 || blockerCount >= 9 )
|
||||
return 1.f - min(1.f, blockerCount);
|
||||
|
||||
avgBlockerDepth /= blockerCount;
|
||||
float fRatio = saturate( ( ( tc.z - avgBlockerDepth ) * PCSS_SUN_WIDTH ) / avgBlockerDepth );
|
||||
fRatio *= fRatio;
|
||||
fRatio = max(PCSS_PIXEL_MIN, fRatio * float(PCSS_PIXEL)) / float(SMAP_size);
|
||||
|
||||
float s = 0.f;
|
||||
[unroll] for( uint i = 0; i < PCSS_NUM_SAMPLES; ++i )
|
||||
{
|
||||
float2 offset = poissonDisk[i] * fRatio;
|
||||
s += s_smap.SampleCmpLevelZero( smp_smap, tc.xy + offset, tc.z ).x;
|
||||
}
|
||||
return s / PCSS_NUM_SAMPLES;
|
||||
}
|
||||
|
||||
float4 Fw(int r, int c)
|
||||
{
|
||||
return float4(W0[r][c], W1[r][c], W2[r][c], 1.0f);
|
||||
}
|
||||
|
||||
//======================================================================================
|
||||
// This shader computes the contact hardening shadow filter
|
||||
//======================================================================================
|
||||
float shadow_extreme_quality_fused(float3 tc)
|
||||
{
|
||||
float4 s = (0.0f).xxxx;
|
||||
float2 stc = (SMAP_size * tc.xy) + float2(0.5, 0.5);
|
||||
float2 tcs = floor(stc);
|
||||
float2 fc;
|
||||
int row;
|
||||
int col;
|
||||
float w = 0.0;
|
||||
float avgBlockerDepth = 0;
|
||||
float blockerCount = 0;
|
||||
float fRatio;
|
||||
float4 v1[FS2 + 1];
|
||||
float2 v0[FS2 + 1];
|
||||
float2 off;
|
||||
|
||||
fc = stc - tcs;
|
||||
tc.xy = tc.xy - (fc * (1.0f / SMAP_size));
|
||||
|
||||
// filter shadow map samples using the dynamic weights
|
||||
[unroll(FS)]
|
||||
for (row = -FS2; row <= FS2; row += 2)
|
||||
{
|
||||
for (col = -FS2; col <= FS2; col += 2)
|
||||
{
|
||||
float4 d4;
|
||||
|
||||
#ifndef PS_4
|
||||
d4 = s_smap.Gather(smp_nofilter, tc.xy + (1.0f / SMAP_size) * float2(col, row));
|
||||
#else
|
||||
d4.w = s_smap.SampleLevel(smp_nofilter, tc.xy + (1.0f / SMAP_size) * float2(col, row), 0).x;
|
||||
d4.z = s_smap.SampleLevel(smp_nofilter, tc.xy + (1.0f / SMAP_size) * float2(col + 1, row), 0).x;
|
||||
d4.y = s_smap.SampleLevel(smp_nofilter, tc.xy + (1.0f / SMAP_size) * float2(col + 1, row + 1), 0).x;
|
||||
d4.x = s_smap.SampleLevel(smp_nofilter, tc.xy + (1.0f / SMAP_size) * float2(col, row + 1), 0).x;
|
||||
#endif
|
||||
float4 b4 = (tc.zzzz <= d4) ? (0.0f).xxxx : (1.0f).xxxx;
|
||||
|
||||
v1[(col + FS2) / 2] = (tc.zzzz <= d4) ? (1.0f).xxxx : (0.0f).xxxx;
|
||||
blockerCount += dot(b4, (1.0).xxxx);
|
||||
avgBlockerDepth += dot(d4, b4);
|
||||
|
||||
if (col == -FS2)
|
||||
{
|
||||
s += (1 - fc.y) * (v1[0].w * (Fw(row + FS2, 0) -
|
||||
Fw(row + FS2, 0) * fc.x) +
|
||||
v1[0].z *
|
||||
(fc.x * (Fw(row + FS2, 0) -
|
||||
Fw(row + FS2, 1)) +
|
||||
Fw(row + FS2, 1)));
|
||||
s += (fc.y) * (v1[0].x * (Fw(row + FS2, 0) -
|
||||
Fw(row + FS2, 0) * fc.x) +
|
||||
v1[0].y * (fc.x * (Fw(row + FS2, 0) -
|
||||
Fw(row + FS2, 1)) +
|
||||
Fw(row + FS2, 1)));
|
||||
if (row > -FS2)
|
||||
{
|
||||
s += (1 - fc.y) * (v0[0].x * (Fw(row + FS2 - 1, 0) -
|
||||
Fw(row + FS2 - 1, 0) * fc.x) +
|
||||
v0[0].y *
|
||||
(fc.x * (Fw(row + FS2 - 1, 0) -
|
||||
Fw(row + FS2 - 1, 1)) +
|
||||
Fw(row + FS2 - 1, 1)));
|
||||
s += (fc.y) * (v1[0].w * (Fw(row + FS2 - 1, 0) -
|
||||
Fw(row + FS2 - 1, 0) * fc.x) +
|
||||
v1[0].z *
|
||||
(fc.x * (Fw(row + FS2 - 1, 0) -
|
||||
Fw(row + FS2 - 1, 1)) +
|
||||
Fw(row + FS2 - 1, 1)));
|
||||
}
|
||||
}
|
||||
else if (col == FS2)
|
||||
{
|
||||
s += (1 - fc.y) * (v1[FS2].w * (fc.x * (Fw(row + FS2, FS - 2) -
|
||||
Fw(row + FS2, FS - 1)) +
|
||||
Fw(row + FS2, FS - 1)) +
|
||||
v1[FS2].z * fc.x *
|
||||
Fw(row + FS2, FS - 1));
|
||||
s += (fc.y) * (v1[FS2].x * (fc.x * (Fw(row + FS2, FS - 2) -
|
||||
Fw(row + FS2, FS - 1)) +
|
||||
Fw(row + FS2, FS - 1)) +
|
||||
v1[FS2].y * fc.x *
|
||||
Fw(row + FS2, FS - 1));
|
||||
if (row > -FS2)
|
||||
{
|
||||
s += (1 - fc.y) * (v0[FS2].x * (fc.x *
|
||||
(Fw(row + FS2 - 1, FS - 2) -
|
||||
Fw(row + FS2 - 1, FS - 1)) +
|
||||
Fw(row + FS2 - 1, FS - 1)) +
|
||||
v0[FS2].y * fc.x * Fw(row + FS2 - 1, FS - 1));
|
||||
s += (fc.y) * (v1[FS2].w * (fc.x *
|
||||
(Fw(row + FS2 - 1, FS - 2) -
|
||||
Fw(row + FS2 - 1, FS - 1)) +
|
||||
Fw(row + FS2 - 1, FS - 1)) +
|
||||
v1[FS2].z * fc.x * Fw(row + FS2 - 1, FS - 1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s += (1 - fc.y) * (v1[(col + FS2) / 2].w * (fc.x *
|
||||
(Fw(row + FS2, col + FS2 - 1) -
|
||||
Fw(row + FS2, col + FS2 + 0)) +
|
||||
Fw(row + FS2, col + FS2 + 0)) +
|
||||
v1[(col + FS2) / 2].z * (fc.x *
|
||||
(Fw(row + FS2, col + FS2 - 0) -
|
||||
Fw(row + FS2, col + FS2 + 1)) +
|
||||
Fw(row + FS2, col + FS2 + 1)));
|
||||
s += (fc.y) * (v1[(col + FS2) / 2].x * (fc.x *
|
||||
(Fw(row + FS2, col + FS2 - 1) -
|
||||
Fw(row + FS2, col + FS2 + 0)) +
|
||||
Fw(row + FS2, col + FS2 + 0)) +
|
||||
v1[(col + FS2) / 2].y * (fc.x *
|
||||
(Fw(row + FS2, col + FS2 - 0) -
|
||||
Fw(row + FS2, col + FS2 + 1)) +
|
||||
Fw(row + FS2, col + FS2 + 1)));
|
||||
if (row > -FS2)
|
||||
{
|
||||
s += (1 - fc.y) * (v0[(col + FS2) / 2].x * (fc.x *
|
||||
(Fw(row + FS2 - 1, col + FS2 - 1) -
|
||||
Fw(row + FS2 - 1, col + FS2 + 0)) +
|
||||
Fw(row + FS2 - 1, col + FS2 + 0)) +
|
||||
v0[(col + FS2) / 2].y * (fc.x *
|
||||
(Fw(row + FS2 - 1, col + FS2 - 0) -
|
||||
Fw(row + FS2 - 1, col + FS2 + 1)) +
|
||||
Fw(row + FS2 - 1, col + FS2 + 1)));
|
||||
s += (fc.y) * (v1[(col + FS2) / 2].w * (fc.x *
|
||||
(Fw(row + FS2 - 1, col + FS2 - 1) -
|
||||
Fw(row + FS2 - 1, col + FS2 + 0)) +
|
||||
Fw(row + FS2 - 1, col + FS2 + 0)) +
|
||||
v1[(col + FS2) / 2].z * (fc.x *
|
||||
(Fw(row + FS2 - 1, col + FS2 - 0) -
|
||||
Fw(row + FS2 - 1, col + FS2 + 1)) +
|
||||
Fw(row + FS2 - 1, col + FS2 + 1)));
|
||||
}
|
||||
}
|
||||
|
||||
if (row != FS2)
|
||||
{
|
||||
v0[(col + FS2) / 2] = v1[(col + FS2) / 2].xy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// compute ratio using formulas from PCSS
|
||||
if (blockerCount > 0.0)
|
||||
{
|
||||
avgBlockerDepth /= blockerCount;
|
||||
fRatio = saturate(((tc.z - avgBlockerDepth) * SUN_WIDTH) / avgBlockerDepth);
|
||||
fRatio *= fRatio;
|
||||
}
|
||||
else
|
||||
{
|
||||
fRatio = 0.0;
|
||||
}
|
||||
|
||||
// sum up weights of dynamic filter matrix
|
||||
for (row = 0; row < FS; ++row)
|
||||
{
|
||||
for (col = 0; col < FS; ++col)
|
||||
{
|
||||
w += Fw(row, col, fRatio);
|
||||
}
|
||||
}
|
||||
|
||||
return dot(s, float4((1.0f - fRatio) * (1.0f - fRatio) * (1.0f - fRatio),
|
||||
3.0f * (1.0 - fRatio) * (1.0 - fRatio) * fRatio,
|
||||
3.0f * fRatio * fRatio * (1.0 - fRatio),
|
||||
fRatio * fRatio * fRatio)) /
|
||||
w;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SM_4_1
|
||||
|
||||
float dx10_1_hw_hq_7x7(float3 tc)
|
||||
{
|
||||
float s = 0.0f;
|
||||
float2 stc = (SMAP_size * tc.xy) + float2(0.5, 0.5);
|
||||
float2 tcs = floor(stc);
|
||||
float2 fc;
|
||||
int row;
|
||||
int col;
|
||||
|
||||
fc.xy = stc - tcs;
|
||||
tc.xy = tcs * (1.0 / SMAP_size);
|
||||
|
||||
// loop over the rows
|
||||
for (row = -GS2; row <= GS2; row += 2)
|
||||
{
|
||||
[unroll] for (col = -GS2; col <= GS2; col += 2)
|
||||
{
|
||||
float4 v = (tc.zzzz <= s_smap.Gather(smp_nofilter, tc.xy, int2(col, row))) ? (1.0).xxxx : (0.0).xxxx;
|
||||
|
||||
if (row == -GS2) // top row
|
||||
{
|
||||
if (col == -GS2) // left
|
||||
{
|
||||
s += dot(float4(1.0 - fc.x, 1.0, 1.0 - fc.y, (1.0 - fc.x) * (1.0 - fc.y)), v);
|
||||
}
|
||||
else if (col == GS2) // right
|
||||
{
|
||||
s += dot(float4(1.0f, fc.x, fc.x * (1.0 - fc.y), 1.0 - fc.y), v);
|
||||
}
|
||||
else // center
|
||||
{
|
||||
s += dot(float4(1.0, 1.0, 1.0 - fc.y, 1.0 - fc.y), v);
|
||||
}
|
||||
}
|
||||
else if (row == GS2) // bottom row
|
||||
{
|
||||
if (col == -GS2) // left
|
||||
{
|
||||
s += dot(float4((1.0 - fc.x) * fc.y, fc.y, 1.0, (1.0 - fc.x)), v);
|
||||
}
|
||||
else if (col == GS2) // right
|
||||
{
|
||||
s += dot(float4(fc.y, fc.x * fc.y, fc.x, 1.0), v);
|
||||
}
|
||||
else // center
|
||||
{
|
||||
s += dot(float4(fc.yy, 1.0, 1.0), v);
|
||||
}
|
||||
}
|
||||
else // center rows
|
||||
{
|
||||
if (col == -GS2) // left
|
||||
{
|
||||
s += dot(float4((1.0 - fc.x), 1.0, 1.0, (1.0 - fc.x)), v);
|
||||
}
|
||||
else if (col == GS2) // right
|
||||
{
|
||||
s += dot(float4(1.0, fc.x, fc.x, 1.0), v);
|
||||
}
|
||||
else // center
|
||||
{
|
||||
s += dot((1.0).xxxx, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s * (1.0 / 49.0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
float dx10_0_hw_hq_7x7(float4 tc)
|
||||
{
|
||||
tc.xyz /= tc.w;
|
||||
|
||||
float s = 0.0;
|
||||
float2 stc = (SMAP_size * tc.xy) + float2(0.5, 0.5);
|
||||
float2 tcs = floor(stc);
|
||||
float2 fc;
|
||||
|
||||
fc = stc - tcs;
|
||||
tc.xy = tc.xy - (fc * (1.0 / SMAP_size));
|
||||
|
||||
float2 pwAB = ((2.0).xx - fc);
|
||||
float2 tcAB = (1.0 / SMAP_size).xx / pwAB;
|
||||
float2 tcM = (0.5 / SMAP_size).xx;
|
||||
float2 pwGH = ((1.0).xx + fc);
|
||||
float2 tcGH = (1.0 / SMAP_size) * (fc / pwGH);
|
||||
|
||||
for (int row = -GS2; row <= GS2; row += 2)
|
||||
{
|
||||
for (int col = -GS2; col <= GS2; col += 2)
|
||||
{
|
||||
if (row == -GS2) // top row
|
||||
{
|
||||
if (col == -GS2) // left
|
||||
{
|
||||
s += (pwAB.x * pwAB.y) * s_smap.SampleCmpLevelZero(smp_smap, tc.xy + tcAB, tc.z, int2(col, row)).x;
|
||||
}
|
||||
else if (col == GS2) // right
|
||||
{
|
||||
s += (pwGH.x * pwAB.y) * s_smap.SampleCmpLevelZero(smp_smap, tc.xy + float2(tcGH.x, tcAB.y), tc.z, int2(col, row)).x;
|
||||
}
|
||||
else // center
|
||||
{
|
||||
s += (2.0 * pwAB.y) * s_smap.SampleCmpLevelZero(smp_smap, tc.xy + float2(tcM.x, tcAB.y), tc.z, int2(col, row)).x;
|
||||
}
|
||||
}
|
||||
else if (row == GS2) // bottom row
|
||||
{
|
||||
if (col == -GS2) // left
|
||||
{
|
||||
s += (pwAB.x * pwGH.y) * s_smap.SampleCmpLevelZero(smp_smap, tc.xy + float2(tcAB.x, tcGH.y), tc.z, int2(col, row)).x;
|
||||
}
|
||||
else if (col == GS2) // right
|
||||
{
|
||||
s += (pwGH.x * pwGH.y) * s_smap.SampleCmpLevelZero(smp_smap, tc.xy + tcGH, tc.z, int2(col, row)).x;
|
||||
}
|
||||
else // center
|
||||
{
|
||||
s += (2.0 * pwGH.y) * s_smap.SampleCmpLevelZero(smp_smap, tc.xy + float2(tcM.x, tcGH.y), tc.z, int2(col, row)).x;
|
||||
}
|
||||
}
|
||||
else // center rows
|
||||
{
|
||||
if (col == -GS2) // left
|
||||
{
|
||||
s += (pwAB.x * 2.0) * s_smap.SampleCmpLevelZero(smp_smap, tc.xy + float2(tcAB.x, tcM.y), tc.z, int2(col, row)).x;
|
||||
}
|
||||
else if (col == GS2) // right
|
||||
{
|
||||
s += (pwGH.x * 2.0) * s_smap.SampleCmpLevelZero(smp_smap, tc.xy + float2(tcGH.x, tcM.y), tc.z, int2(col, row)).x;
|
||||
}
|
||||
else // center
|
||||
{
|
||||
s += (2.0 * 2.0) * s_smap.SampleCmpLevelZero(smp_smap, tc.xy + tcM, tc.z, int2(col, row)).x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s / 49.0;
|
||||
}
|
||||
|
||||
float shadow_hw_hq(float4 tc)
|
||||
{
|
||||
#if SUN_QUALITY >= 4 // extreme quality
|
||||
return shadow_extreme_quality(tc.xyz / tc.w);
|
||||
#else // SUN_QUALITY<4
|
||||
#ifdef SM_4_1
|
||||
return dx10_1_hw_hq_7x7(tc.xyz / tc.w);
|
||||
#else // SM_4_1
|
||||
return dx10_0_hw_hq_7x7(tc);
|
||||
#endif // SM_4_1
|
||||
#endif // SUN_QUALITY==4
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// D24X8+PCF
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
float4 test(float4 tc, float2 offset)
|
||||
{
|
||||
tc.xyz /= tc.w;
|
||||
tc.xy += offset;
|
||||
return s_smap.SampleCmpLevelZero(smp_smap, tc.xy, tc.z).x;
|
||||
}
|
||||
|
||||
float shadowtest_sun(float4 tc, float4 tcJ) // jittered sampling
|
||||
{
|
||||
float4 r;
|
||||
|
||||
// const float scale = (2.0f/float(SMAP_size));
|
||||
const float scale = (0.7f / float(SMAP_size));
|
||||
|
||||
float2 tc_J = frac(tc.xy / tc.w * SMAP_size / 4.0f) * 0.5f;
|
||||
float4 J0 = jitter0.Sample(smp_jitter, tc_J) * scale;
|
||||
// float4 J1 = tex2D (jitter1,tc_J)*scale;
|
||||
|
||||
const float k = 0.5f / float(SMAP_size);
|
||||
r.x = test(tc, J0.xy + float2(-k, -k)).x;
|
||||
r.y = test(tc, J0.wz + float2(k, -k)).y;
|
||||
r.z = test(tc, -J0.xy + float2(-k, k)).z;
|
||||
r.w = test(tc, -J0.wz + float2(k, k)).x;
|
||||
|
||||
return dot(r, 1.0f / 4.0f);
|
||||
}
|
||||
|
||||
// jittered sampling
|
||||
float shadow_high(float4 tc)
|
||||
{
|
||||
const float scale = (0.5f / float(SMAP_size));
|
||||
|
||||
float2 tc_J = frac(tc.xy / tc.w * SMAP_size / 4.0f) * .5f;
|
||||
float4 J0 = jitter0.Sample(smp_jitter, tc_J) * scale;
|
||||
|
||||
const float k = 1.0f / float(SMAP_size);
|
||||
float4 r;
|
||||
r.x = test(tc, J0.xy + float2(-k, -k)).x;
|
||||
r.y = test(tc, J0.wz + float2(k, -k)).y;
|
||||
|
||||
r.z = test(tc, J0.xy + float2(-k, k)).z;
|
||||
r.w = test(tc, J0.wz + float2(k, k)).x;
|
||||
|
||||
const float k1 = 1.3f / float(SMAP_size);
|
||||
float4 r1;
|
||||
r1.x = test(tc, -J0.xy + float2(-k1, 0)).x;
|
||||
r1.y = test(tc, -J0.wz + float2(0, -k1)).y;
|
||||
|
||||
r1.z = test(tc, -2 * J0.xy + float2(k1, 0)).z;
|
||||
r1.w = test(tc, -2 * J0.wz + float2(0, k1)).x;
|
||||
|
||||
return (r.x + r.y + r.z + r.w + r1.x + r1.y + r1.z + r1.w) * 1.0f / 8.0f;
|
||||
}
|
||||
|
||||
float shadow(float4 tc)
|
||||
{
|
||||
#ifdef USE_ULTRA_SHADOWS
|
||||
return shadow_hw_hq(tc);
|
||||
#else
|
||||
#if SUN_QUALITY >= 2
|
||||
return shadow_hw(tc);
|
||||
#else
|
||||
return shadow_hw(tc);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
float shadow_volumetric(float4 tc)
|
||||
{
|
||||
return sample_hw_pcf(tc, float4(-1, -1, 0, 0));
|
||||
}
|
||||
|
||||
// testbed
|
||||
|
||||
float shadowtest(float4 tc, float4 tcJ) // jittered sampling
|
||||
{
|
||||
float4 r;
|
||||
|
||||
const float scale = (2.7f / float(SMAP_size));
|
||||
|
||||
tcJ.xy /= tcJ.w;
|
||||
float4 J0 = jitter0.Sample(smp_jitter, tcJ.xy) * scale;
|
||||
float4 J1 = jitter1.Sample(smp_jitter, tcJ.xy) * scale;
|
||||
|
||||
r.x = test(tc, J0.xy).x;
|
||||
r.y = test(tc, J0.wz).y;
|
||||
r.z = test(tc, J1.xy).z;
|
||||
r.w = test(tc, J1.wz).x;
|
||||
|
||||
return dot(r, 1.h / 4.h);
|
||||
}
|
||||
|
||||
float shadow_rain(float4 tc, float2 tcJ) // jittered sampling
|
||||
{
|
||||
float4 r;
|
||||
|
||||
const float scale = (4.0f / float(SMAP_size));
|
||||
// float4 J0 = jitter0.Sample( smp_jitter, tcJ )*scale;
|
||||
// float4 J1 = jitter1.Sample( smp_jitter, tcJ )*scale;
|
||||
float4 J0 = jitter0.Sample(smp_linear, tcJ) * scale;
|
||||
float4 J1 = jitter1.Sample(smp_linear, tcJ) * scale;
|
||||
|
||||
r.x = test(tc, J0.xy).x;
|
||||
r.y = test(tc, J0.wz).y;
|
||||
r.z = test(tc, J1.xy).z;
|
||||
r.w = test(tc, J1.wz).x;
|
||||
|
||||
return dot(r, 1.h / 4.h);
|
||||
}
|
||||
|
||||
#ifdef USE_SUNMASK
|
||||
|
||||
float3x4 m_sunmask;
|
||||
float sunmask(float4 P)
|
||||
{
|
||||
float2 tc = mul(m_sunmask, P).xy;
|
||||
return 0.25f + 0.75f * s_lmap.SampleLevel(smp_linear, tc, 0).w;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
float sunmask(float4 P)
|
||||
{
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue