really compiles! ;-)
[dd2d.git] / data / shaders / srlight_blur.frag
blob70fd75ddc1716a4943f2975ca5aebbcc8ef569ee
1 /* DooM2D: Midnight on the Firing Line
2  * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3  * Understanding is not required. Only obedience.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 #version 130
20 //#define TWO_TEXTURES
22 // alpha threshold for our occlusion map
23 #define THRESHOLD  (0.75)
25 #define PI 3.1415926
27 uniform sampler2D texDist; // 1D distance
28 uniform sampler2D texBg; // background
29 uniform sampler2D texOccFull; // occluders
30 //uniform sampler2D texOccSmall; // occluders, small map
31 uniform vec2 lightTexSize; // x: size of distmap; y: size of this texture
32 uniform vec2 mapPixSize;
33 uniform vec4 lightColor;
34 uniform vec2 lightPos; // lefttop
35 #define SHADOW_DO_BLUR
37 #define SOFT_SHADOWS  (1.0f)
40 // sample from the 1D distance map
41 #define sample(cc_)  step(r, texture2D(texDist, vec2(tc.x+(cc_)*blur, /*tc.y*/0.0)).r)
43 //gl_FragCoord.x: [0..lightTexSize.x)
44 //gl_FragCoord.y: somehow it is constant; wtf?!
46 void main (void) {
47   vec2 vTexCoord0 = gl_TexCoord[0].xy;
48   // don't even ask me!
49   vec2 tctxy = vec2(lightPos.x+gl_FragCoord.x, lightPos.y+gl_TexCoord[0].y*lightTexSize.x);
50   ivec2 iocxy = ivec2(int(tctxy.x), int(tctxy.y));
51   ivec2 ibtxy = ivec2(iocxy.x, int(mapPixSize.y-tctxy.y));
52   vec4 color;
54   if (texelFetch(texOccFull, iocxy, 0).a > THRESHOLD) {
55     // occluder hit, this will take care of lighted walls (we'll fix wall in next pass)
56     color = vec4(0.0, 0.0, 0.0, 0.0);
57     #ifdef TWO_TEXTURES
58     gl_FragData[0] = color;
59     gl_FragData[1] = color;
60     #else
61     gl_FragColor = color;
62     #endif
63   } else {
64     float ltsxi = 1.0/lightTexSize.x;
66     // rectangular to polar
67     vec2 norm = vTexCoord0.st*2.0-1.0;
68     float theta = atan(norm.y, norm.x);
69     float r = length(norm);
70     float coord = (theta+PI)/(2.0*PI);
72     // the texDist coord to sample our 1D lookup texture
73     // always 0.0 on y axis
74     vec2 tc = vec2(coord, 0.0);
76     // the center texDist coord, which gives us hard shadows
77     float center = step(r, texture2D(texDist, tc.xy).r); //sample(vec2(tc.x, tc.y), r);
79     // now we use a simple gaussian blur
80     #ifdef SHADOW_DO_BLUR
81       // we multiply the blur amount by our distance from center
82       // this leads to more blurriness as the shadow "fades away"
83       float blur = ltsxi*smoothstep(0.0, 1.0, r);
85       float sum  = sample(-4.0)*0.05;
86             sum += sample(-3.0)*0.09;
87             sum += sample(-2.0)*0.12;
88             sum += sample(-1.0)*0.15;
89             sum += center*0.16;
90             sum += sample( 1.0)*0.15;
91             sum += sample( 2.0)*0.12;
92             sum += sample( 3.0)*0.09;
93             sum += sample( 4.0)*0.05;
94       // sum of 1.0 -> in light, 0.0 -> in shadow
95       float lit = mix(center, sum, SOFT_SHADOWS);
96     #else
97       float lit = center;
98     #endif
100     // multiply the summed amount by our distance, which gives us a radial falloff
101     lit = lit*smoothstep(1.0, 0.0, r);
103     if (lit == 0.0) {
104       color = vec4(0.0, 0.0, 0.0, 0.0);
105       #ifdef TWO_TEXTURES
106       gl_FragData[0] = color;
107       gl_FragData[1] = color;
108       #else
109       gl_FragColor = color;
110       #endif
111     } else {
112       // has some light here
113       vec4 bcolor = texelFetch(texBg, ibtxy, 0);
114       if (lightColor.r+lightColor.g+lightColor.b == 0.0) {
115         color = bcolor*vec4(vec3(lightColor.a), lit);
116       } else {
117         color = lightColor*lit;
118         color += bcolor*lit;
119         color.a = lit/2.0;
120       }
121       #ifdef TWO_TEXTURES
122       gl_FragData[0] = color;
123       gl_FragData[1] = vec4(1.0, 1.0, 1.0, lit);
124       #else
125       gl_FragColor = color;
126       #endif
127     }
128   }