1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
float2 g_WakeTexScale = {0.0028,0.0028};
float2 g_WakeTexOffset = {0.82,0.5};
SamplerComparisonState g_samplerShadow
{
Filter = COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
AddressU = Border;
AddressV = Border;
BorderColor = float4(1, 1, 1, 1);
ComparisonFunc = LESS;
};
float RND_1d(float2 x)
{
uint n = asuint(x.y * 6435.1392 + x.x * 45.97345);
n = (n<<13)^n;
n = n * (n*n*15731u + 789221u) + 1376312589u;
n = (n>>9u) | 0x3F800000;
return 2.0 - asfloat(n);
}
static const float2 g_SamplePositions[] = {
// Poisson disk with 16 points
float2(-0.3935238f, 0.7530643f),
float2(-0.3022015f, 0.297664f),
float2(0.09813362f, 0.192451f),
float2(-0.7593753f, 0.518795f),
float2(0.2293134f, 0.7607011f),
float2(0.6505286f, 0.6297367f),
float2(0.5322764f, 0.2350069f),
float2(0.8581018f, -0.01624052f),
float2(-0.6928226f, 0.07119545f),
float2(-0.3114384f, -0.3017288f),
float2(0.2837671f, -0.179743f),
float2(-0.3093514f, -0.749256f),
float2(-0.7386893f, -0.5215692f),
float2(0.3988827f, -0.617012f),
float2(0.8114883f, -0.458026f),
float2(0.08265103f, -0.8939569f)
};
float GetShadowValue(Texture2D shadowMap, float4x4 lightMatrix, float3 fragmentPos, uniform bool simpleShadows=false)
{
float4 clipPos = mul(float4(fragmentPos, 1.0f), lightMatrix);
clipPos.z *= 0.99999;
clipPos.xyz /= clipPos.w;
clipPos.x = clipPos.x * 0.5f + 0.5f;
clipPos.y = 0.5f - clipPos.y * 0.5f;
if ( clipPos.x < 0 || clipPos.x > 1 ||
clipPos.y < 0 || clipPos.y > 1 )
{
return 0;
}
if (simpleShadows)
{
return shadowMap.SampleCmpLevelZero(g_samplerShadow, clipPos.xy, clipPos.z);
}
float shadow = 0;
float totalWeight = 0;
for(int nSample = 0; nSample < 16; ++nSample)
{
float2 offset = g_SamplePositions[nSample];
float weight = 1.0;
offset *= (1.0f / kSpotlightShadowResolution) * 2.25;
float sample = shadowMap.SampleCmpLevelZero(g_samplerShadow, clipPos.xy + offset, clipPos.z);
shadow += sample * weight;
totalWeight += weight;
}
shadow /= totalWeight;
return shadow;
}
|