anchor.diff:    return sqrt(dot(vec3(0.299, 0.587, 0.114) * color*color, vec3(1)));
   }
   
  -vec3 getDirectEmmission(Ray ray, Triangle tri, Hit result, vec3 normal){
  +vec3 getDirectEmmission(vec3 origin, vec3 normal, vec3 incident, float specular){
     vec3 color = vec3(0);
  -  vec3 origin = ray.origin + ray.dir * result.t;
     vec2 range = lightRanges[uint(rand(coords.xy + origin.xy) * numLights)];
     Triangle light = randomLight(origin.xz, range);
     vec3 lightPoint = randomPointOnTriangle(light, origin.zy);
     vec3 dir = normalize(lightPoint - origin);
  -  ray = Ray(origin + normal*EPSILON, dir);
  +  Ray ray = Ray(origin, dir);
     Hit shadow = traverseTree(ray);
     vec3 tspan = ray.dir * shadow.t;
     vec3 span = lightPoint - ray.origin;
  +  float weight = directLightWeight(normal, incident, normalize(span), specular);
     if(abs(shadow.t - length(span)) < EPSILON * 10.0){
       Material mat = createMaterial(shadow.index);
       vec3 lightNormal = barycentricNormal(barycentricWeights(createTriangle(shadow.index), origin), createNormals(shadow.index));
  
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];
  