1#version 150
2
3uniform float inverseShadowmapSize;
4uniform float fixedDepthBias;
5uniform float gradientClamp;
6uniform float gradientScaleBias;
7uniform float shadowFuzzyWidth;
8uniform vec4 lightColour;
9
10uniform sampler2D shadowMap;
11uniform sampler2D normalMap;
12
13in vec3 tangentLightDir;
14in vec4 oUv0;
15in vec4 oUv1;
16out vec4 fragColour;
17
18// Expand a range-compressed vector
19vec3 expand(vec3 v)
20{
21	return (v - 0.5) * 2.0;
22}
23
24void main()
25{
26	// get the new normal and diffuse values
27	vec3 normal = normalize(expand(texture(normalMap, oUv1.xy).xyz));
28
29	vec4 vertexColour = clamp(dot(normal, tangentLightDir),0.0,1.0) * lightColour;
30
31	vec4 shadowUV = oUv0;
32	// point on shadowmap
33#if LINEAR_RANGE
34	shadowUV.xy = shadowUV.xy / shadowUV.w;
35#else
36	shadowUV = shadowUV / shadowUV.w;
37#endif
38	float centerdepth = texture(shadowMap, shadowUV.xy).x;
39
40    // gradient calculation
41  	float pixeloffset = inverseShadowmapSize;
42    vec4 depths = vec4(
43    	texture(shadowMap, shadowUV.xy + vec2(-pixeloffset, 0)).x,
44    	texture(shadowMap, shadowUV.xy + vec2(+pixeloffset, 0)).x,
45    	texture(shadowMap, shadowUV.xy + vec2(0, -pixeloffset)).x,
46    	texture(shadowMap, shadowUV.xy + vec2(0, +pixeloffset)).x);
47
48	vec2 differences = abs( depths.yw - depths.xz );
49	float gradient = min(gradientClamp, max(differences.x, differences.y));
50	float gradientFactor = gradient * gradientScaleBias;
51
52	// visibility function
53	float depthAdjust = gradientFactor + (fixedDepthBias * centerdepth);
54	float finalCenterDepth = centerdepth + depthAdjust;
55
56	// shadowUV.z contains lightspace position of current object
57
58#if FUZZY_TEST
59	// fuzzy test - introduces some ghosting in result and doesn't appear to be needed?
60	//float visibility = saturate(1 + delta_z / (gradient * shadowFuzzyWidth));
61	float visibility = saturate(1 + (finalCenterDepth - shadowUV.z) * shadowFuzzyWidth * shadowUV.w);
62
63	fragColour = vertexColour * visibility;
64#else
65	// hard test
66#if PCF
67	// use depths from prev, calculate diff
68	depths += depthAdjust;
69	float final = (finalCenterDepth > shadowUV.z) ? 1.0 : 0.0;
70	final += (depths.x > shadowUV.z) ? 1.0 : 0.0;
71	final += (depths.y > shadowUV.z) ? 1.0 : 0.0;
72	final += (depths.z > shadowUV.z) ? 1.0 : 0.0;
73	final += (depths.w > shadowUV.z) ? 1.0 : 0.0;
74
75	final *= 0.2;
76
77	fragColour = vec4(vertexColour.xyz * final, 1);
78#else
79	fragColour = (finalCenterDepth > shadowUV.z) ? vertexColour : vec4(0,0,0,1);
80#endif
81#endif
82}
83