anchor.diff:    return fract(sin(sn) * c);
   }
   
  -float getAngle(vec3 a, vec3 b){
  +float getAngle(vec3 a){
  +  vec3 b = vec3(0.0,0.0,1.0);
     return atan(length(cross(a,b)),a.z);
   }
   
  
positive.code:         oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c);
  }
  
  // GGX microfacet
  vec3 randomNormal(vec3 oNormal, float a, vec3 seed){
    vec2 xi = vec2(rand(seed.xy), rand(seed.zx));
    float phi = 2.0f * M_PI * xi.x;
    float theta = acos(sqrt((1.0f - xi.y)/((a*a - 1.0f) * xi.y + 1.0f)));
    vec3 facet = vec3(cos(phi) * sin(theta), sin(theta) * sin(phi), cos(theta));
    float trans = getAngle(oNormal, vec3(0.0,0.0,1.0));
    return rotationMatrix(cross(oNormal,vec3(0.0,0.0,1.0)),trans) * facet;
  }
  
  //vec3 randomVec(vec3 normal, vec3 seed){
  
negative.code:     if(result.index < 0.0){ emittance[i] = skybox; break; }
      Triangle tri = createTriangle(result.index);
      vec3 weights = barycentricWeights(tri, origin);
      vec2 texCoord = barycentricTexCoord(weights, createTexCoords(result.index)) + 0.5 / vec2(textureSize(atlasTex, 0));
      Material mat = createMaterial(result.index);
      vec3 oNormal = barycentricNormal(weights, createNormals(result.index));
      vec3 incident = ray.dir;
      vec3 normal = randomNormal(oNormal, mat.specular, origin);
      vec3 dir = reflect(ray.dir, normal);
      ray = Ray(origin + normal * EPSILON, dir);
      vec3 texRef =  texture(atlasTex, texCoord).rgb;
      emittance[i] = texRef * getDirectEmmission(ray.origin, oNormal, incident, mat.specular);
      reflectance[i] = texRef;
      if(dot(mat.emittance, vec3(1)) > 0.0 || rand(origin.zy) > albedo(texRef)){break;}
    }
    for(int i=bounces-1; i>=0; i--){
      color = reflectance[i]*color + emittance[i];
  