// variant of https://shadertoy.com/view/4stfRX

float i;                                                      // face id

float G( vec3 q ) {
    vec3 a = abs(q);
    return max( abs( i = dot(sin(q),cos(q.yzx)) ),            // gyroid.  Is thickness -.1 or -.3 better ?
                max(a.x,max(a.y,a.z)) -6. );                  // clamped to cube
}

#define R(a) mat2( sin( a + vec4(0,33,11,0)) )                // rotation

void mainImage(out vec4 O, vec2 U) {

    vec3  q = iResolution, e = vec3(1e-3,0,0), N,
          D = vec3(.3*(U+U-q.xy)/q.y, -1),                    // ray direction
          C = iMouse.z > 0. ? 8.*iMouse.xyz/q -4.             // camera control
                          : 3.* cos(.3*iTime + vec3(0,11,0)), // demo mode
         p = 30./q;                                           // marching point along ray
    p.xz *= R(C.x), p.yz *= R(C.y),                           // rotation
    D.xz *= R(C.x), D.yz *= R(C.y);
    O *= 0.;
    float d = 1.;
    for ( O++; O.x > 0. && d > .01 ; O-=.015 )
        q = p,
        d = G(q),
        p += .5*d*D;                                          // step forward = dist to obj

    O *= i>0. ? vec4(1,.9,.9,1) : vec4(.9,.9,1,1);            // face coloring

    N = vec3( G(q+e), G(q+e.yxy), G(q+e.yyx) ) - d ;          // normal
    O.x < 0. ? O = .5*texture(iChannel0, D) :                 // uncomment to display environment
    O *= length( texture(iChannel0, reflect(D,N/length(N) ) ).rgb ); // reflect of environment map

}
