File: shadows.sdr

package info (click to toggle)
freespace2 24.2.0%2Brepack-1
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 43,716 kB
  • sloc: cpp: 595,001; ansic: 21,741; python: 1,174; sh: 457; makefile: 248; xml: 181
file content (105 lines) | stat: -rw-r--r-- 5,312 bytes parent folder | download | duplicates (2)
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

const float VARIANCE_SHADOW_SCALE = 1000000.0;
const float VARIANCE_SHADOW_SCALE_INV = 1.0/VARIANCE_SHADOW_SCALE;

vec2 sampleShadowMap(sampler2DArray shadow_map, vec2 uv, vec2 offset_uv, int cascade, float shadowMapSizeInv)
{
	return texture(shadow_map, vec3(uv + offset_uv * shadowMapSizeInv, float(cascade))).xy;
}

float computeShadowFactor(float shadowDepth, vec2 moments, float bias)
{
	float shadow = 1.0;
	if((moments.x - bias) > shadowDepth)
	{
		// variance shadow mapping using Chebychev's Formula
		float variance = moments.y * VARIANCE_SHADOW_SCALE - moments.x * moments.x;
		float mD = moments.x - bias - shadowDepth;
		shadow = variance / (variance + mD * mD);
		shadow = clamp(shadow, 0.0, 1.0);
	}
	return shadow;
}

float sampleNoPCF(sampler2DArray shadow_map, float shadowDepth, int cascade, vec4 shadowUV[4])
{
	return computeShadowFactor(shadowDepth, sampleShadowMap(shadow_map, shadowUV[cascade].xy, vec2(0.0, 0.0), cascade, 1.0/1024.0), 0.05);
}

float samplePoissonPCF(sampler2DArray shadow_map, float shadowDepth, int cascade, vec4 shadowUV[4])
{
	if(cascade > 3 || cascade < 0) return 1.0;
	vec2 poissonDisc[16];
	poissonDisc[0] = vec2(-0.76275, -0.3432573);
	poissonDisc[1] = vec2(-0.5226235, -0.8277544);
	poissonDisc[2] = vec2(-0.3780261, 0.01528688);
	poissonDisc[3] = vec2(-0.7742821, 0.4245702);
	poissonDisc[4] = vec2(0.04196143, -0.02622231);
	poissonDisc[5] = vec2(-0.2974772, -0.4722782);
	poissonDisc[6] = vec2(-0.516093, 0.71495);
	poissonDisc[7] = vec2(-0.3257416, 0.3910343);
	poissonDisc[8] = vec2(0.2705966, 0.6670476);
	poissonDisc[9] = vec2(0.4918377, 0.1853267);
	poissonDisc[10] = vec2(0.4428544, -0.6251478);
	poissonDisc[11] = vec2(-0.09204347, 0.9267113);
	poissonDisc[12] = vec2(0.391505, -0.2558275);
	poissonDisc[13] = vec2(0.05605913, -0.7570801);
	poissonDisc[14] = vec2(0.81772, -0.02475523);
	poissonDisc[15] = vec2(0.6890262, 0.5191521);
	float maxUVOffset[4];
	maxUVOffset[0] = 1.0/300.0;
	maxUVOffset[1] = 1.0/250.0;
	maxUVOffset[2] = 1.0/200.0;
	maxUVOffset[3] = 1.0/200.0;
	vec2 sum = sampleShadowMap(shadow_map, shadowUV[cascade].xy, poissonDisc[0], cascade, maxUVOffset[cascade])*(1.0/16.0);
	sum += sampleShadowMap(shadow_map, shadowUV[cascade].xy, poissonDisc[1], cascade, maxUVOffset[cascade])*(1.0/16.0);
	sum += sampleShadowMap(shadow_map, shadowUV[cascade].xy, poissonDisc[2], cascade, maxUVOffset[cascade])*(1.0/16.0);
	sum += sampleShadowMap(shadow_map, shadowUV[cascade].xy, poissonDisc[3], cascade, maxUVOffset[cascade])*(1.0/16.0);
	sum += sampleShadowMap(shadow_map, shadowUV[cascade].xy, poissonDisc[4], cascade, maxUVOffset[cascade])*(1.0/16.0);
	sum += sampleShadowMap(shadow_map, shadowUV[cascade].xy, poissonDisc[5], cascade, maxUVOffset[cascade])*(1.0/16.0);
	sum += sampleShadowMap(shadow_map, shadowUV[cascade].xy, poissonDisc[6], cascade, maxUVOffset[cascade])*(1.0/16.0);
	sum += sampleShadowMap(shadow_map, shadowUV[cascade].xy, poissonDisc[7], cascade, maxUVOffset[cascade])*(1.0/16.0);
	sum += sampleShadowMap(shadow_map, shadowUV[cascade].xy, poissonDisc[8], cascade, maxUVOffset[cascade])*(1.0/16.0);
	sum += sampleShadowMap(shadow_map, shadowUV[cascade].xy, poissonDisc[9], cascade, maxUVOffset[cascade])*(1.0/16.0);
	sum += sampleShadowMap(shadow_map, shadowUV[cascade].xy, poissonDisc[10], cascade, maxUVOffset[cascade])*(1.0/16.0);
	sum += sampleShadowMap(shadow_map, shadowUV[cascade].xy, poissonDisc[11], cascade, maxUVOffset[cascade])*(1.0/16.0);
	sum += sampleShadowMap(shadow_map, shadowUV[cascade].xy, poissonDisc[12], cascade, maxUVOffset[cascade])*(1.0/16.0);
	sum += sampleShadowMap(shadow_map, shadowUV[cascade].xy, poissonDisc[13], cascade, maxUVOffset[cascade])*(1.0/16.0);
	sum += sampleShadowMap(shadow_map, shadowUV[cascade].xy, poissonDisc[14], cascade, maxUVOffset[cascade])*(1.0/16.0);
	sum += sampleShadowMap(shadow_map, shadowUV[cascade].xy, poissonDisc[15], cascade, maxUVOffset[cascade])*(1.0/16.0);
	return computeShadowFactor(shadowDepth, sum, 0.1);
}

