1// Compatibility #ifdefs needed for parameters
2#ifdef GL_ES
3#define COMPAT_PRECISION mediump
4#else
5#define COMPAT_PRECISION
6#endif
7
8// Parameter lines go here:
9#pragma parameter RETRO_PIXEL_SIZE "Retro Pixel Size" 0.84 0.0 1.0 0.01
10#ifdef PARAMETER_UNIFORM
11// All parameter floats need to have COMPAT_PRECISION in front of them
12uniform COMPAT_PRECISION float RETRO_PIXEL_SIZE;
13#else
14#define RETRO_PIXEL_SIZE 0.84
15#endif
16
17#if defined(VERTEX)
18
19#if __VERSION__ >= 130
20#define COMPAT_VARYING out
21#define COMPAT_ATTRIBUTE in
22#define COMPAT_TEXTURE texture
23#else
24#define COMPAT_VARYING varying
25#define COMPAT_ATTRIBUTE attribute
26#define COMPAT_TEXTURE texture2D
27#endif
28
29#ifdef GL_ES
30#define COMPAT_PRECISION mediump
31#else
32#define COMPAT_PRECISION
33#endif
34
35COMPAT_ATTRIBUTE vec4 VertexCoord;
36COMPAT_ATTRIBUTE vec4 COLOR;
37COMPAT_ATTRIBUTE vec4 TexCoord;
38COMPAT_VARYING vec4 COL0;
39COMPAT_VARYING vec4 TEX0;
40// out variables go here as COMPAT_VARYING whatever
41
42vec4 _oPosition1;
43uniform mat4 MVPMatrix;
44uniform COMPAT_PRECISION int FrameDirection;
45uniform COMPAT_PRECISION int FrameCount;
46uniform COMPAT_PRECISION vec2 OutputSize;
47uniform COMPAT_PRECISION vec2 TextureSize;
48uniform COMPAT_PRECISION vec2 InputSize;
49
50// compatibility #defines
51#define vTexCoord TEX0.xy
52#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
53#define OutSize vec4(OutputSize, 1.0 / OutputSize)
54
55void main()
56{
57    gl_Position = MVPMatrix * VertexCoord;
58    TEX0.xy = VertexCoord.xy;
59// Paste vertex contents here:
60}
61
62#elif defined(FRAGMENT)
63
64#if __VERSION__ >= 130
65#define COMPAT_VARYING in
66#define COMPAT_TEXTURE texture
67out vec4 FragColor;
68#else
69#define COMPAT_VARYING varying
70#define FragColor gl_FragColor
71#define COMPAT_TEXTURE texture2D
72#endif
73
74#ifdef GL_ES
75#ifdef GL_FRAGMENT_PRECISION_HIGH
76precision highp float;
77#else
78precision mediump float;
79#endif
80#define COMPAT_PRECISION mediump
81#else
82#define COMPAT_PRECISION
83#endif
84
85uniform COMPAT_PRECISION int FrameDirection;
86uniform COMPAT_PRECISION int FrameCount;
87uniform COMPAT_PRECISION vec2 OutputSize;
88uniform COMPAT_PRECISION vec2 TextureSize;
89uniform COMPAT_PRECISION vec2 InputSize;
90uniform sampler2D Texture;
91COMPAT_VARYING vec4 TEX0;
92// in variables go here as COMPAT_VARYING whatever
93
94// compatibility #defines
95#define Source Texture
96#define vTexCoord TEX0.xy
97
98#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
99#define OutSize vec4(OutputSize, 1.0 / OutputSize)
100
101// delete all 'params.' or 'registers.' or whatever in the fragment
102float iGlobalTime = float(FrameCount)*0.025;
103vec2 iResolution = OutputSize.xy;
104
105const float pi = 3.14159;
106
107mat3 xrot(float t)
108{
109    return mat3(1.0, 0.0, 0.0,
110                0.0, cos(t), -sin(t),
111                0.0, sin(t), cos(t));
112}
113
114mat3 yrot(float t)
115{
116    return mat3(cos(t), 0.0, -sin(t),
117                0.0, 1.0, 0.0,
118                sin(t), 0.0, cos(t));
119}
120
121mat3 zrot(float t)
122{
123    return mat3(cos(t), -sin(t), 0.0,
124                sin(t), cos(t), 0.0,
125                0.0, 0.0, 1.0);
126}
127
128float udBox( vec3 p, vec3 b )
129{
130  return length(max(abs(p)-b,0.0));
131}
132
133float sdBox( vec3 p, vec3 b )
134{
135  vec3 d = abs(p) - b;
136  return min(max(d.x,max(d.y,d.z)),0.0) +
137         length(max(d,0.0));
138}
139
140float sdTube(vec3 p, float a)
141{
142    return length(p.xy) - a;
143}
144
145float room(vec3 p)
146{
147	float fd = sdBox(p, vec3(8.0));
148    fd = min(fd, sdBox(p+vec3(0.0,6.0,0.0), vec3(2.0,2.0,100.0)));
149    fd = min(fd, sdBox(p+vec3(0.0,6.0,0.0), vec3(100.0,2.0,2.0)));
150    return fd;
151}
152
153bool alpha = false;
154
155vec2 map(vec3 p)
156{
157	float d = -room(p);
158    float m = 0.0;
159
160    float pe = sdBox(p+vec3(0.0,8.0,0.0), vec3(1.0, 2.0, 1.0));
161    if (pe < d) {
162        d = pe;
163        m = 1.0;
164    }
165
166    if (alpha) {
167        float c = sdBox(p+vec3(0.0,5.0,0.0), vec3(1.0));
168        if (c < d)
169        {
170            d = c;
171            m = 2.0;
172        }
173    } else {
174        float c = length(p+vec3(0.0,5.3,0.0)) - 0.7;
175        if (c < d)
176        {
177            d = c;
178            m = 3.0;
179        }
180    }
181
182    return vec2(d, m);
183}
184
185vec3 normal(vec3 p)
186{
187	vec3 o = vec3(0.01, 0.0, 0.0);
188    return normalize(vec3(map(p+o.xyy).x - map(p-o.xyy).x,
189                          map(p+o.yxy).x - map(p-o.yxy).x,
190                          map(p+o.yyx).x - map(p-o.yyx).x));
191}
192
193float trace(vec3 o, vec3 r)
194{
195 	float t = 0.0;
196    for (int i = 0; i < 32; ++i) {
197        vec3 p = o + r * t;
198        float d = map(p).x;
199        t += d;
200    }
201    return t;
202}
203
204float mapl(vec3 p)
205{
206    p *= yrot(pi*0.25);
207	float r = 0.01;
208    float o = 7.0;
209    vec3 q = fract(p) * 2.0 - 1.0;
210    float a = sdTube(vec3(q.z,q.y,q.x), r);
211    float b = sdTube(vec3(q.x,q.y,q.z), r);
212    return min(a,b);
213}
214
215float tracel(vec3 o, vec3 r)
216{
217 	float t = 0.0;
218    for (int i = 0; i < 16; ++i) {
219        vec3 p = o + r * t;
220        float d = mapl(p);
221        t += d * 0.8;
222    }
223    return t;
224}
225
226vec3 _texture(vec3 p)
227{
228	vec3 ta = texture(Texture, vec2(p.y,p.z)).xyz;
229    vec3 tb = texture(Texture, vec2(p.x,p.z)).xyz;
230    vec3 tc = texture(Texture, vec2(p.x,p.y)).xyz;
231    return (ta + tb + tc) / 3.0;
232}
233
234vec4 diffcol(vec3 w, vec3 r, vec3 sn, vec2 fd, float t)
235{
236    vec3 mdiff = vec3(0.0);
237    float gloss = 0.0;
238    float light = 1.0;
239    if (fd.y == 1.0) {
240        mdiff = vec3(1.0);
241        gloss = 1.0;
242    } else if (fd.y == 2.0) {
243        mdiff = vec3(1.0);
244    } else if (fd.y == 3.0) {
245        mdiff = vec3(1.0);
246        gloss = 1.0;
247    } else {
248        if (sn.y > 0.9) {
249    		mdiff = vec3(1.0) * vec3(0.2,0.5,0.2);
250            gloss = 0.1;
251        } else if (sn.y < -0.9) {
252            mdiff = vec3(5.0);
253            gloss = 1.0;
254            light = 0.0;
255        } else {
256            mdiff = _texture(w*0.1) * vec3(0.0, 1.0, 1.0);
257            gloss = 1.0;
258        }
259    }
260    float fog = 1.0 / (1.0 + t * t * 0.05);
261    mdiff = mix(mdiff, vec3(1.0), abs(w.y) / 8.0 * light);
262    return vec4(mdiff*fog, gloss);
263}
264
265vec3 laser(vec3 o, vec3 r)
266{
267    float t = tracel(o, r);
268    float k = 1.0 / (1.0 + t * t * 0.1);
269    return vec3(1.0, 0.0, 0.0) * k;
270}
271
272void mainImage( out vec4 fragColor, in vec2 fragCoord )
273{
274	vec2 uv = fragCoord.xy / iResolution.xy;
275    uv = uv * 2.0 - 1.0;
276    uv.x *= iResolution.x / iResolution.y;
277
278    mat3 xfm = xrot(sin(-iGlobalTime*0.25)*0.25) * yrot(iGlobalTime);
279
280    vec3 r = normalize(vec3(uv, 1.0));
281    r *= xrot(pi * 0.25) * xfm;
282
283    vec3 o = vec3(0.0, 0.0, -3.0);
284    o *= xfm;
285    o.y -= 3.0;
286
287    alpha = true;
288    float t = trace(o, r);
289    vec3 w = o + r * t;
290    vec2 fd = map(w);
291    vec3 sn = normal(w);
292
293	vec4 mdiff = diffcol(w, r, sn, fd, t);
294
295    if (fd.y == 2.0) {
296    	alpha = false;
297    	vec3 rr = refract(r, sn, 0.9);
298    	float art = trace(w, rr);
299        vec3 aw = w + rr * art;
300    	vec2 afd = map(aw);
301        vec3 asn = normal(aw);
302		mdiff = diffcol(aw, rr, asn, afd, t+art);
303        mdiff.xyz += laser(w, rr);
304        mdiff.w = 1.0;
305
306        if (afd.y == 3.0) {
307            alpha = false;
308            vec3 brf = reflect(rr, asn);
309            float brt = trace(aw + asn * 0.1, brf);
310            vec3 bw = aw + brf * brt;
311            vec2 bfd = map(bw);
312            vec3 bsn = normal(bw);
313            vec4 bdiff = diffcol(bw, brf, bsn, bfd, brt);
314            float prod = max(dot(rr, -asn), 0.0);
315            mdiff.xyz = bdiff.xyz * prod + laser(aw, t+art+brf);
316        }
317    }
318
319    alpha = true;
320    vec3 rf = reflect(r, sn);
321    float tr = trace(w + sn * 0.01, rf);
322    vec3 rw = w + rf * tr;
323    vec2 rfd = map(rw);
324    vec3 rsn = normal(rw);
325    vec4 rdiff = diffcol(rw, rf, rsn, rfd, t+tr);
326
327    float prod = max(dot(r, -sn), 0.0);
328
329	vec3 fdiff = mix(mdiff.xyz, rdiff.xyz, mdiff.w*(1.0-prod));
330
331    vec3 fc = fdiff + laser(o, r);
332
333	fragColor = vec4(sqrt(fc), 1.0);
334}
335
336 void main(void)
337{
338  //just some shit to wrap shadertoy's stuff
339  vec2 FragCoord = vTexCoord.xy*OutputSize.xy;
340  mainImage(FragColor,FragCoord);
341}
342#endif
343