attempt to reduce tile edge effects
[maximus:fractal-channel-hopping.git] / src / fch.frag
1 /*
2   fractal-channel-hopping -- infinite fractal television zoom
3   Copyright (C) 2011 Claude Heiland-Allen
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
19 #version 130
20
21 uniform sampler2D images; // 4x4 tile sheet
22 uniform vec3 matches[8]; // hardcoded maximum channels
23 uniform int focus;
24 uniform float blend0;
25 uniform float blend1;
26 uniform float blend2;
27
28 vec3 get(int n, vec2 p, float bias, bool wrap) {
29   int j = int(floor(float(n) / 4.0));
30   int i = n - 4 * j;
31   vec2 p1 = p;
32   if (wrap) {
33     float k = pow(2.0, 8.0 - bias);
34     p1 = floor(p1 * k) / k;
35   }
36   p1 *= 254.0 / 256.0;
37   p1 += 1.0 / 256.0;
38   vec2 q = (vec2(float(i), float(j)) + p1) / 4.0;
39   return textureLod(images, q, bias).rgb;
40 }
41
42 int match(int def, vec3 c) {
43   float d = 1024.0;
44   int m = def;
45   for (int i = 0; i < 8; ++i) {
46     if (length(matches[i]) > 0.0) {
47       float d2 = length(c - matches[i]);
48       if (d2 < d) {
49         d = d2;
50         m = i;
51       }
52     }
53   }
54   return m;
55 }
56
57 void main(void) {
58   int  f0 = focus;
59   vec2 p0 = gl_TexCoord[0].xy;
60   vec3 c0 = get(f0, p0, 0.0, false);
61   vec3 ca = get(f0, p0, 4.0, true);
62
63   int  f1 = match(f0, ca);
64   vec2 p1 = 16.0 * p0; p1 -= floor(p1);
65   vec3 c1 = get(f1, p1, 0.0, false);
66   vec3 cb = get(f1, p1, 4.0, true);
67
68   int  f2 = match(f1, cb);
69   vec2 p2 = 16.0 * p1; p2 -= floor(p2);
70   vec3 c2 = get(f2, p2, 0.0, false);
71
72   float channel[8];
73   channel[0] = 0.0;
74   channel[1] = 0.0;
75   channel[2] = 0.0;
76   channel[3] = 0.0;
77   channel[4] = 0.0;
78   channel[5] = 0.0;
79   channel[6] = 0.0;
80   channel[7] = 0.0;
81   channel[f0] += blend0;
82   channel[f1] += blend1;
83   channel[f2] += blend2;
84   gl_FragData[0] = vec4(blend0 * c0 + blend1 * c1 + blend2 * c2, 1.0);
85   gl_FragData[1] = vec4(channel[0], channel[1], channel[2], channel[3]);
86   gl_FragData[2] = vec4(channel[4], channel[5], channel[6], channel[7]);
87 }