1{
2  is_2d: #false;
3  is_3d: #true;
4  bbox: [[-0.375,-0.375,-0.5],[0.75,0.375,0.5]];
5  shader:
6    "#define AA 1
7    |#define TAA 1
8    |#define FDUR 0.04
9    |const vec3 background_colour = vec3(1,1,1);
10    |const int ray_max_iter = 200;
11    |const float ray_max_depth = 400.0;
12    |#ifdef GLSLVIEWER
13    |uniform vec3 u_eye3d;
14    |uniform vec3 u_centre3d;
15    |uniform vec3 u_up3d;
16    |#endif
17    |uniform float rv_Morph;
18    |float dist(vec4 r0)
19    |{
20    |  /* constants */
21    |  float r3 = 0.5;
22    |  float r7 = 0.0;
23    |  float r11 = 0.375;
24    |  vec3 r21 = vec3(0.375,0.0,0.0);
25    |  float r31 = 1.5707963267948966;
26    |  vec3 r32 = vec3(1.0,0.0,0.0);
27    |  float r63 = 1.0;
28    |  float r77 = 0.325;
29    |  float r81 = 0.05;
30    |  float r92 = 0.3375;
31    |  vec3 r104 = vec3(0.0,0.0,-0.4625);
32    |  float r117 = 0.0375;
33    |  float r132 = rv_Morph;
34    |  float r133 = 1.0/0.0;
35    |  /* body */
36    |  float r1 = r0.z;
37    |  float r2 = abs(r1);
38    |  float r4 = r2-r3;
39    |  float r5 = r0.x;
40    |  float r6 = r0.y;
41    |  float r8 = r0.w;
42    |  vec2 r9 = vec2(r5,r6);
43    |  float r10 = length(r9);
44    |  float r12 = r10-r11;
45    |  vec2 r13 = vec2(r4,r12);
46    |  vec2 r14 = vec2(r7);
47    |  vec2 r15 = max(r13,r14);
48    |  float r16 = length(r15);
49    |  float r17 = max(r4,r12);
50    |  float r18 = min(r17,r7);
51    |  float r19 = r16+r18;
52    |  float r20 = r0.x;
53    |  float r22 = r21.x;
54    |  float r23 = r20-r22;
55    |  float r24 = r0.y;
56    |  float r25 = r21.y;
57    |  float r26 = r24-r25;
58    |  float r27 = r0.z;
59    |  float r28 = r21.z;
60    |  float r29 = r27-r28;
61    |  float r30 = r0.w;
62    |  vec3 r33 = vec3(r23,r26,r29);
63    |  float r34 = cos(r31);
64    |  vec3 r35 = vec3(r34);
65    |  vec3 r36 = r33*r35;
66    |  float r37 = r32.y;
67    |  float r38 = r33.z;
68    |  float r39 = r37*r38;
69    |  float r40 = r32.z;
70    |  float r41 = r33.y;
71    |  float r42 = r40*r41;
72    |  float r43 = r39-r42;
73    |  float r44 = r32.z;
74    |  float r45 = r33.x;
75    |  float r46 = r44*r45;
76    |  float r47 = r32.x;
77    |  float r48 = r33.z;
78    |  float r49 = r47*r48;
79    |  float r50 = r46-r49;
80    |  float r51 = r32.x;
81    |  float r52 = r33.y;
82    |  float r53 = r51*r52;
83    |  float r54 = r32.y;
84    |  float r55 = r33.x;
85    |  float r56 = r54*r55;
86    |  float r57 = r53-r56;
87    |  vec3 r58 = vec3(r43,r50,r57);
88    |  float r59 = sin(r31);
89    |  vec3 r60 = vec3(r59);
90    |  vec3 r61 = r58*r60;
91    |  vec3 r62 = r36-r61;
92    |  float r64 = cos(r31);
93    |  float r65 = r63-r64;
94    |  vec3 r66 = vec3(r65);
95    |  vec3 r67 = r33*r66;
96    |  float r68 = dot(r32,r67);
97    |  vec3 r69 = vec3(r68);
98    |  vec3 r70 = r32*r69;
99    |  vec3 r71 = r62+r70;
100    |  float r72 = r71.x;
101    |  float r73 = r71.y;
102    |  float r74 = r71.z;
103    |  vec2 r75 = vec2(r72,r73);
104    |  float r76 = length(r75);
105    |  float r78 = r76-r77;
106    |  vec2 r79 = vec2(r78,r74);
107    |  float r80 = length(r79);
108    |  float r82 = r80-r81;
109    |  float r83 = min(r19,r82);
110    |  float r84 = r0.z;
111    |  float r85 = abs(r84);
112    |  float r86 = r85-r63;
113    |  float r87 = r0.x;
114    |  float r88 = r0.y;
115    |  float r89 = r0.w;
116    |  vec2 r90 = vec2(r87,r88);
117    |  float r91 = length(r90);
118    |  float r93 = r91-r92;
119    |  vec2 r94 = vec2(r86,r93);
120    |  vec2 r95 = vec2(r7);
121    |  vec2 r96 = max(r94,r95);
122    |  float r97 = length(r96);
123    |  float r98 = max(r86,r93);
124    |  float r99 = min(r98,r7);
125    |  float r100 = r97+r99;
126    |  float r101 = -(r100);
127    |  float r102 = max(r83,r101);
128    |  float r103 = r0.x;
129    |  float r105 = r104.x;
130    |  float r106 = r103-r105;
131    |  float r107 = r0.y;
132    |  float r108 = r104.y;
133    |  float r109 = r107-r108;
134    |  float r110 = r0.z;
135    |  float r111 = r104.z;
136    |  float r112 = r110-r111;
137    |  float r113 = r0.w;
138    |  vec4 r114 = vec4(r106,r109,r112,r113);
139    |  float r115 = r114.z;
140    |  float r116 = abs(r115);
141    |  float r118 = r116-r117;
142    |  float r119 = r114.x;
143    |  float r120 = r114.y;
144    |  float r121 = r114.w;
145    |  vec2 r122 = vec2(r119,r120);
146    |  float r123 = length(r122);
147    |  float r124 = r123-r11;
148    |  vec2 r125 = vec2(r118,r124);
149    |  vec2 r126 = vec2(r7);
150    |  vec2 r127 = max(r125,r126);
151    |  float r128 = length(r127);
152    |  float r129 = max(r118,r124);
153    |  float r130 = min(r129,r7);
154    |  float r131 = r128+r130;
155    |  bool r134 =(r102 == r133);
156    |  float r135 = r131-r102;
157    |  float r136 = r3*r135;
158    |  float r137 = r136/r132;
159    |  float r138 = r3+r137;
160    |  float r139 = max(r138,r7);
161    |  float r140 = min(r139,r63);
162    |  float r141 = r63-r140;
163    |  float r142 = r131*r141;
164    |  float r143 = r102*r140;
165    |  float r144 = r142+r143;
166    |  float r145 = r132*r140;
167    |  float r146 = r63-r140;
168    |  float r147 = r145*r146;
169    |  float r148 = r144-r147;
170    |  float r149 =(r134 ? r131 : r148);
171    |  return r149;
172    |}
173    |vec3 colour(vec4 r0)
174    |{
175    |  /* constants */
176    |  vec3 r1 = vec3(0.9573695761995268,0.8355277914608409,0.6870308121546249);
177    |  /* body */
178    |  return r1;
179    |}
180    |const vec3 bbox_min = vec3(-0.375,-0.375,-0.5);
181    |const vec3 bbox_max = vec3(0.75,0.375,0.5);
182    |// ray marching. ro is ray origin, rd is ray direction (unit vector).
183    |// result is (t,r,g,b), where
184    |//  * t is the distance that we marched,
185    |//  * r,g,b is the colour of the distance field at the point we ended up at.
186    |//    (-1,-1,-1) means no object was hit.
187    |vec4 castRay( in vec3 ro, in vec3 rd, float time )
188    |{
189    |    float tmin = 0.0;
190    |    float tmax = ray_max_depth;
191    |
192    |    float t = tmin;
193    |    vec3 c = vec3(-1.0,-1.0,-1.0);
194    |    for (int i=0; i<ray_max_iter; i++) {
195    |        float precis = 0.0005*t;
196    |        vec4 p = vec4(ro+rd*t,time);
197    |        float d = dist(p);
198    |        if (abs(d) < abs(precis)) {
199    |            c = colour(p);
200    |            break;
201    |        }
202    |        t += d;
203    |        if (t > tmax) break;
204    |    }
205    |    return vec4( t, c );
206    |}
207    |vec3 calcNormal( in vec3 pos, float time )
208    |{
209    |    vec2 e = vec2(1.0,-1.0)*0.5773*0.0005;
210    |    return normalize( e.xyy*dist( vec4(pos + e.xyy,time) ) +
211    |                      e.yyx*dist( vec4(pos + e.yyx,time) ) +
212    |                      e.yxy*dist( vec4(pos + e.yxy,time) ) +
213    |                      e.xxx*dist( vec4(pos + e.xxx,time) ) );
214    |}
215    |float calcAO( in vec3 pos, in vec3 nor, float time )
216    |{
217    |    float occ = 0.0;
218    |    float sca = 1.0;
219    |    for( int i=0; i<5; i++ )
220    |    {
221    |        float hr = 0.01 + 0.12*float(i)/4.0;
222    |        vec3 aopos =  nor * hr + pos;
223    |        float dd = dist( vec4(aopos,time) );
224    |        occ += -(dd-hr)*sca;
225    |        sca *= 0.95;
226    |    }
227    |    return clamp( 1.0 - 3.0*occ, 0.0, 1.0 );
228    |}
229    |// in ro: ray origin
230    |// in rd: ray direction
231    |// out: rgb colour
232    |vec3 render( in vec3 ro, in vec3 rd, float time )
233    |{
234    |    //vec3 col = vec3(0.7, 0.9, 1.0) +rd.z*0.8;
235    |    vec3 col = background_colour;
236    |    vec4 res = castRay(ro,rd, time);
237    |    float t = res.x;
238    |    vec3 c = res.yzw;
239    |    if( c.x>=0.0 )
240    |    {
241    |        vec3 pos = ro + t*rd;
242    |        vec3 nor = calcNormal( pos, time );
243    |        vec3 ref = reflect( rd, nor );
244    |
245    |        // material
246    |        col = c;
247    |
248    |        // lighting
249    |        float occ = calcAO( pos, nor, time );
250    |        vec3  lig = normalize( vec3(-0.4, 0.6, 0.7) );
251    |        float amb = clamp( 0.5+0.5*nor.z, 0.0, 1.0 );
252    |        float dif = clamp( dot( nor, lig ), 0.0, 1.0 );
253    |        float bac = clamp( dot( nor, normalize(vec3(-lig.x,lig.y,0.0))), 0.0, 1.0 )*clamp( 1.0-pos.z,0.0,1.0);
254    |        float dom = smoothstep( -0.1, 0.1, ref.z );
255    |        float fre = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 );
256    |        float spe = pow(clamp( dot( ref, lig ), 0.0, 1.0 ),16.0);
257    |
258    |        vec3 lin = vec3(0.0);
259    |        lin += 1.30*dif*vec3(1.00,0.80,0.55);
260    |        lin += 2.00*spe*vec3(1.00,0.90,0.70)*dif;
261    |        lin += 0.40*amb*vec3(0.40,0.60,1.00)*occ;
262    |        lin += 0.50*dom*vec3(0.40,0.60,1.00)*occ;
263    |        lin += 0.50*bac*vec3(0.35,0.35,0.35)*occ;
264    |        lin += 0.25*fre*vec3(1.00,1.00,1.00)*occ;
265    |        vec3 iqcol = col*lin;
266    |
267    |        //col = mix( col, vec3(0.8,0.9,1.0), 1.0-exp( -0.0002*t*t*t ) );
268    |        col = mix(col,iqcol, 0.5);
269    |    }
270    |
271    |    return vec3( clamp(col,0.0,1.0) );
272    |}
273    |// Create a matrix to transform coordinates to look towards a given point.
274    |// * `eye` is the position of the camera.
275    |// * `centre` is the position to look towards.
276    |// * `up` is the 'up' direction.
277    |mat3 look_at(vec3 eye, vec3 centre, vec3 up)
278    |{
279    |    vec3 ww = normalize(centre - eye);
280    |    vec3 uu = normalize(cross(ww, up));
281    |    vec3 vv = normalize(cross(uu, ww));
282    |    return mat3(uu, vv, ww);
283    |}
284    |// Generate a ray direction for ray-casting.
285    |// * `camera` is the camera look-at matrix.
286    |// * `pos` is the screen position, normally in the range -1..1
287    |// * `lens` is the lens length of the camera (encodes field-of-view).
288    |//   0 is very wide, and 2 is a good default.
289    |vec3 ray_direction(mat3 camera, vec2 pos, float lens)
290    |{
291    |    return normalize(camera * vec3(pos, lens));
292    |}
293    |void mainImage( out vec4 fragColour, in vec2 fragCoord )
294    |{
295    |    vec3 col = vec3(0.0);
296    |    const vec3 origin = (bbox_min + bbox_max) / 2.0;
297    |    const vec3 radius = (bbox_max - bbox_min) / 2.0;
298    |    float r = max(radius.x, max(radius.y, radius.z)) / 1.3;
299    |#if AA>1
300    |  for (int m=0; m<AA; ++m)
301    |  for (int n=0; n<AA; ++n) {
302    |    vec2 o = vec2(float(m),float(n)) / float(AA) - 0.5;
303    |#else
304    |    const vec2 o = vec2(0.0);
305    |#endif
306    |    vec2 p = -1.0 + 2.0 * (fragCoord+o) / iResolution.xy;
307    |    p.x *= iResolution.x/iResolution.y;
308    |
309    |#ifdef GLSLVIEWER
310    |    vec3 eye = vec3(u_eye3d.x, -u_eye3d.z, u_eye3d.y)*r + origin;
311    |    vec3 centre = vec3(u_centre3d.x, -u_centre3d.z, u_centre3d.y)*r + origin;
312    |    vec3 up = vec3(u_up3d.x, -u_up3d.z, u_up3d.y);
313    |#else
314    |    vec3 eye = vec3(2.6, -4.5, 3.0);
315    |    vec3 centre = vec3(0.0, 0.0, 0.0);
316    |    vec3 up = vec3(-0.25, 0.433, 0.866);
317    |#endif
318    |    mat3 camera = look_at(eye, centre, up);
319    |    vec3 dir = ray_direction(camera, p, 2.5);
320    |
321    |#if TAA>1
322    |  for (int t=0; t<TAA; ++t) {
323    |    float time = iTime + float(t)/float(TAA)*float(FDUR);
324    |#else
325    |    float time = iTime;
326    |#endif
327    |    col += render( eye, dir, time );
328    |
329    |#if TAA>1
330    |  }
331    |#endif
332    |#if AA>1
333    |  }
334    |#endif
335    |#if AA>1 || TAA>1
336    |    col /= float(AA*AA*TAA);
337    |#endif
338    |
339    |    // convert linear RGB to sRGB
340    |    col = pow(col, vec3(0.454545454545454545));
341    |    fragColour = vec4(col,1.0);
342    |}
343    ";
344  parameters: [
345    {name: "rv_Morph", type: "float", value: 0, label: "Morph", config: {slider:[0,1]}};
346  ];
347}
348