float getShadowValue(sampler2DArray shadow_map, float depth, float shadowDepth, vec4 shadowUV[4], float fardist,
					 float middist, float neardist, float veryneardist)
{
	// Valathil's Shadows
	int cascade = 4;
	cascade -= int(step(depth, fardist));
	cascade -= int(step(depth, middist));
	cascade -= int(step(depth, neardist));
	cascade -= int(step(depth, veryneardist));
	float cascade_start_dist[5];
	cascade_start_dist[0] = 0.0;
	cascade_start_dist[1] = veryneardist;
	cascade_start_dist[2] = neardist;
	cascade_start_dist[3] = middist;
	cascade_start_dist[4] = fardist;
	if(cascade > 3 || cascade < 0) return 1.0;
	float dist_threshold = (cascade_start_dist[cascade+1] - cascade_start_dist[cascade])*0.2;
	if(cascade_start_dist[cascade+1] - dist_threshold > depth)
		return samplePoissonPCF(shadow_map, shadowDepth, cascade, shadowUV);
	return mix(samplePoissonPCF(shadow_map, shadowDepth, cascade, shadowUV), samplePoissonPCF(shadow_map, shadowDepth, cascade+1, shadowUV),
			smoothstep(cascade_start_dist[cascade+1] - dist_threshold, cascade_start_dist[cascade+1], depth));
}

vec4 transformToShadowMap(mat4 shadow_proj_matrix, int i, vec4 pos)
{
	vec4 shadow_proj;
	shadow_proj = shadow_proj_matrix * pos;
	shadow_proj += 1.0;
	shadow_proj *= 0.5;
	shadow_proj.w = shadow_proj.z;
	shadow_proj.z = float(i);
	return shadow_proj;
}