• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Because gpu_shader5 is actually where those
2// gather functions are declared to work on shadowmaps
3#extension GL_ARB_gpu_shader5 : enable
4
5#ifdef HARDWARE_SHADOWS
6    #define SHADOWMAP sampler2DShadow
7    #define SHADOWCOMPAREOFFSET(tex,coord,offset) textureProjOffset(tex, coord, offset)
8    #define SHADOWCOMPARE(tex,coord) textureProj(tex, coord)
9    #define SHADOWGATHER(tex,coord) textureGather(tex, coord.xy, coord.z)
10#else
11    #define SHADOWMAP sampler2D
12    #define SHADOWCOMPAREOFFSET(tex,coord,offset) step(coord.z, textureProjOffset(tex, coord, offset).r)
13    #define SHADOWCOMPARE(tex,coord) step(coord.z, textureProj(tex, coord).r)
14    #define SHADOWGATHER(tex,coord) step(coord.z, textureGather(tex, coord.xy))
15#endif
16
17
18#if FILTER_MODE == 0
19    #define GETSHADOW SHADOWCOMPARE
20    #define KERNEL 1
21#elif FILTER_MODE == 1
22    #ifdef HARDWARE_SHADOWS
23        #define GETSHADOW SHADOWCOMPARE
24    #else
25        #define GETSHADOW Shadow_DoBilinear_2x2
26    #endif
27    #define KERNEL 1
28#elif FILTER_MODE == 2
29    #define GETSHADOW Shadow_DoDither_2x2
30    #define KERNEL 1
31#elif FILTER_MODE == 3
32    #define GETSHADOW Shadow_DoPCF
33    #define KERNEL 4
34#elif FILTER_MODE == 4
35    #define GETSHADOW Shadow_DoPCF
36    #define KERNEL 8
37#endif
38
39out vec4 outFragColor;
40
41uniform SHADOWMAP m_ShadowMap0;
42uniform SHADOWMAP m_ShadowMap1;
43uniform SHADOWMAP m_ShadowMap2;
44uniform SHADOWMAP m_ShadowMap3;
45
46uniform vec4 m_Splits;
47uniform float m_ShadowIntensity;
48
49in vec4 projCoord0;
50in vec4 projCoord1;
51in vec4 projCoord2;
52in vec4 projCoord3;
53in float shadowPosition;
54
55float Shadow_BorderCheck(in vec2 coord){
56    // Fastest, "hack" method (uses 4-5 instructions)
57    vec4 t = vec4(coord.xy, 0.0, 1.0);
58    t = step(t.wwxy, t.xyzz);
59    return dot(t,t);
60}
61
62float Shadow_DoDither_2x2(in SHADOWMAP tex, in vec4 projCoord){
63    float border = Shadow_BorderCheck(projCoord.xy);
64    if (border > 0.0)
65        return 1.0;
66
67    ivec2 texSize = textureSize(tex, 0);
68    vec2 pixSize = 1.0 / vec2(texSize);
69
70    float shadow = 0.0;
71    ivec2 o = ivec2(mod(floor(gl_FragCoord.xy), 2.0));
72    shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy+pixSize*(vec2(-1.5, 1.5)+o), projCoord.zw));
73    shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy+pixSize*(vec2( 0.5, 1.5)+o), projCoord.zw));
74    shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy+pixSize*(vec2(-1.5, -0.5)+o), projCoord.zw));
75    shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy+pixSize*(vec2( 0.5, -0.5)+o), projCoord.zw));
76    shadow *= 0.25;
77    return shadow;
78}
79
80float Shadow_DoBilinear_2x2(in SHADOWMAP tex, in vec4 projCoord){
81    float border = Shadow_BorderCheck(projCoord.xy);
82    if (border > 0.0)
83        return 1.0;
84
85    ivec2 texSize = textureSize(tex, 0);
86    #ifdef GL_ARB_gpu_shader5
87        vec4 coord = vec4(projCoord.xyz / projCoord.www,0.0);
88        vec4 gather = SHADOWGATHER(tex, coord);
89    #else
90        vec4 gather = vec4(0.0);
91        gather.x = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(0, 0));
92        gather.y = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(1, 0));
93        gather.z = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(0, 1));
94        gather.w = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(1, 1));
95   #endif
96
97   vec2 f = fract( projCoord.xy * texSize );
98   vec2 mx = mix( gather.xz, gather.yw, f.x );
99   return mix( mx.x, mx.y, f.y );
100}
101
102float Shadow_DoPCF(in SHADOWMAP tex, in vec4 projCoord){
103    float pixSize = 1.0 / textureSize(tex,0).x;
104
105    float shadow = 0.0;
106    float border = Shadow_BorderCheck(projCoord.xy);
107    if (border > 0.0)
108        return 1.0;
109
110    float bound = KERNEL * 0.5 - 0.5;
111    bound *= PCFEDGE;
112    for (float y = -bound; y <= bound; y += PCFEDGE){
113        for (float x = -bound; x <= bound; x += PCFEDGE){
114            vec4 coord = vec4(projCoord.xy + vec2(x,y) * pixSize, projCoord.zw);
115            shadow += SHADOWCOMPARE(tex, coord);
116        }
117    }
118
119    shadow = shadow / (KERNEL * KERNEL);
120    return shadow;
121}
122
123void main(){
124    float shadow = 0.0;
125
126    if(shadowPosition < m_Splits.x){
127        shadow = GETSHADOW(m_ShadowMap0, projCoord0);
128    }else if( shadowPosition <  m_Splits.y){
129        shadow = GETSHADOW(m_ShadowMap1, projCoord1);
130    }else if( shadowPosition <  m_Splits.z){
131        shadow = GETSHADOW(m_ShadowMap2, projCoord2);
132    }else if( shadowPosition <  m_Splits.w){
133        shadow = GETSHADOW(m_ShadowMap3, projCoord3);
134    }
135
136    shadow = shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity);
137    outFragColor = vec4(shadow, shadow, shadow, 1.0);
138}
139
140