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// Frozen wasteland
106// https://www.shadertoy.com/view/Xls3D2
107// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
108// By Dave Hoskins
109
110#define ITR 90
111#define FAR 110.
112#define time iGlobalTime
113#define MOD3 vec3(.16532,.17369,.15787)
114#define SUN_COLOUR  vec3(1., .95, .85)
115
116#define TRIANGLE_NOISE	// .. This
117//#define FOUR_D_NOISE	// ...Or this
118//#define TEXTURE_NOISE		// .. Or this (faster, but not as sharp edged)
119//#define VALUE_NOISE 		// .. or more normal noise.
120
121
122float height(in vec2 p)
123{
124    float h = sin(p.x*.1+p.y*.2)+sin(p.y*.1-p.x*.2)*.5;
125    h += sin(p.x*.04+p.y*.01+3.0)*4.;
126    h -= sin(h*10.0)*.1;
127    return h;
128}
129
130float camHeight(in vec2 p)
131{
132    float h = sin(p.x*.1+p.y*.2)+sin(p.y*.1-p.x*.2)*.5;
133    h += sin(p.x*.04+p.y*.01+3.0)*4.;
134    return h;
135}
136
137float smin( float a, float b)
138{
139	const float k = 2.7;
140	float h = clamp( 0.5 + 0.5*(b-a)/k, 0.0, 1.0 );
141	return mix( b, a, h ) - k*h*(1.0-h);
142}
143
144#define MOD2 vec2(.16632,.17369)
145#define MOD3 vec3(.16532,.17369,.15787)
146float tri(in float x){return abs(fract(x)-.5);}
147
148float hash12(vec2 p)
149{
150	p  = fract(p * MOD2);
151    p += dot(p.xy, p.yx+19.19);
152    return fract(p.x * p.y);
153}
154float vine(vec3 p, in float c, in float h)
155{
156    p.y += sin(p.z*.5625+1.3)*3.5-.5;
157    p.x += cos(p.z*2.)*1.;
158    vec2 q = vec2(mod(p.x, c)-c/2., p.y);
159    return length(q) - h*1.4 -sin(p.z*3.+sin(p.x*7.)*0.5)*0.1;
160}
161
162//========================================================================
163// ################ DIFFERENT NOISE FUNCTIONS ################
164#ifdef TRIANGLE_NOISE
165vec3 tri3(in vec3 p){return vec3( tri(p.z+tri(p.y)), tri(p.z+tri(p.x)), tri(p.y+tri(p.x)));}
166float Noise3d(in vec3 p)
167{
168    float z=1.4;
169	float rz = 0.;
170    vec3 bp = p;
171	for (float i=0.; i<= 2.; i++ )
172	{
173        vec3 dg = tri3(bp);
174        p += (dg);
175
176        bp *= 2.;
177		z *= 1.5;
178		p *= 1.3;
179
180        rz+= (tri(p.z+tri(p.x+tri(p.y))))/z;
181        bp += 0.14;
182	}
183	return rz;
184}
185#endif
186
187//--------------------------------------------------------------------------------
188#ifdef FOUR_D_NOISE
189
190vec4 quad(in vec4 p){return abs(fract(p.yzwx+p.wzxy)-.5);}
191
192float Noise3d(in vec3 q)
193{
194    float z=1.4;
195    vec4 p = vec4(q, iGlobalTime*.1);
196	float rz = 0.;
197    vec4 bp = p;
198	for (float i=0.; i<= 2.; i++ )
199	{
200        vec4 dg = quad(bp);
201        p += (dg);
202
203		z *= 1.5;
204		p *= 1.3;
205
206        rz+= (tri(p.z+tri(p.w+tri(p.y+tri(p.x)))))/z;
207
208        bp = bp.yxzw*2.0+.14;
209	}
210	return rz;
211}
212#endif
213
214//--------------------------------------------------------------------------------
215#ifdef TEXTURE_NOISE
216float Noise3d(in vec3 x)
217{
218
219    x*=10.0;
220    float h = 0.0;
221    float a = .34;
222    for (int i = 0; i < 4; i++)
223    {
224        vec3 p = floor(x);
225        vec3 f = fract(x);
226        f = f*f*(3.0-2.0*f);
227
228        vec2 uv = (p.xy+vec2(37.0,17.0)*p.z) + f.xy;
229        vec2 rg = textureLod( iChannel0, (uv+ 0.5)/256.0, 0.0 ).yx;
230        h += mix( rg.x, rg.y, f.z )*a;
231        a*=.5;
232        x+=x;
233    }
234    return h;
235}
236#endif
237
238
239//--------------------------------------------------------------------------------
240#ifdef VALUE_NOISE
241float Hash(vec3 p)
242{
243	p  = fract(p * MOD3);
244    p += dot(p.xyz, p.yzx + 19.19);
245    return fract(p.x * p.y * p.z);
246}
247
248float Noise3d(in vec3 p)
249{
250    vec2 add = vec2(1.0, 0.0);
251	p *= 10.0;
252    float h = 0.0;
253    float a = .3;
254    for (int n = 0; n < 4; n++)
255    {
256        vec3 i = floor(p);
257        vec3 f = fract(p);
258        f *= f * (3.0-2.0*f);
259
260        h += mix(
261            mix(mix(Hash(i), Hash(i + add.xyy),f.x),
262                mix(Hash(i + add.yxy), Hash(i + add.xxy),f.x),
263                f.y),
264            mix(mix(Hash(i + add.yyx), Hash(i + add.xyx),f.x),
265                mix(Hash(i + add.yxx), Hash(i + add.xxx),f.x),
266                f.y),
267            f.z)*a;
268         a*=.5;
269        p += p;
270    }
271    return h;
272}
273#endif
274
275//--------------------------------------------------------------------------------
276float map(vec3 p)
277{
278    p.y += height(p.zx);
279    float d = p.y+.5;
280
281    d = smin(d, vine(p+vec3(.8,0.,0),30.,3.3) );
282    d = smin(d, vine(p.zyx+vec3(0.,0,17.),33.,1.4) );
283    d += Noise3d(p*.05)*(p.y*1.2);
284    p.xz *=.2;
285    d+= Noise3d(p*.3);
286    return d;
287}
288float fogmap(in vec3 p, in float d)
289{
290    p.xz -= time*7.+sin(p.z*.3)*3.;
291    p.y -= time*.5;
292    return (max(Noise3d(p*.008+.1)-.1,0.0)*Noise3d(p*.1))*.3;
293}
294
295float march(in vec3 ro, in vec3 rd, out float drift, in vec2 scUV)
296{
297	float precis = 0.01;
298    float h=precis*2.0;
299    float d = hash12(scUV);
300    drift = 0.0;
301    for( int i=0; i<ITR; i++ )
302    {
303        vec3 p = ro+rd*d;
304        if(h < precis || d > FAR) break;
305        h = map(p);
306        drift +=  fogmap(p, d);
307        d += min(h*.65 + d * .002, 8.0);
308	 }
309    drift = min(drift, 1.0);
310	return d;
311}
312
313vec3 normal( in vec3 pos, in float d )
314{
315	vec2 eps = vec2( d *d* .003+.01, 0.0);
316	vec3 nor = vec3(
317	    map(pos+eps.xyy) - map(pos-eps.xyy),
318	    map(pos+eps.yxy) - map(pos-eps.yxy),
319	    map(pos+eps.yyx) - map(pos-eps.yyx) );
320	return normalize(nor);
321}
322
323float bnoise(in vec3 p)
324{
325    p.xz*=.4;
326    float n = Noise3d(p*3.)*0.4;
327    n += Noise3d(p*1.5)*0.2;
328    return n*n*.2;
329}
330
331vec3 bump(in vec3 p, in vec3 n, in float ds)
332{
333    p.xz *= .4;
334    //p *= 1.0;
335    vec2 e = vec2(.01,0);
336    float n0 = bnoise(p);
337    vec3 d = vec3(bnoise(p+e.xyy)-n0, bnoise(p+e.yxy)-n0, bnoise(p+e.yyx)-n0)/e.x;
338    n = normalize(n-d*10./(ds));
339    return n;
340}
341
342float shadow(in vec3 ro, in vec3 rd, in float mint)
343{
344	float res = 1.0;
345
346    float t = mint;
347    for( int i=0; i<12; i++ )
348    {
349		float h = map(ro + rd*t);
350        res = min( res, 4.*h/t );
351        t += clamp( h, 0.1, 1.5 );
352            }
353    return clamp( res, 0., 1.0 );
354}
355
356vec3 Clouds(vec3 sky, vec3 rd)
357{
358
359    rd.y = max(rd.y, 0.0);
360    float ele = rd.y;
361    float v = (200.0)/rd.y;
362
363    rd.y = v;
364    rd.xz = rd.xz * v - time*8.0;
365	rd.xz *= .0004;
366
367	float f = Noise3d(rd.xzz*3.) * Noise3d(rd.zxx*1.3)*2.5;
368    f = f*pow(ele, .5)*2.;
369  	f = clamp(f-.15, 0.01, 1.0);
370
371    return  mix(sky, vec3(1),f );
372}
373
374
375vec3 Sky(vec3 rd, vec3 ligt)
376{
377    rd.y = max(rd.y, 0.0);
378
379    vec3 sky = mix(vec3(.1, .15, .25), vec3(.8), pow(.8-rd.y, 3.0));
380    return  mix(sky, SUN_COLOUR, min(pow(max(dot(rd,ligt), 0.0), 4.5)*1.2, 1.0));
381}
382float Occ(vec3 p)
383{
384    float h = 0.0;
385    h  = clamp(map(p), 0.5, 1.0);
386 	return sqrt(h);
387}
388
389
390void mainImage( out vec4 fragColor, in vec2 fragCoord )
391{
392	vec2 p = fragCoord.xy/iResolution.xy-0.5;
393    vec2 q = fragCoord.xy/iResolution.xy;
394	p.x*=iResolution.x/iResolution.y;
395#ifdef MOUSE
396    vec2 mo = iMouse.xy / iResolution.xy-.5;
397#else
398    vec2 mo = 0.0 / iResolution.xy-.5;
399#endif
400    mo = (mo==vec2(-.5))?mo=vec2(-0.1,0.07):mo;
401	mo.x *= iResolution.x/iResolution.y;
402
403	vec3 ro = vec3(0.+smoothstep(0.,1.,tri(time*1.5)*.3)*1.5, smoothstep(0.,1.,tri(time*3.)*3.)*0.08, -time*3.5-130.0);
404    ro.y -= camHeight(ro.zx)-.4;
405    mo.x += smoothstep(0.7,1.,sin(time*.35))*.5-1.5 - smoothstep(-.7,-1.,sin(time*.35))*.5;
406
407    vec3 eyedir = normalize(vec3(cos(mo.x),mo.y*2.-.05+sin(time*.5)*0.1,sin(mo.x)));
408    vec3 rightdir = normalize(vec3(cos(mo.x+1.5708),0.,sin(mo.x+1.5708)));
409    vec3 updir = normalize(cross(rightdir,eyedir));
410	vec3 rd=normalize((p.x*rightdir+p.y*updir)*1.+eyedir);
411
412    vec3 ligt = normalize( vec3(1.5, .9, -.5) );
413    float fg;
414	float rz = march(ro,rd, fg, fragCoord);
415	vec3 sky = Sky(rd, ligt);
416
417    vec3 col = sky;
418
419    if ( rz < FAR )
420    {
421        vec3 pos = ro+rz*rd;
422        vec3 nor= normal( pos, rz);
423        float d = distance(pos,ro);
424        nor = bump(pos,nor,d);
425        float shd = (shadow(pos,ligt,.04));
426
427        float dif = clamp( dot( nor, ligt ), 0.0, 1.0 );
428        vec3 ref = reflect(rd,nor);
429        float spe = pow(clamp( dot( ref, ligt ), 0.0, 1.0 ),5.)*2.;
430
431        float fre = pow( clamp(1.+dot(rd, nor),0.0,1.0), 3. );
432        col = vec3(.8);
433	    col = col*dif*shd + fre*spe*shd*SUN_COLOUR +abs(nor.y)*vec3(.12, .13, .13);
434        // Fake the red absorption of ice...
435        d = Occ(pos+nor*3.);
436        col *= vec3(d, d, min(d*1.4, 1.0));
437        // Fog from ice storm...
438        col = mix(col, sky, smoothstep(FAR-25.,FAR,rz));
439
440    }
441    else
442    {
443        col = Clouds(col, rd);
444    }
445
446
447    // Fog mix...
448    col = mix(col, vec3(0.7, .7, .7), fg);
449
450    // Post...
451    col = mix(col, vec3(.5), -.1);
452	//col = clamp(pow(col*1.,vec3(0.4)),0.0, 1.0);
453
454	col = sqrt(col);
455
456
457    // Borders...
458    float f = smoothstep(0.0, 3.0, iGlobalTime)*.5;
459    col *= f+f*pow(70. *q.x*q.y*(1.0-q.x)*(1.0-q.y), .2);
460
461
462	fragColor = vec4( col, 1.0 );
463}
464
465 void main(void)
466{
467  //just some shit to wrap shadertoy's stuff
468  vec2 FragCoord = vTexCoord.xy*OutputSize.xy;
469  mainImage(FragColor,FragCoord);
470}
471#endif
472