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// M.A.M. Stairs -  leon - 2017-11-24
106// https://www.shadertoy.com/view/MIIBR7
107
108// Another raymarching sketch inspired by Marc-Antoine Mathieu.
109
110// M.A.M. Stairs by Leon Denise aka ponk
111// another raymarching sketch inspired by Marc-Antoine Mathieu.
112// using code from IQ, Mercury, LJ, Duke, Koltes
113// made with Atom Editor GLSL viewer (that's why there is 2 space tabulations)
114// 2017-11-24
115
116#define STEPS 50.
117#define VOLUME 0.01
118#define PI 3.14159
119#define TAU (2.*PI)
120#define time iGlobalTime
121#define repeat(v,c) (mod(v,c)-c/2.)
122#define sDist(v,r) (length(v)-r)
123
124mat2 rot (float a) { float c=cos(a),s=sin(a); return mat2(c,-s,s,c); }
125float rng (vec2 seed) { return fract(sin(dot(seed*.1684,vec2(32.649,321.547)))*43415.); }
126float sdBox( vec3 p, vec3 b ) { vec3 d = abs(p) - b; return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0)); }
127float amod (inout vec2 p, float count) { float an = TAU/count; float a = atan(p.y,p.x)+an/2.; float c = floor(a/an); c = mix(c,abs(c),step(count*.5,abs(c))); a = mod(a,an)-an/2.; p.xy = vec2(cos(a),sin(a))*length(p); return c; }
128float aindex (vec2 p, float count) { float an = TAU/count; float a = atan(p.y,p.x)+an/2.; float c = floor(a/an); return mix(c,abs(c),step(count*.5,abs(c))); }
129float map (vec3);
130vec3 getNormal (vec3 p) { vec2 e = vec2(.001,0); return normalize(vec3(map(p+e.xyy)-map(p-e.xyy),map(p+e.yxy)-map(p-e.yxy),map(p+e.yyx)-map(p-e.yyx))); }
131float hardShadow (vec3 pos, vec3 light) {
132    vec3 dir = normalize(light - pos);
133    float maxt = length(light - pos);
134    float t = .02;
135    for (float i = 0.; i <= 1.; i += 1./30.) {
136        float dist = map(pos + dir * t);
137        if (dist < VOLUME) return 0.;
138        t += dist;
139        if (t >= maxt) break;
140    }
141    return 1.;
142}
143
144float map (vec3 pos) {
145  float scene = 1000.;
146  float wallThin = .2;
147  float wallRadius = 8.;
148  float wallOffset = .2;
149  float wallCount = 10.;
150  float floorThin = .1;
151  float stairRadius = 5.;
152  float stairHeight = .4;
153  float stairCount = 40.;
154  float stairDepth = .31;
155  float bookCount = 100.;
156  float bookRadius = 9.5;
157  float bookSpace = 1.75;
158  vec3 bookSize = vec3(1.,.2,.2);
159  vec3 panelSize = vec3(.03,.2,.7);
160  vec2 cell = vec2(1.4,3.);
161  float paperRadius = 4.;
162  vec3 paperSize = vec3(.3,.01,.4);
163  vec3 p;
164
165  // move it
166  pos.y += time;
167
168  // twist it
169  // pos.xz *= rot(pos.y*.05+time*.1);
170  // pos.xz += normalize(pos.xz) * sin(pos.y*.5+time);
171
172  // holes
173  float holeWall = sDist(pos.xz, wallRadius);
174  float holeStair = sDist(pos.xz, stairRadius);
175
176  // walls
177  p = pos;
178  amod(p.xz, wallCount);
179  p.x -= wallRadius;
180  scene = min(scene, max(-p.x, abs(p.z)-wallThin));
181  scene = max(scene, -sDist(pos.xz, wallRadius-wallOffset));
182
183  // floors
184  p = pos;
185  p.y = repeat(p.y, cell.y);
186  float disk = max(sDist(p.xz, 1000.), abs(p.y)-floorThin);
187  disk = max(disk, -sDist(pos.xz, wallRadius));
188  scene = min(scene, disk);
189
190  // stairs
191  p = pos;
192  float stairIndex = amod(p.xz, stairCount);
193  p.y -= stairIndex*stairHeight;
194  p.y = repeat(p.y, stairCount*stairHeight);
195  float stair = sdBox(p, vec3(100,stairHeight,stairDepth));
196  scene = min(scene, max(stair, max(holeWall, -holeStair)));
197  p = pos;
198  p.xz *= rot(PI/stairCount);
199  stairIndex = amod(p.xz, stairCount);
200  p.y -= stairIndex*stairHeight;
201  p.y = repeat(p.y, stairCount*stairHeight);
202  stair = sdBox(p, vec3(100,stairHeight,stairDepth));
203  scene = min(scene, max(stair, max(holeWall, -holeStair)));
204  p = pos;
205  p.y += stairHeight*.5;
206  p.y -= stairHeight*stairCount*atan(p.z,p.x)/TAU;
207  p.y = repeat(p.y, stairCount*stairHeight);
208  scene = min(scene, max(max(sDist(p.xz, wallRadius), abs(p.y)-stairHeight), -holeStair));
209
210  // books
211  p = pos;
212  p.y -= cell.y*.5;
213  vec2 seed = vec2(floor(p.y/cell.y), 0);
214  p.y = repeat(p.y, cell.y);
215  p.xz *= rot(PI/wallCount);
216  seed.y += amod(p.xz, wallCount)/10.;
217  seed.y += floor(p.z/(bookSize.z*bookSpace));
218  p.z = repeat(p.z, bookSize.z*bookSpace);
219  float salt = rng(seed);
220  bookSize.x *= .5+.5*salt;
221  bookSize.y += salt;
222  bookSize.z *= .5+.5*salt;
223  p.x -= bookRadius + wallOffset;
224  p.x += cos(p.z*2.) - bookSize.x - salt * .25;
225  p.x += .01*smoothstep(.99,1.,sin(p.y*(1.+10.*salt)));
226  scene = min(scene, max(sdBox(p, vec3(bookSize.x,100.,bookSize.z)), p.y-bookSize.y));
227
228  // panel
229  p = pos;
230  p.y = repeat(p.y, cell.y);
231  p.xz *= rot(PI/wallCount);
232  amod(p.xz, wallCount);
233  p.x -= wallRadius;
234  float panel = sdBox(p, panelSize);
235  float pz = p.z;
236  p.z = repeat(p.z, .2+.3*salt);
237  panel = min(panel, max(sdBox(p, vec3(.1,.1,.04)), abs(pz)-panelSize.z*.8));
238  scene = min(scene, panel);
239
240  // papers
241  p = pos;
242  p.y -= stairHeight;
243  p.y += time*2.;
244  p.xz *= rot(PI/stairCount);
245  float ry = 8.;
246  float iy = floor(p.y/ry);
247  salt = rng(vec2(iy));
248  float a = iy;
249  p.xz -= vec2(cos(a),sin(a))*paperRadius;
250  p.y = repeat(p.y, ry);
251  p.xy *= rot(p.z);
252  p.xz *= rot(PI/4.+salt+time);
253  scene = min(scene, sdBox(p, paperSize));
254
255  return scene;
256}
257
258vec3 getCamera (vec3 eye, vec2 uv) {
259  vec3 lookAt = vec3(0.);
260#ifdef MOUSE
261  float click = clamp(iMouse.w,0.,1.);
262  lookAt.x += mix(0.,((iMouse.x/iResolution.x)*2.-1.) * 10., click);
263  lookAt.y += mix(0.,iMouse.y/iResolution.y * 10., click);
264#else
265  float click = clamp(0.,0.,1.);
266  lookAt.x += mix(0.,((0./iResolution.x)*2.-1.) * 10., click);
267  lookAt.y += mix(0.,0./iResolution.y * 10., click);
268#endif
269  float fov = .65;
270  vec3 forward = normalize(lookAt - eye);
271  vec3 right = normalize(cross(vec3(0,1,0), forward));
272  vec3 up = normalize(cross(forward, right));
273  return normalize(fov * forward + uv.x * right + uv.y * up);
274}
275
276float getLight (vec3 pos, vec3 eye) {
277  vec3 light = vec3(-.5,7.,1.);
278  vec3 normal = getNormal(pos);
279  vec3 view = normalize(eye-pos);
280  float shade = dot(normal, view);
281  shade *= hardShadow(pos, light);
282  return shade;
283}
284
285vec4 raymarch () {
286  vec2 uv = (gl_FragCoord.xy-.5*iResolution.xy)/iResolution.y;
287  float dither = rng(uv+fract(time));
288  vec3 eye = vec3(0,5,-4.5);
289  vec3 ray = getCamera(eye, uv);
290  vec3 pos = eye;
291  float shade = 0.;
292  for (float i = 0.; i <= 1.; i += 1./STEPS) {
293    float dist = map(pos);
294		if (dist < VOLUME) {
295			shade = 1.-i;
296			break;
297		}
298    dist *= .5 + .1 * dither;
299    pos += ray * dist;
300  }
301
302  vec4 color = vec4(shade);
303  color *= getLight(pos, eye);
304  color = smoothstep(.0, .5, color);
305  color = sqrt(color);
306  return color;
307}
308
309void mainImage( out vec4 fragColor, in vec2 fragCoord )
310{
311	fragColor = raymarch();
312}
313
314 void main(void)
315{
316  //just some shit to wrap shadertoy's stuff
317  vec2 FragCoord = vTexCoord.xy*OutputSize.xy;
318  mainImage(FragColor,FragCoord);
319}
320#endif
321