1
1
/* This file is part of the Marble Marcher (https://github.com/HackerPoet/MarbleMarcher).
2
2
* Copyright(C) 2018 CodeParade
3
- *
3
+ *
4
4
* This program is free software: you can redistribute it and/or modify
5
5
* it under the terms of the GNU General Public License as published by
6
6
* the Free Software Foundation, either version 2 of the License, or
7
7
* (at your option) any later version.
8
- *
8
+ *
9
9
* This program is distributed in the hope that it will be useful,
10
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
12
* GNU General Public License for more details.
13
- *
13
+ *
14
14
* You should have received a copy of the GNU General Public License
15
15
* along with this program.If not, see <http://www.gnu.org/licenses/>.
16
16
*/
@@ -61,8 +61,8 @@ uniform float iExposure;
61
61
float FOVperPixel;
62
62
63
63
vec3 refraction(vec3 rd, vec3 n, float p) {
64
- float dot_nd = dot (rd, n);
65
- return p * (rd - dot_nd * n) + sqrt (1.0 - (p * p) * (1.0 - dot_nd * dot_nd)) * n;
64
+ float dot_nd = dot (rd, n);
65
+ return p * (rd - dot_nd * n) + sqrt (1.0 - (p * p) * (1.0 - dot_nd * dot_nd)) * n;
66
66
}
67
67
68
68
// ##########################################
@@ -121,40 +121,40 @@ float de_box(vec4 p, vec3 s) {
121
121
}
122
122
float de_tetrahedron(vec4 p, float r) {
123
123
float md = max (max (- p.x - p.y - p.z, p.x + p.y - p.z),
124
- max (- p.x + p.y + p.z, p.x - p.y + p.z));
124
+ max (- p.x + p.y + p.z, p.x - p.y + p.z));
125
125
return (md - r) / (p.w * sqrt (3.0 ));
126
126
}
127
127
float de_capsule(vec4 p, float h, float r) {
128
- p.y -= clamp (p.y, - h, h);
129
- return (length (p.xyz) - r) / p.w;
128
+ p.y -= clamp (p.y, - h, h);
129
+ return (length (p.xyz) - r) / p.w;
130
130
}
131
131
132
132
// ##########################################
133
133
// Main DEs
134
134
// ##########################################
135
135
float de_fractal(vec4 p) {
136
- for (int i = 0 ; i < FRACTAL_ITER; ++ i) {
137
- p.xyz = abs (p.xyz);
138
- rotZ(p, iFracAng1);
139
- mengerFold(p);
140
- rotX(p, iFracAng2);
141
- p *= iFracScale;
142
- p.xyz += iFracShift;
143
- }
144
- return de_box(p, vec3 (6.0 ));
136
+ for (int i = 0 ; i < FRACTAL_ITER; ++ i) {
137
+ p.xyz = abs (p.xyz);
138
+ rotZ(p, iFracAng1);
139
+ mengerFold(p);
140
+ rotX(p, iFracAng2);
141
+ p *= iFracScale;
142
+ p.xyz += iFracShift;
143
+ }
144
+ return de_box(p, vec3 (6.0 ));
145
145
}
146
146
vec4 col_fractal(vec4 p) {
147
- vec3 orbit = vec3 (0.0 );
148
- for (int i = 0 ; i < FRACTAL_ITER; ++ i) {
149
- p.xyz = abs (p.xyz);
150
- rotZ(p, iFracAng1);
151
- mengerFold(p);
152
- rotX(p, iFracAng2);
153
- p *= iFracScale;
154
- p.xyz += iFracShift;
155
- orbit = max (orbit, p.xyz* iFracCol);
156
- }
157
- return vec4 (orbit, de_box(p, vec3 (6.0 )));
147
+ vec3 orbit = vec3 (0.0 );
148
+ for (int i = 0 ; i < FRACTAL_ITER; ++ i) {
149
+ p.xyz = abs (p.xyz);
150
+ rotZ(p, iFracAng1);
151
+ mengerFold(p);
152
+ rotX(p, iFracAng2);
153
+ p *= iFracScale;
154
+ p.xyz += iFracShift;
155
+ orbit = max (orbit, p.xyz* iFracCol);
156
+ }
157
+ return vec4 (orbit, de_box(p, vec3 (6.0 )));
158
158
}
159
159
float de_marble(vec4 p) {
160
160
return de_sphere(p - vec4 (iMarblePos, 0 ), iMarbleRad);
@@ -163,36 +163,36 @@ vec4 col_marble(vec4 p) {
163
163
return vec4 (0 , 0 , 0 , de_sphere(p - vec4 (iMarblePos, 0 ), iMarbleRad));
164
164
}
165
165
float de_flag(vec4 p) {
166
- vec3 f_pos = iFlagPos + vec3 (1.5 , 4 , 0 )* iFlagScale;
167
- float d = de_box(p - vec4 (f_pos, 0 ), vec3 (1.5 , 0.8 , 0.08 )* iMarbleRad);
168
- d = min (d, de_capsule(p - vec4 (iFlagPos + vec3 (0 , iFlagScale* 2.4 , 0 ), 0 ), iMarbleRad* 2.4 , iMarbleRad* 0.18 ));
169
- return d;
166
+ vec3 f_pos = iFlagPos + vec3 (1.5 , 4 , 0 )* iFlagScale;
167
+ float d = de_box(p - vec4 (f_pos, 0 ), vec3 (1.5 , 0.8 , 0.08 )* iMarbleRad);
168
+ d = min (d, de_capsule(p - vec4 (iFlagPos + vec3 (0 , iFlagScale* 2.4 , 0 ), 0 ), iMarbleRad* 2.4 , iMarbleRad* 0.18 ));
169
+ return d;
170
170
}
171
171
vec4 col_flag(vec4 p) {
172
- vec3 f_pos = iFlagPos + vec3 (1.5 , 4 , 0 )* iFlagScale;
173
- float d1 = de_box(p - vec4 (f_pos, 0 ), vec3 (1.5 , 0.8 , 0.08 )* iMarbleRad);
174
- float d2 = de_capsule(p - vec4 (iFlagPos + vec3 (0 , iFlagScale* 2.4 , 0 ), 0 ), iMarbleRad* 2.4 , iMarbleRad* 0.18 );
175
- if (d1 < d2) {
176
- return vec4 (1.0 , 0.2 , 0.1 , d1);
177
- } else {
178
- return vec4 (0.9 , 0.9 , 0.1 , d2);
179
- }
172
+ vec3 f_pos = iFlagPos + vec3 (1.5 , 4 , 0 )* iFlagScale;
173
+ float d1 = de_box(p - vec4 (f_pos, 0 ), vec3 (1.5 , 0.8 , 0.08 )* iMarbleRad);
174
+ float d2 = de_capsule(p - vec4 (iFlagPos + vec3 (0 , iFlagScale* 2.4 , 0 ), 0 ), iMarbleRad* 2.4 , iMarbleRad* 0.18 );
175
+ if (d1 < d2) {
176
+ return vec4 (1.0 , 0.2 , 0.1 , d1);
177
+ } else {
178
+ return vec4 (0.9 , 0.9 , 0.1 , d2);
179
+ }
180
180
}
181
181
float de_scene(vec4 p) {
182
- float d = de_fractal(p);
183
- d = min (d, de_marble(p));
184
- d = min (d, de_flag(p));
185
- return d;
182
+ float d = de_fractal(p);
183
+ d = min (d, de_marble(p));
184
+ d = min (d, de_flag(p));
185
+ return d;
186
186
}
187
187
vec4 col_scene(vec4 p) {
188
- vec4 col = col_fractal(p);
189
- vec4 col_f = col_flag(p);
190
- if (col_f.w < col.w) { col = col_f; }
191
- vec4 col_m = col_marble(p);
192
- if (col_m.w < col.w) {
193
- return vec4 (col_m.xyz, 1.0 );
194
- }
195
- return vec4 (col.xyz, 0.0 );
188
+ vec4 col = col_fractal(p);
189
+ vec4 col_f = col_flag(p);
190
+ if (col_f.w < col.w) { col = col_f; }
191
+ vec4 col_m = col_marble(p);
192
+ if (col_m.w < col.w) {
193
+ return vec4 (col_m.xyz, 1.0 );
194
+ }
195
+ return vec4 (col.xyz, 0.0 );
196
196
}
197
197
198
198
// ##########################################
@@ -201,25 +201,22 @@ vec4 col_scene(vec4 p) {
201
201
202
202
// A faster formula to find the gradient/normal direction of the DE(the w component is the average DE)
203
203
// credit to http://www.iquilezles.org/www/articles/normalsSDF/normalsSDF.htm
204
- vec4 calcGrad(vec4 p, float dx)
205
- {
206
- const vec3 k = vec3 (1 ,- 1 ,0 );
207
- return (k.xyyx* DE(p + k.xyyz* dx) +
208
- k.yyxx* DE(p + k.yyxz* dx) +
209
- k.yxyx* DE(p + k.yxyz* dx) +
210
- k.xxxx* DE(p + k.xxxz* dx)) / vec4 (4 * dx,4 * dx,4 * dx,4 );
204
+ vec4 calcGrad(vec4 p, float dx) {
205
+ const vec3 k = vec3 (1 ,- 1 ,0 );
206
+ return (k.xyyx* DE(p + k.xyyz* dx) +
207
+ k.yyxx* DE(p + k.yyxz* dx) +
208
+ k.yxyx* DE(p + k.yxyz* dx) +
209
+ k.xxxx* DE(p + k.xxxz* dx)) / vec4 (4 * dx,4 * dx,4 * dx,4 );
211
210
}
212
211
213
212
// find the average color of the fractal in a radius dx in plane s1-s2
214
- vec4 smoothColor(vec4 p, vec3 s1, vec3 s2, float dx)
215
- {
216
- return (COL(p + vec4 (s1,0 )* dx) +
217
- COL(p - vec4 (s1,0 )* dx) +
218
- COL(p + vec4 (s2,0 )* dx) +
213
+ vec4 smoothColor(vec4 p, vec3 s1, vec3 s2, float dx) {
214
+ return (COL(p + vec4 (s1,0 )* dx) +
215
+ COL(p - vec4 (s1,0 )* dx) +
216
+ COL(p + vec4 (s2,0 )* dx) +
219
217
COL(p - vec4 (s2,0 )* dx))/ 4 ;
220
218
}
221
219
222
-
223
220
vec4 ray_march(inout vec4 p, vec4 ray, float sharpness) {
224
221
// March the ray
225
222
float d = DE(p);
@@ -275,18 +272,18 @@ vec4 scene(inout vec4 p, inout vec4 ray, float vignette) {
275
272
vec3 s2 = cross (s1,n);
276
273
// get filtered color
277
274
vec4 orig_col = clamp (smoothColor(p, s1, s2, min_dist* 0.5 ), 0.0 , 1.0 );
278
- #else
275
+ #else
279
276
vec4 orig_col = clamp (COL(p), 0.0 , 1.0 );
280
277
#endif
281
- col.w = orig_col.w;
278
+ col.w = orig_col.w;
282
279
283
280
// Get if this point is in shadow
284
281
float k = 1.0 ;
285
282
#if SHADOWS_ENABLED
286
283
vec4 light_pt = p;
287
284
light_pt.xyz += n * MIN_DIST * 100 ;
288
285
vec4 rm = ray_march(light_pt, vec4 (LIGHT_DIRECTION, 0.0 ), SHADOW_SHARPNESS);
289
- k = rm.w * min (rm.z, 1.0 );
286
+ k = rm.w * min (rm.z, 1.0 );
290
287
#endif
291
288
292
289
// Get specular
@@ -340,7 +337,7 @@ void main() {
340
337
for (int i = 0 ; i < ANTIALIASING_SAMPLES; ++ i) {
341
338
for (int j = 0 ; j < ANTIALIASING_SAMPLES; ++ j) {
342
339
// Get normalized screen coordinate
343
- vec2 delta = vec2 (i, j) / ANTIALIASING_SAMPLES;
340
+ vec2 delta = vec2 (i, j) / ANTIALIASING_SAMPLES;
344
341
vec2 screen_pos = (gl_FragCoord .xy + delta) / iResolution.xy;
345
342
346
343
// Calculate the view angle per pixel
@@ -351,40 +348,40 @@ void main() {
351
348
352
349
// Convert screen coordinate to 3d ray
353
350
vec4 ray = iMat * normalize (vec4 (uv.x, uv.y, - FOCAL_DIST, 0.0 ));
354
- vec4 p = iMat[3 ];
351
+ vec4 p = iMat[3 ];
355
352
356
353
// Reflect light if needed
357
354
float vignette = 1.0 - VIGNETTE_STRENGTH * length (screen_pos - 0.5 );
358
- vec3 r = ray.xyz;
359
- vec4 col_r = scene(p, ray, vignette);
355
+ vec3 r = ray.xyz;
356
+ vec4 col_r = scene(p, ray, vignette);
360
357
361
- // Check if this is the glass marble
362
- if (col_r.w > 0.5 ) {
363
- // Calculate refraction
364
- vec3 n = normalize (iMarblePos - p.xyz);
365
- vec3 q = refraction(r, n, 1.0 / 1.5 );
366
- vec3 p2 = p.xyz + (dot (q, n) * 2.0 * iMarbleRad) * q;
367
- n = normalize (p2 - iMarblePos);
368
- q = (dot (q, r) * 2.0 ) * q - r;
369
- vec4 p_temp = vec4 (p2 + n * (MIN_DIST * 10 ), 1.0 );
370
- vec4 r_temp = vec4 (q, 0.0 );
371
- vec3 refr = scene(p_temp, r_temp, 0.8 ).xyz;
358
+ // Check if this is the glass marble
359
+ if (col_r.w > 0.5 ) {
360
+ // Calculate refraction
361
+ vec3 n = normalize (iMarblePos - p.xyz);
362
+ vec3 q = refraction(r, n, 1.0 / 1.5 );
363
+ vec3 p2 = p.xyz + (dot (q, n) * 2.0 * iMarbleRad) * q;
364
+ n = normalize (p2 - iMarblePos);
365
+ q = (dot (q, r) * 2.0 ) * q - r;
366
+ vec4 p_temp = vec4 (p2 + n * (MIN_DIST * 10 ), 1.0 );
367
+ vec4 r_temp = vec4 (q, 0.0 );
368
+ vec3 refr = scene(p_temp, r_temp, 0.8 ).xyz;
372
369
373
- // Calculate refraction
374
- n = normalize (p.xyz - iMarblePos);
375
- q = r - n* (2 * dot (r,n));
376
- p_temp = vec4 (p.xyz + n * (MIN_DIST * 10 ), 1.0 );
377
- r_temp = vec4 (q, 0.0 );
378
- vec3 refl = scene(p_temp, r_temp, 0.8 ).xyz;
370
+ // Calculate refraction
371
+ n = normalize (p.xyz - iMarblePos);
372
+ q = r - n* (2 * dot (r,n));
373
+ p_temp = vec4 (p.xyz + n * (MIN_DIST * 10 ), 1.0 );
374
+ r_temp = vec4 (q, 0.0 );
375
+ vec3 refl = scene(p_temp, r_temp, 0.8 ).xyz;
379
376
380
- // Combine for final marble color
381
- col += refr * 0 .6f + refl * 0 .4f + col_r.xyz;
382
- } else {
383
- col += col_r.xyz;
384
- }
377
+ // Combine for final marble color
378
+ col += refr * 0 .6f + refl * 0 .4f + col_r.xyz;
379
+ } else {
380
+ col += col_r.xyz;
381
+ }
385
382
}
386
383
}
387
384
388
385
col *= iExposure / (ANTIALIASING_SAMPLES * ANTIALIASING_SAMPLES);
389
- gl_FragColor = vec4 (clamp (col, 0.0 , 1.0 ), 1.0 );
386
+ gl_FragColor = vec4 (clamp (col, 0.0 , 1.0 ), 1.0 );
390
387
}
0 commit comments