tracer fix
[dd2d.git] / data / shaders / srlight_trace.frag
blob965c31973430ac9bc3e1342115a47af3db71fc15
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 HUMANIOD_THETA
22 #define INTO_DEPTH  (6)
24 #define PI  (3.14159265)
26 //uniform sampler2D texOcc;
27 uniform vec2 lightTexSize;
29 uniform sampler2D texOccFull; // occluders map, full
30 uniform sampler2D texOccSmall; // occluders, small map
31 uniform vec2 lightPos; // light coords in occluders map
32 uniform vec2 mapPixSize; // size of occluders map
34 // alpha threshold for our occlusion map
35 #define THRESHOLD  (0.75)
38 #define TRACE_STEP  do { \
39   vec2 nextTraceCell = vec2(0, 0); \
40   float t = 1e10; \
41   float tempT = 1e10; \
42   if (ab.x > 0.0 && testX) { \
43     tempT = -(-r0.x+(currentTraceCell.x+1.0))/(-ab.x); \
44     if (tempT >= 0.0) { t = tempT; nextTraceCell = vec2(1.0, 0.0); } \
45   } \
46   if (ab.y > 0.0 && testY) { \
47     tempT = -(-r0.y+(currentTraceCell.y+1.0))/(-ab.y); \
48     if (tempT < t && tempT >= 0.0) { t = tempT; nextTraceCell = vec2(0.0, 1.0); } \
49   } \
50   if (ab.x < 0.0 && testX) { \
51     tempT = -(r0.x-(currentTraceCell.x-1.0))/(ab.x); \
52     if (tempT < t && tempT >= 0.0) { t = tempT; nextTraceCell = vec2(-1.0, 0.0); } \
53   } \
54   if (ab.y < 0.0 && testY) { \
55     tempT = -(r0.y-(currentTraceCell.y-1.0))/(ab.y); \
56     if (tempT < t && tempT >= 0.0) { t = tempT; nextTraceCell = vec2(0.0, -1.0); } \
57   } \
58   r0 += ab*t; \
59   currentTraceCell += nextTraceCell; \
60 } while (false)
63 void main (void) {
64   //float dmposx = gl_TexCoord[0].x;
65   //vec2 ltPos = lightPos/mapPixSize;
66   /*if (texture2D(texOccFull, ltPos).a > THRESHOLD) {
67     gl_FragColor = vec4(vec3(1.0), 1.0);
68   } else*/
69   {
70     vec2 ltPos;
71     float dmposx = gl_FragCoord.x/lightTexSize.x;
72     // theta: 90 and greater
73 #ifdef HUMANIOD_THETA
74     float theta = 360.0*dmposx;
75     theta += 90; // turn it
76     //theta = PI*theta/180.0; // to radians
77     theta = radians(theta);
78 #else
79     float theta = PI*1.5+(dmposx*2.0-1.0)*PI;
80 #endif
81     float nsint = -sin(theta);
82     float ncost = cos(theta);
84     vec2 a = lightPos;
85     vec2 b = a+normalize(vec2(nsint, ncost))*(lightTexSize.x/2);
87     vec2 ab = b-a;
88     float lengthAB = length(ab);
89     ab /= lengthAB;
90     vec2 r0 = a;
91     float lengthABSqr = lengthAB*lengthAB;
92     bool testX = abs(ab.x) > 1e-4;
93     bool testY = abs(ab.y) > 1e-4;
94     vec2 currentTraceCell = floor(lightPos);
96     float dst = 1.0;
98     while (dot(r0-a, r0-a) < lengthABSqr) {
99       float dataa = texture2D(texOccFull, currentTraceCell/mapPixSize).a;
100       if (dataa > THRESHOLD) {
101         vec2 lastHit = r0;
102 #ifdef INTO_DEPTH
103         // do some steps
104         for (int stp = INTO_DEPTH; stp > 0; --stp) {
105           TRACE_STEP;
106           dataa = texture2D(texOccFull, /*currentTraceCell*/r0/mapPixSize).a;
107           if (dataa <= THRESHOLD) break;
108           lastHit = r0;
109         }
110 #endif
111         dst = distance(lightPos, lastHit)/(lightTexSize.x/2.0);
112         break;
113       }
114       TRACE_STEP;
115     }
117     //dst /= lightTexSize.x;
118     //dst *= 2.0;
119     dst = max(min(dst, 1.0), 0.0);
120     gl_FragColor = vec4(vec3(dst), 1.0);
121   }