1#ifdef NO_SHADOW2DPROJ
2#define SHADOWMAP sampler2D
3#define SHADOWTEX texture2D
4#define SHADCOORD(coord) coord.xy
5#else
6#define SHADOWMAP sampler2DShadow
7#define SHADOWTEX shadow2D
8#define SHADCOORD(coord) vec3(coord.xy,0.0)
9#endif
10
11//float shadowDepth = texture2DProj(tex, projCoord);
12
13const float texSize = 1024.0;
14const float pixSize = 1.0 / texSize;
15const vec2 pixSize2 = vec2(pixSize);
16
17float Shadow_DoShadowCompareOffset(in SHADOWMAP tex, vec4 projCoord, vec2 offset){
18     return step(projCoord.z, SHADOWTEX(tex, SHADCOORD(projCoord.xy + offset * pixSize2)).r);
19}
20
21float Shadow_DoShadowCompare(in SHADOWMAP tex, vec4 projCoord){
22    return step(projCoord.z, SHADOWTEX(tex, SHADCOORD(projCoord.xy)).r);
23}
24
25float Shadow_BorderCheck(in vec2 coord){
26    // Very slow method (uses 24 instructions)
27    //if (coord.x >= 1.0)
28    //    return 1.0;
29    //else if (coord.x <= 0.0)
30    //    return 1.0;
31    //else if (coord.y >= 1.0)
32    //    return 1.0;
33    //else if (coord.y <= 0.0)
34    //    return 1.0;
35    //else
36    //    return 0.0;
37
38    // Fastest, "hack" method (uses 4-5 instructions)
39    vec4 t = vec4(coord.xy, 0.0, 1.0);
40    t = step(t.wwxy, t.xyzz);
41    return dot(t,t);
42}
43
44float Shadow_DoDither_2x2(in SHADOWMAP tex, in vec4 projCoord){
45    float shadow = 0.0;
46    vec2 o = mod(floor(gl_FragCoord.xy), 2.0);
47    shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2(-1.5, 1.5) + o);
48    shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2( 0.5, 1.5) + o);
49    shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2(-1.5, -0.5) + o);
50    shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2( 0.5, -0.5) + o);
51    shadow *= 0.25 ;
52    return shadow;
53}
54
55float Shadow_DoBilinear(in SHADOWMAP tex, in vec4 projCoord){
56    const vec2 size  = vec2(256.0);
57    const vec2 pixel = vec2(1.0) / vec2(256.0);
58
59    vec2 tc = projCoord.xy * size;
60    vec2 bl = fract(tc);
61    vec2 dn = floor(tc) * pixel;
62    vec2 up = dn + pixel;
63   
64    vec4 coord = vec4(dn.xy, projCoord.zw);
65    float s_00 = Shadow_DoShadowCompare(tex, coord);
66    s_00 = clamp(s_00, 0.0, 1.0);
67
68    coord = vec4(up.x, dn.y, projCoord.zw);
69    float s_10 = Shadow_DoShadowCompare(tex, coord);
70    s_10 = clamp(s_10, 0.0, 1.0);
71
72    coord = vec4(dn.x, up.y, projCoord.zw);
73    float s_01 = Shadow_DoShadowCompare(tex, coord);
74    s_01 = clamp(s_01, 0.0, 1.0);
75
76    coord = vec4(up.xy, projCoord.zw);
77    float s_11 = Shadow_DoShadowCompare(tex, coord);
78    s_11 = clamp(s_11, 0.0, 1.0);
79
80    float xb0   = mix(s_00, s_10, clamp(bl.x, 0.0, 1.0));
81    float xb1   = mix(s_01, s_11, clamp(bl.x, 0.0, 1.0));
82    float yb    = mix(xb0, xb1,   clamp(bl.y, 0.0, 1.0));
83    return yb;
84}
85
86float Shadow_DoPCF_2x2(in SHADOWMAP tex, in vec4 projCoord){
87
88    float shadow = 0.0;
89    float x,y;
90    for (y = -1.5 ; y <=1.5 ; y+=1.0)
91            for (x = -1.5 ; x <=1.5 ; x+=1.0)
92                    shadow += clamp(Shadow_DoShadowCompareOffset(tex,projCoord,vec2(x,y)) +
93                                    Shadow_BorderCheck(projCoord.xy),
94                                    0.0, 1.0);
95
96    shadow /= 16.0 ;
97    return shadow;
98}
99
100
101float Shadow_GetShadow(in SHADOWMAP tex, in vec4 projCoord){
102    return clamp(Shadow_DoDither_2x2(tex, projCoord) + Shadow_BorderCheck(projCoord.xy), 0.0, 1.0);
103}
104
105
106