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// Skin peeler -  2015-08-19
106// https://www.shadertoy.com/view/XtfSWX
107
108// Skin peeler
109// by Dave Hoskins
110// Originally from Xyptonjtroz by nimitz (twitter: @stormoid)
111// Edited by Dave Hoskins, by changing atmosphere with quite a few lighting changes & added audio
112
113#define ITR 100
114#define FAR 30.
115#define time iGlobalTime
116
117/*
118	Believable animated volumetric dust storm in 7 samples,
119	blending each layer in based on geometry distance allows to
120	render it without visible seams. 3d Triangle noise is
121	used for the dust volume.
122
123	Further explanation of the dust generation...
124
125	The basic idea is to have layers of gradient shaded volumetric
126	animated noise. The problem is when geometry is intersected
127	before the ray reaches the far plane. A way to smoothly blend
128	the low sampled noise is needed.  So I am blending (smoothstep)
129	each dust layer based on current ray distance and the solid
130	interesction distance. I am also scaling the noise taps	as a
131	function of the current distance so that the distant dust doesn't
132	appear too noisy and as a function of current height to get some
133	"ground hugging" effect.
134
135*/
136
137#define MOD3 vec3(.16532,.17369,.15787)
138mat2 mm2(in float a){float c = cos(a), s = sin(a);return mat2(c,s,-s,c);}
139
140float height(in vec2 p)
141{
142    p *= 0.2;
143    return sin(p.y)*0.4 + sin(p.x)*0.4;
144}
145
146//smooth min form iq
147float smin( float a, float b)
148{
149    const float k = 0.7;
150	float h = clamp( 0.5 + 0.5*(b-a)/k, 0.0, 1.0 );
151	return mix( b, a, h ) - k*h*(1.0-h);
152}
153
154///  2 out, 2 in...
155vec2 hash22(vec2 p)
156{
157	vec3 p3 = fract(vec3(p.xyx) * MOD3);
158    p3 += dot(p3.zxy, p3.yxz+19.19);
159    return fract(vec2(p3.x * p3.y, p3.z*p3.x));
160}
161
162float vine(vec3 p, in float c, in float h)
163{
164    p.y += sin(p.z*.5625+1.3)*1.5-.5;
165    p.x += cos(p.z*.4575)*1.;
166    //p.z -=.3;
167    vec2 q = vec2(mod(p.x, c)-c/2., p.y);
168    return length(q) - h -sin(p.z*3.+sin(p.x*7.)*0.5+time)*0.13;
169}
170
171float map(vec3 p)
172{
173    p.y += height(p.zx);
174
175    vec3 bp = p;
176    vec2 hs = hash22(floor(p.zx/4.));
177    p.zx = mod(p.zx,4.)-2.;
178
179    float d = p.y+0.5;
180    p.y -= hs.x*0.4-0.15;
181    p.zx += hs*1.3;
182    d = smin(d, length(p)-hs.x*0.4);
183
184    d = smin(d, vine(bp+vec3(1.8,0.,0),15.,.8) );
185    d = smin(d, vine(bp.zyx+vec3(0.,0,17.),20.,0.75) );
186
187    return d*1.1;
188}
189
190float march(in vec3 ro, in vec3 rd)
191{
192	float precis = 0.002;
193    float h=precis*2.0;
194    float d = 0.;
195    for( int i=0; i<ITR; i++ )
196    {
197        if( abs(h)<precis || d>FAR ) break;
198        d += h;
199	   	h = map(ro+rd*d);
200
201    }
202	return d;
203}
204
205float tri(in float x){return abs(fract(x)-.5);}
206vec3 tri3(in vec3 p){return vec3( tri(p.z+tri(p.y*1.)), tri(p.z+tri(p.x*1.)), tri(p.y+tri(p.x*1.)));}
207
208mat2 m2 = mat2(0.970,  0.242, -0.242,  0.970);
209
210float triNoise3d(in vec3 p)
211{
212    float z=1.4;
213	float rz = 0.;
214    vec3 bp = p;
215	for (float i=0.; i<=3.; i++ )
216	{
217        vec3 dg = tri3(bp);
218        p += (dg);
219
220        bp *= 2.;
221		z *= 1.5;
222		p *= 1.2;
223        //p.xz*= m2;
224
225        rz+= (tri(p.z+tri(p.x+tri(p.y))))/z;
226        bp += 0.14;
227	}
228	return rz;
229}
230
231float fogmap(in vec3 p, in float d)
232{
233   p.x += time;
234   p.z += time*.5;
235
236    return triNoise3d(p*2.2/(d+8.0))*(smoothstep(.7,.0,p.y));
237}
238
239vec3 fog(in vec3 col, in vec3 ro, in vec3 rd, in float mt)
240{
241    float d = .5;
242    for(int i=0; i<7; i++)
243    {
244        vec3  pos = ro + rd*d;
245        float rz = fogmap(pos, d);
246        col = mix(col,vec3(.85, .65, .5),clamp(rz*smoothstep(d,d*1.8,mt),0.,1.) );
247        d *= 1.8;
248        if (d>mt)break;
249    }
250    return col;
251}
252
253vec3 normal(in vec3 p)
254{
255    vec2 e = vec2(-1., 1.)*0.005;
256	return normalize(e.yxx*map(p + e.yxx) + e.xxy*map(p + e.xxy) +
257					 e.xyx*map(p + e.xyx) + e.yyy*map(p + e.yyy) );
258}
259
260float bnoise(in vec3 p)
261{
262    float n = sin(triNoise3d(p*3.)*7.)*0.4;
263    n += sin(triNoise3d(p*1.5)*7.)*0.2;
264    return (n*n)*0.01;
265}
266
267vec3 bump(in vec3 p, in vec3 n, in float ds)
268{
269    vec2 e = vec2(.005,0);
270    float n0 = bnoise(p);
271    vec3 d = vec3(bnoise(p+e.xyy)-n0, bnoise(p+e.yxy)-n0, bnoise(p+e.yyx)-n0)/e.x;
272    n = normalize(n-d*2.5/sqrt(ds));
273    return n;
274}
275
276float shadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
277{
278	float res = 1.0;
279    float t = mint;
280    for( int i=0; i<20; i++ )
281    {
282		float h = map(ro + rd*t);
283        res = min( res, 4.*h/t );
284        t += clamp( h, 0.2, 1.5 );
285            }
286    return clamp( res, 0.0, 1.0 );
287
288}
289
290
291void mainImage( out vec4 fragColor, in vec2 fragCoord )
292
293{
294	vec2 p = fragCoord.xy/iResolution.xy-0.5;
295    vec2 q = fragCoord.xy/iResolution.xy;
296	p.x*=iResolution.x/iResolution.y;
297#ifdef MOUSE
298    vec2 mo = iMouse.xy / iResolution.xy-.5;
299#else
300    vec2 mo = 0.0 / iResolution.xy-.5;
301#endif
302    mo = (mo==vec2(-.5))?mo=vec2(-0.1,0.07):mo;
303	mo.x *= iResolution.x/iResolution.y;
304
305	vec3 ro = vec3(smoothstep(0.,1.,tri(time*.6)*2.)*0.1, smoothstep(0.,1.,tri(time*1.2)*2.)*0.05, -time*0.6);
306    ro.y -= height(ro.zx)+0.07;
307    mo.x += smoothstep(0.7,1.,sin(time*.35))-1.5 - smoothstep(-.7,-1.,sin(time*.35));
308
309    vec3 eyedir = normalize(vec3(cos(mo.x),mo.y*2.-0.2+sin(time*.75*1.37)*0.15,sin(mo.x)));
310    vec3 rightdir = normalize(vec3(cos(mo.x+1.5708),0.,sin(mo.x+1.5708)));
311    vec3 updir = normalize(cross(rightdir,eyedir));
312	vec3 rd=normalize((p.x*rightdir+p.y*updir)*1.+eyedir);
313
314    vec3 ligt = normalize( vec3(.5, .5, -.2) );
315
316	float rz = march(ro,rd);
317
318    vec3 fogb = mix(vec3(.5, .4,.4), vec3(1.,.9,.8), min(pow(max(dot(rd,ligt), 0.0), 1.5)*1.25, 1.0));
319    vec3 col = fogb;
320
321    if ( rz < FAR )
322    {
323        vec3 pos = ro+rz*rd;
324        vec3 nor= normal( pos );
325        float d = distance(pos,ro);
326        nor = bump(pos,nor,d);
327        float shd = shadow(pos,ligt,0.1,3.);
328        float dif = clamp( dot( nor, ligt ), 0.0, 1.0 )*shd;
329        float spe = pow(clamp( dot( reflect(rd,nor), ligt ), 0.0, 1.0 ),3.)*shd;
330        float fre = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 1.5 );
331        vec3 brdf = dif*vec3(1.00)+abs(nor.y)*.4;
332        col = clamp(mix(vec3(.7,0.4,.3),vec3(.3, 0.1, 0.1),(pos.y+.5)*.25), .0, 1.0);
333        col *= (sin(bnoise(pos*.1)*250.)*0.5+0.5);
334        col = col*brdf + spe*fre;// + fre*vec3(.4,.4,0.4)*.5*crv;
335    }
336
337    //ordinary distance fog first
338    col = mix(col, fogb, smoothstep(FAR-10.,FAR,rz));
339
340    //then volumetric fog
341    col = fog(col, ro, rd, rz);
342
343    //post...
344
345	col = pow(col,vec3(0.8));
346    col = smoothstep(0.0, 1.0, col);
347
348    col *= .5+.5*pow(70. *q.x*q.y*(1.0-q.x)*(1.0-q.y), .2);
349
350
351	fragColor = vec4( col  * smoothstep(0.0, 3.0, time), 1.0 );
352}
353
354 void main(void)
355{
356  //just some shit to wrap shadertoy's stuff
357  vec2 FragCoord = vTexCoord.xy*OutputSize.xy;
358  mainImage(FragColor,FragCoord);
359}
360#endif
361