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
105vec2 doModel(vec3 p);
106
107vec2 calcRayIntersection(vec3 rayOrigin, vec3 rayDir, float maxd, float precis) {
108  float latest = precis * 2.0;
109  float dist   = +0.0;
110  float type   = -1.0;
111  vec2  res    = vec2(-1.0, -1.0);
112
113  for (int i = 0; i < 70; i++) {
114    if (latest < precis || dist > maxd) break;
115
116    vec2 result = doModel(rayOrigin + rayDir * dist);
117
118    latest = result.x;
119    type   = result.y;
120    dist  += latest;
121  }
122
123  if (dist < maxd) {
124    res = vec2(dist, type);
125  }
126
127  return res;
128}
129
130vec2 calcRayIntersection(vec3 rayOrigin, vec3 rayDir) {
131  return calcRayIntersection(rayOrigin, rayDir, 20.0, 0.001);
132}
133
134vec3 calcNormal(vec3 pos, float eps) {
135  const vec3 v1 = vec3( 1.0,-1.0,-1.0);
136  const vec3 v2 = vec3(-1.0,-1.0, 1.0);
137  const vec3 v3 = vec3(-1.0, 1.0,-1.0);
138  const vec3 v4 = vec3( 1.0, 1.0, 1.0);
139
140  return normalize( v1 * doModel( pos + v1*eps ).x +
141                    v2 * doModel( pos + v2*eps ).x +
142                    v3 * doModel( pos + v3*eps ).x +
143                    v4 * doModel( pos + v4*eps ).x );
144}
145
146vec3 calcNormal(vec3 pos) {
147  return calcNormal(pos, 0.002);
148}
149
150vec2 squareFrame(vec2 screenSize, vec2 coord) {
151  vec2 position = 2.0 * (coord.xy / screenSize.xy) - 1.0;
152  position.x *= screenSize.x / screenSize.y;
153  return position;
154}
155
156mat3 calcLookAtMatrix(vec3 origin, vec3 target, float roll) {
157  vec3 rr = vec3(sin(roll), cos(roll), 0.0);
158  vec3 ww = normalize(target - origin);
159  vec3 uu = normalize(cross(ww, rr));
160  vec3 vv = normalize(cross(uu, ww));
161
162  return mat3(uu, vv, ww);
163}
164
165vec3 getRay(mat3 camMat, vec2 screenPos, float lensLength) {
166  return normalize(camMat * vec3(screenPos, lensLength));
167}
168
169vec3 getRay(vec3 origin, vec3 target, vec2 screenPos, float lensLength) {
170  mat3 camMat = calcLookAtMatrix(origin, target, 0.0);
171  return getRay(camMat, screenPos, lensLength);
172}
173
174void orbitCamera(
175  in float camAngle,
176  in float camHeight,
177  in float camDistance,
178  in vec2 screenResolution,
179  out vec3 rayOrigin,
180  out vec3 rayDirection,
181  in vec2 coord
182) {
183  vec2 screenPos = squareFrame(screenResolution, coord);
184  vec3 rayTarget = vec3(0.0);
185
186  rayOrigin = vec3(
187    camDistance * sin(camAngle),
188    camHeight,
189    camDistance * cos(camAngle)
190  );
191
192  rayDirection = getRay(rayOrigin, rayTarget, screenPos, 2.0);
193}
194
195float sdBox(vec3 position, vec3 dimensions) {
196  vec3 d = abs(position) - dimensions;
197
198  return min(max(d.x, max(d.y,d.z)), 0.0) + length(max(d, 0.0));
199}
200
201float gaussianSpecular(
202  vec3 lightDirection,
203  vec3 viewDirection,
204  vec3 surfaceNormal,
205  float shininess) {
206  vec3 H = normalize(lightDirection + viewDirection);
207  float theta = acos(dot(H, surfaceNormal));
208  float w = theta / shininess;
209  return exp(-w*w);
210}
211
212const float PI = 3.14159265359;
213
214vec2 rotate2D(vec2 p, float a) {
215 return p * mat2(cos(a), -sin(a), sin(a),  cos(a));
216}
217
218vec3 palette(float t, vec3 a, vec3 b, vec3 c, vec3 d) {
219  return a + b * cos(6.28318 * (c * t + d));
220}
221
222vec3 gradient(float t) {
223  return palette(t,
224    vec3(0.5),
225    vec3(0.5),
226    vec3(0.5, 0.25, 0.39),
227    vec3(0.35, 0.25, 0.15)
228  );
229}
230
231float modAngle(inout vec2 p, float a) {
232  float a1 = atan(p.y, p.x);
233  float a2 = mod(a1 + a * 0.5, a) - a * 0.5;
234
235  p = vec2(cos(a2), sin(a2)) * length(p);
236
237  return mod(floor(a1 / a + 0.5), 2.0 * PI / a);
238}
239
240float modRot(inout vec2 p, float i) {
241  return modAngle(p, 2.0 * PI / i);
242}
243
244vec2 doModel(vec3 p) {
245  float off2 = iGlobalTime * -0.5 + sin(iGlobalTime * 2.) * 0.4;
246  float off1 = 1.7 + sin(-iGlobalTime * 3.) * .25;
247  float bsize = 0.1 - pow(abs(p.y / off1), 20.05) * 0.15;
248  float d = length(p) - 1.;
249
250  d += sin((p.x * p.y * p.z) * 10. - iGlobalTime * 5.) * 0.025;
251  d = min(d, length(abs(p) - vec3(0, off1, 0)) - 0.3);
252
253  modRot(p.xz, 8.0);
254  p.yx = rotate2D(p.yx, off2);
255  modRot(p.yx, 6.0);
256
257  p.xz = rotate2D(p.xz, iGlobalTime * 2. + sin(iGlobalTime * 2.) * 2.);
258  float d2 = sdBox(p - vec3(0, off1, 0), vec3(bsize)) - 0.02;
259
260  d = min(d, d2);
261
262  return vec2(d, 0.0);
263}
264
265vec3 bg(vec3 ro, vec3 rd) {
266  return gradient(rd.y);
267}
268
269void mainImage(out vec4 fragColor, in vec2 fragCoord) {
270  vec3 ro, rd;
271
272  vec2  uv       = squareFrame(iResolution.xy, fragCoord.xy);
273  float rotation = iGlobalTime * 0.85;
274  float height   = 0.1;
275  float dist     = 4.5;
276
277  orbitCamera(rotation, height, dist, iResolution.xy, ro, rd, fragCoord.xy);
278
279  vec3 color = mix(bg(ro, rd) * 1.5, vec3(1), 0.125);
280  vec2 t = calcRayIntersection(ro, rd, 8., 0.005);
281  if (t.x > -0.5) {
282    vec3 pos = ro + rd * t.x;
283    vec3 nor = calcNormal(pos);
284    color = bg(pos, reflect(rd, nor));
285    color += gaussianSpecular(vec3(0, 1, 0), -rd, nor, 0.415) * 1.0;
286  }
287
288  color = mix(color, vec3(1), 0.5);
289  color -= dot(uv, uv * 0.155) * vec3(0.5, 1, 0.7) * 0.9;
290  color.r = smoothstep(0.1, 0.9, color.r);
291  color.g = smoothstep(0.0, 1.1, color.g);
292  color.b = smoothstep(0.05, 1.0, color.b);
293
294  fragColor.rgb = color;
295  fragColor.a   = 1.0;
296}
297
298 void main(void)
299{
300  //just some shit to wrap shadertoy's stuff
301  vec2 FragCoord = vTexCoord.xy*OutputSize.xy;
302  mainImage(FragColor,FragCoord);
303}
304#endif
305