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
105// Xafer - 2017-04-30
106// https://www.shadertoy.com/view/4dlyzl
107
108// Reflections, refractions, lights such
109
110#define NEAR 0.01
111#define FAR 12.0
112
113#define STEP_SIZE 0.1
114#define MAX_ITER 300
115#define MAX_CYCLES 2
116#define DELTA 0.01
117#define A_SPEED 0.3
118#define CAM_DIST 3.3
119
120#define RECAST_MAX 5
121
122#define GLOW_POWER 6.0
123#define GLOW_COLOR vec3(0.2,0.4,0.4)
124#define GRASS_SIZE vec2(0.005,0.4)
125
126#define SKY_COLOR vec3(0.1,0.3,0.4)
127
128
129//Structures
130
131struct Light
132{
133    vec3 pos;
134    vec3 color;
135    float radius;
136    float intensity;
137};
138
139struct lComp
140{
141	vec3 specular;
142    float specularIntensity;
143    vec3 diffuse;
144};
145
146struct Ray
147{
148    vec3 pos;
149    vec3 dir;
150    float dist;
151    float near;
152};
153
154struct Material
155{
156    vec3 color;
157    float specular;
158    float diffuse;//
159    float ambient;//Ambient light factor
160    float refl;//How reflective is a surface
161    float refr;//Refraction index
162    float opacity;//For refractions
163};
164
165
166//Signed Distance Functions
167
168float sdSphere(vec3 p)
169{
170    return length(p) - 1.0;
171}
172
173float sdPlane(vec3 p)
174{
175    return -p.y;
176}
177
178float sdBox( vec3 p)
179{
180  vec3 d = abs(p) - vec3(1.0);
181  return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
182}
183
184float opAdd(float d1, float d2)
185{
186    return min(d1,d2);
187}
188
189float opSub(float d1, float d2)
190{
191    return max(-d1,d2);
192}
193
194float opInter(float d1, float d2)
195{
196    return max(d1,d2);
197}
198
199
200//Combinations
201
202float walls(vec3 p)
203{
204    p.y -= 1.0;
205    p.y * 2.0;
206
207    vec3 p2 = p;
208    vec3 p3 = p;
209
210    float width = 0.1;
211    vec2 dist = vec2(5.0);
212
213    p2.xz = mod(p2.xz,dist)-(dist/2.0);
214    p2.x /= width;
215    p2.z /= 2.0;
216
217    p3.xz = mod(p3.xz,dist)-(dist/2.0);
218    p3.z /= width;
219    p3.x /= 2.0;
220
221    float env = opAdd(sdPlane(p),opAdd(sdBox(p2),sdBox(p3)));
222
223    env = opSub(max(-p.y - 0.3, p.y + 0.2),max(env,sdSphere(p/(CAM_DIST-0.4))));
224
225    env = opAdd(env,sdSphere(p/0.7 + vec3(0,0.5,0)));
226
227    return opSub(sdSphere(p),env);
228}
229
230float map(vec3 pos, float factor)
231{
232    return walls(pos);
233}
234
235float map(vec3 pos)
236{
237 	return map(pos,0.0);
238}
239
240//Environment propreties
241
242vec3 getNormal(vec3 p)
243{
244	vec2 delta = vec2 (DELTA, 0.0);
245	vec3 normal = normalize (vec3 (
246		map (p + delta.xyy) - map (p - delta.xyy),
247		map (p + delta.yxy) - map (p - delta.yxy),
248		map (p + delta.yyx) - map (p - delta.yyx)));
249
250	return normalize(normal);
251}
252
253
254
255Material getMaterial(vec3 pos)
256{
257    Material mat;
258    mat.color = vec3(sin(pos.y),cos(pos.x),sin(pos.z))/2.0 + 0.5;
259    mat.refl = 0.0;
260    mat.refr = 0.8;
261    mat.opacity = 0.7;
262
263    mat.color = mix(mat.color,getNormal(pos),0.2);
264
265    return mat;
266}
267
268//RayMarching
269
270Ray march(Ray ray, int iterations)
271{
272    float n = 1.0 / min(iResolution.x, iResolution.y);
273
274    for(int i = 0; i < iterations; i++)
275    {
276    	ray.near = map(ray.pos,sqrt(ray.dist)*n);
277
278        if(ray.near < DELTA || ray.dist > FAR)
279            break;
280
281        float n = ray.near * STEP_SIZE;
282        ray.pos += ray.dir * n;
283        ray.dist += n;
284    }
285
286    return ray;
287}
288
289lComp getLighting(Ray ray)
290{
291    lComp lightComposition;
292
293    //Looping through lights
294    Light light;
295    light.radius = 3.5;
296    light.intensity = 1.0;
297    light.pos = vec3(0,-1,0);
298    light.color = vec3(1.0,0.8,0.6);
299
300    float specular;
301    float diffuse;
302
303    vec3 rayPos = ray.pos;
304    vec3 dir = light.pos - ray.pos;
305    float lDist = length(dir);
306
307    dir = normalize(dir);
308
309    rayPos += DELTA*dir;
310
311    float near = 0.0;
312    float dist = 0.0;
313
314    float l;
315
316    for(int i =0 ; i < MAX_ITER;i++)
317    {
318        near = map(rayPos);
319        l = length(rayPos-light.pos);
320        if(near < DELTA || dist > lDist)
321            break;
322
323        float n = abs(near * 0.1);
324
325        rayPos += n*dir;
326        dist += n;
327    }
328
329    if(near < DELTA)
330        diffuse = 0.0;
331    else if(dist > lDist)
332    {
333        diffuse = max(0.0,1.0 - (lDist/light.radius));
334        specular = dot(reflect(ray.dir,getNormal(ray.pos)),dir)/2.0 + 0.5;
335        specular = -cos(specular*3.1416)/2.0 + 0.5;
336        specular = pow(specular,lDist*lDist);
337        //if(specular > 0.9);
338        //	specular /= 20.0;
339    }
340
341    vec3 normal = getNormal(ray.pos);
342
343    lightComposition.diffuse = mix(SKY_COLOR, light.color, diffuse);
344    lightComposition.specular = light.color;
345    lightComposition.specularIntensity = specular;
346
347    return lightComposition;
348}
349
350//Marching through refractions
351
352vec3 getRefraction(Ray ray)
353{
354    vec3 color;
355    float colorFactor;
356
357    float intensity = 1.0;
358   	Material mat = getMaterial(ray.pos);;
359
360    for(int i = 0; i < MAX_CYCLES; i++)
361    {
362        vec3 normal = getNormal(ray.pos);
363        ray.dir = refract(ray.dir, normal, mat.refr);
364
365        vec3 m = ray.dir*DELTA*2.0;
366
367        int inside = 0;
368
369        for(int j = 0; j < MAX_ITER && (ray.near < DELTA || inside == 1); j++)
370        {
371            ray.pos += m;
372            ray.dist += DELTA*2.0;
373            ray.near = map(ray.pos);
374        }
375
376        ray.dir = refract(ray.dir,normal,mat.refr);
377        ray = march(ray,MAX_ITER);
378
379        if(ray.near > DELTA || ray.dist > FAR)
380        {
381            color += SKY_COLOR*intensity;
382            colorFactor += intensity;
383            break;
384        }
385
386        lComp lightComposition = getLighting(ray);
387
388        mat = getMaterial(ray.pos);
389
390        vec3 col = mix(mat.color * lightComposition.diffuse,lightComposition.specular, lightComposition.specularIntensity);
391
392        color += mix(col,SKY_COLOR,ray.dist/FAR)*intensity;
393        colorFactor += intensity;
394
395        intensity *= 1.0 - mat.opacity;
396    }
397
398    return color/colorFactor;
399}
400
401//Marching through reflections
402
403vec3 getReflection(Ray ray)
404{
405    vec3 color;
406    float colorFactor;
407
408    float intensity = 1.0;
409
410    for(int i = 0; i < MAX_CYCLES; i++)
411    {
412        vec3 normal = getNormal(ray.pos);
413        ray.dir = reflect(ray.dir,normal);
414        ray.pos += ray.dir * DELTA;
415
416        ray = march(ray, MAX_ITER);
417
418        Material mat = getMaterial(ray.pos);
419
420        intensity *= mat.refl;
421
422        lComp lightComposition = getLighting(ray);
423
424        vec3 col = mix(mat.color * lightComposition.diffuse, lightComposition.specular, lightComposition.specularIntensity);
425
426        color += mix(col,SKY_COLOR,ray.dist/FAR)*intensity;
427        colorFactor += intensity;
428    }
429
430    return color/colorFactor;
431}
432
433//Getting the color at the specified point
434
435vec3 getColor(Ray ray)
436{
437
438    vec3 color;
439    vec3 normal = getNormal(ray.pos);
440
441    if(ray.dist > FAR)
442    {
443		color = SKY_COLOR;
444    }
445    else if(ray.near <= DELTA)
446    {
447        Material mat = getMaterial(ray.pos);
448
449        color = mat.color;
450
451        lComp lightComposition = getLighting(ray);
452       	color *= lightComposition.diffuse;
453
454        if(mat.refr > 0.0)
455            color = mix(getRefraction(ray),color,mat.opacity);
456
457    	if(mat.refl > 0.0)
458            color = mix(color,getReflection(ray),mat.refl);
459
460        color = mix(color, lightComposition.specular, lightComposition.specularIntensity);
461
462    	color = mix(color, SKY_COLOR , ray.dist/FAR);
463        color = mix(color, SKY_COLOR , dot(ray.dir,normal)/2.0 + 0.5);
464    }
465
466	return color;
467}
468
469vec3 castRay(vec3 origin, vec3 direction)
470{
471    //Generating ray
472    Ray ray;
473    ray.pos = origin;
474    ray.dir = direction;
475    ray.dist = 0.0;
476
477    //Move the ray to a surface up to far distance
478    ray = march(ray, MAX_ITER*2);
479
480    return getColor(ray);
481}
482
483//Initialisation
484
485void mainImage( out vec4 fragColor, in vec2 fragCoord )
486{
487
488    //Setting up screen-correct uv
489	vec2 uv = ( fragCoord.xy / iResolution.xy ) * 2.0 - vec2( 1 );
490    uv.x *= iResolution.x/iResolution.y;
491
492    //Setting up rotation
493    float sa = sin( iGlobalTime * A_SPEED );
494    float ca = cos( iGlobalTime * A_SPEED );
495
496    float cDist = CAM_DIST + sin(iGlobalTime * A_SPEED);
497
498    //Creating ray
499    vec3 or = vec3(sa*cDist,0.5,-ca*cDist);
500    vec3 di = -normalize(vec3(uv.x,uv.y,-1.0));
501
502    //Rotating orientation
503    mat3 r;
504    r[0] = vec3(ca,0,sa);
505    r[1] = vec3(0,1,0);
506    r[2] = vec3(-sa,0,ca);
507    di = r*di;
508
509    vec3 color = castRay(or,di);
510
511	fragColor = vec4(color,1);
512}
513
514 void main(void)
515{
516  //just some shit to wrap shadertoy's stuff
517  vec2 FragCoord = vTexCoord.xy*OutputSize.xy;
518  mainImage(FragColor,FragCoord);
519}
520#endif
521