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
105float time;
106
107// ******* Tools  *******
108
109vec3 rotate(vec3 r, float v){ return vec3(r.x*cos(v)+r.z*sin(v),r.y,r.z*cos(v)-r.x*sin(v));}
110
111float box( vec3 p, vec3 b ){
112  vec3 d = abs(p) - b;
113  return min(max(d.x,max(d.y,d.z)),0.0)+length(max(d,0.0));
114}
115
116float sphere( vec3 p, float r ){
117    return r-length(p);
118}
119
120float rand2d(vec2 n){
121  return fract(sin(dot(n,vec2(12.9898,4.1414))) * 43758.5453);
122}
123
124float noise2d(vec2 n){
125  vec2 b = floor(n);
126  vec2 f = smoothstep(vec2(0.0,0.0),vec2(1.0,1.0),fract(n));
127  return mix(mix(rand2d(b),rand2d(b+vec2(1.0,0.0)),f.x),mix(rand2d(b+vec2(0.0,1.0)),rand2d(b+vec2(1.0,1.0)),f.x),f.y);
128}
129
130// ******* Scene  *******
131
132vec3 path(float t){
133	t += 6.0;
134    return vec3(sin(t*-0.2)*200.0,sin(t*0.053)*300.0-470.0,sin(t*0.13)*400.0+3.2);
135}
136
137vec3 env(vec3 r){
138    return mix(vec3(0.05,0.08,0.15),vec3(0.41,0.45,0.45),pow(0.6+sin(r.y)*0.4,4.0));
139}
140
141float terrain(vec3 pos){
142
143    pos = rotate(pos,time*0.01);
144    float  n1 = noise2d(pos.xz*0.1+pos.z*0.1);
145    float  p1 =  pos.y - 500.0;
146    float  s1 =  450.0 + pos.y + sin(pos.x*0.01)*30.0 - abs(pos.z*0.2) - n1*10.0;
147
148    vec3 pp =   abs(pos) -120.0;
149         pp =   abs(pp)  -120.0;
150         pp =   abs(pp)  -120.0;
151
152    float p2 = 8.0 - box(pp+vec3(0.0,0.0,30.0),   vec3(10.0,115.0,10.0));
153    float p3 = 1.0 - box(pp+vec3(0.0,0.0,0.0),    vec3(110.0,3.0,115.0))-sin(n1*10.)*0.1;
154    float p4 = 1.0 - box(pp+vec3(0.0,0.0,30.0),   vec3(120.0,6.0,10.0));
155    float p5 = 1.0 - box(pp+vec3(-120.0,20.0,0.0),vec3(2.0,80.0,120.0));
156    float p6 = 1.0 - box(pp+vec3(0.0,20.0,-120.0),vec3(120.0,40.0,2.0));
157    float p7 = 1.0 - box(pp+vec3(70.0,0.0,-130.0),vec3(2.0,120.0,2.0));
158
159    float c1 = sphere(pos,300.0)+n1*10.0 -sin(pos.y*0.01)*10.0;
160    float c2 = sphere(pos+vec3(0.0,300.0+sin(time*0.3)*50.0,00.0),120.0)+n1*5.0*sin(time*2.0+pos.z*0.01);
161
162    float s = min(max(min(min(max(max(max(max(max(max(p2,p3),p4),p1),p5),p6),p7),-c1),-c2-50.0),c2),s1);
163
164	return s;
165}
166
167
168// ******* Main  *******
169
170float test = 0.0;
171float tran = 0.0;
172vec3  pos = vec3(0.0);
173
174void raymarch(vec3 p,vec3 r){
175    test = 0.0;
176    tran = 0.0;
177	pos  = p;
178    for(int i=0;i<40;i++){
179        test  = terrain(pos);
180        pos  += r*test;
181        tran += test;
182        if(abs(test)<=0.01){ break; }
183    }
184}
185
186
187void mainImage( out vec4 fragColor, in vec2 fragCoord ){
188
189    time        = iGlobalTime*2.0;
190    float pulse	= pow(max(sin(time*0.5),0.0)*0.98,50.0);
191
192	vec2 uv     = fragCoord.xy/(iResolution.xx*0.5)-vec2(1.0,iResolution.y/iResolution.x);
193    vec3 ray1   = normalize(vec3(uv.x,uv.y,0.5));
194#ifdef MOUSE
195    vec3 campos = path(time)+vec3(iMouse.x,-50.0+iMouse.y,500.0+sin(time*0.02)*400.0);
196#else
197    vec3 campos = path(time)+vec3(0.0,-50.0+0.0,500.0+sin(time*0.02)*400.0);
198#endif
199    vec3 lightpos = path(time+0.5);
200
201
202    // Surface
203    raymarch(campos + ray1*-10.0, ray1);
204    float test1 = test;
205    float tran1 = tran;
206    vec3  pos1  = pos;
207
208    // Shadow
209	vec3  ray2   = normalize(pos1-lightpos);
210    raymarch(pos1+ray1,ray2);
211    float test2  = test;
212    float tran2  = tran;
213    vec3  pos2   = pos;
214    float dist   = distance(lightpos,pos1);
215	float dist2  = distance(lightpos,campos);
216
217    // Normal
218    vec3  axe = vec3(0.1,0.0,0.0);
219    vec3  nor = normalize(vec3( test1-terrain(pos1-axe.xyy) , test1-terrain(pos1-axe.yxy) , test1-terrain(pos1-axe.yyx) ) );
220    float ang = max(0.0,dot(nor,-ray1));
221
222    // Shade
223    float bkg = smoothstep(4000.0,0.0,distance(campos,pos1));
224    float ocl = min(smoothstep(0.0,80.0,test1-terrain(pos1-nor*20.0)),pow(smoothstep(0.0,1000.0,test1-terrain(pos1-nor*200.0)),1.0))*bkg;
225    float sha = smoothstep(-50.0,0.0,abs(tran2)-dist)*pow(smoothstep(2000.0+pulse*1000.0,0.0,dist),20.0)*bkg;
226
227	float fog = noise2d(ray1.xy*3.0+campos.xz*0.001+vec2(0.0,-time*0.2));
228	float mtr = noise2d(pos1.xz*0.5+pos1.y)*1.0;
229
230    float dif = smoothstep(0.0,1.0,ang)*sha;
231    float spc = smoothstep(0.8,1.0,ang)*sha;
232
233    vec3  col  = mix(env(ray1)*0.3,(0.01+mtr*0.1+env(nor))*pow(ocl,0.6),bkg);
234          col += (vec3(1.70,1.65,1.60)+mtr*0.3)*dif;
235          col += (vec3(0.80,0.80,0.70)+mtr*0.3)*spc;
236
237
238    // Fake some visible light
239	float lightdist = smoothstep(200.0+pulse*400.0,0.0,length(cross(ray1,lightpos-campos)));
240    float lightdepth = smoothstep(10.0,-100.0,tran1+dist2);
241	float l = pow(lightdist,20.0)*lightdepth;
242		  l += fog*0.2*lightdist*lightdepth + fog*0.01;
243
244    fragColor = vec4(sqrt(col+l)-dot(uv,uv)*0.12,1.0);
245
246}
247
248 void main(void)
249{
250  //just some shit to wrap shadertoy's stuff
251  vec2 FragCoord = vTexCoord.xy*OutputSize.xy;
252  mainImage(FragColor,FragCoord);
253}
254#endif
255