From 3f479e470f2650f73161f3988b23ba150783d161 Mon Sep 17 00:00:00 2001 From: Ketmar Dark Date: Sun, 17 Apr 2016 15:15:58 +0300 Subject: [PATCH] new tracer --- data/shaders/srlight_trace.frag | 98 +++++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 38 deletions(-) diff --git a/data/shaders/srlight_trace.frag b/data/shaders/srlight_trace.frag index cd4aab4..1a61dcf 100644 --- a/data/shaders/srlight_trace.frag +++ b/data/shaders/srlight_trace.frag @@ -19,7 +19,7 @@ #define HUMANIOD_THETA -#define INTO_DEPTH (4.0) +#define INTO_DEPTH (6) #define PI (3.14159265) @@ -35,6 +35,31 @@ uniform vec2 mapPixSize; // size of occluders map #define THRESHOLD (0.75) +#define TRACE_STEP do { \ + vec2 nextTraceCell = vec2(0, 0); \ + float t = 1e10; \ + float tempT = 1e10; \ + if (ab.x > 0.0 && testX) { \ + tempT = -(-r0.x+(currentTraceCell.x+1.0))/(-ab.x); \ + if (tempT >= 0.0) { t = tempT; nextTraceCell = vec2(1.0, 0.0); } \ + } \ + if (ab.y > 0.0 && testY) { \ + tempT = -(-r0.y+(currentTraceCell.y+1.0))/(-ab.y); \ + if (tempT < t && tempT >= 0.0) { t = tempT; nextTraceCell = vec2(0.0, 1.0); } \ + } \ + if (ab.x < 0.0 && testX) { \ + tempT = -(r0.x-(currentTraceCell.x-1.0))/(ab.x); \ + if (tempT < t && tempT >= 0.0) { t = tempT; nextTraceCell = vec2(-1.0, 0.0); } \ + } \ + if (ab.y < 0.0 && testY) { \ + tempT = -(r0.y-(currentTraceCell.y-1.0))/(ab.y); \ + if (tempT < t && tempT >= 0.0) { t = tempT; nextTraceCell = vec2(0.0, -1.0); } \ + } \ + r0 += ab*t; \ + currentTraceCell += nextTraceCell; \ +} while (false) + + void main (void) { //float dmposx = gl_TexCoord[0].x; //vec2 ltPos = lightPos/mapPixSize; @@ -55,46 +80,43 @@ void main (void) { #endif float nsint = -sin(theta); float ncost = cos(theta); - float dst = 0.0; - while (dst < lightTexSize.x/2.0) { - // sample the occlusion map - ltPos = lightPos+vec2(nsint*dst, ncost*dst); - vec2 ltsmPos = vec2(floor(ltPos.x/8), floor(ltPos.y/8)); - ltsmPos = ltsmPos*8+0.5; - if (texture2D(texOccSmall, ltsmPos/mapPixSize).a <= THRESHOLD) { - //dst = min(dst+8.0, lightTexSize.x/2.0); - dst += 3.0; - } else { - ltPos /= mapPixSize; - float dataa = texture2D(texOccFull, ltPos).a; - // if we've hit an opaque fragment (occluder), then get new distance - // if the new distance is below the current, then we'll use that for our ray - if (dataa > THRESHOLD) { - #ifdef INTO_DEPTH - // if we hit occluders, trace through it for some more steps, so blur will look better on hitpoints - float orgDst = dst; - for (float count = 0.0; count <= INTO_DEPTH; count += 1.0) { - dst += 1.0; - ltPos = (lightPos+vec2(nsint*dst, ncost*dst))/mapPixSize; - dataa = texture2D(texOccFull, ltPos).a; - if (dataa <= THRESHOLD) { - dst -= 1.0; - break; - } - } - #else - //dst = max(0.0, dst-ltsyStep); - //dst = max(0.0, dst-1.0); - #endif - break; // the current distance is how far from the top we've come + + vec2 a = lightPos; + vec2 b = a+normalize(vec2(nsint, ncost))*(lightTexSize.x/2); + + vec2 ab = b-a; + float lengthAB = length(ab); + ab /= lengthAB; + vec2 r0 = a; + float lengthABSqr = lengthAB*lengthAB; + bool testX = abs(ab.x) > 1e-4; + bool testY = abs(ab.y) > 1e-4; + vec2 currentTraceCell = floor(lightPos); + + float dst = 1.0; + + while (dot(r0-a, r0-a) < lengthABSqr) { + float dataa = texture2D(texOccFull, currentTraceCell/mapPixSize).a; + if (dataa > THRESHOLD) { + vec2 lastHit = r0; +#ifdef INTO_DEPTH + // do some steps + for (int stp = INTO_DEPTH; stp > 0; --stp) { + TRACE_STEP; + dataa = texture2D(texOccFull, currentTraceCell/mapPixSize).a; + if (dataa <= THRESHOLD) break; + lastHit = r0; } - dst += 1.0; +#endif + dst = distance(lightPos, lastHit)/(lightTexSize.x/2.0); + break; } + TRACE_STEP; } - //dst = distance(lightPos, lightPos+vec2(nsint*dst, ncost*dst)); - dst /= lightTexSize.x; - dst *= 2.0; - dst = min(dst, 1.0); + + //dst /= lightTexSize.x; + //dst *= 2.0; + dst = max(min(dst, 1.0), 0.0); gl_FragColor = vec4(vec3(dst), 1.0); } } -- 2.11.4.GIT