anchor.diff:      vec3 diffuseNormal = shading_normal;
   #endif
   
  +#if IBL_INTEGRATION == IBL_INTEGRATION_PREFILTERED_CUBEMAP
       vec3 diffuseIrradiance = diffuseIrradiance(diffuseNormal);
  +#elif IBL_INTEGRATION == IBL_INTEGRATION_IMPORTANCE_SAMPLING
  +    vec3 diffuseIrradiance = isEvaluateDiffuseIBL(pixel, diffuseNormal, shading_view);
  +#endif
       vec3 Fd = pixel.diffuseColor * diffuseIrradiance * (1.0 - E) * diffuseBRDF;
   
       // sheen layer
  
positive.code:     p.anisotropy = 0.0;
  #endif
  
      vec3 clearCoatLobe = isEvaluateIBL(p, clearCoatNormal, shading_view, clearCoatNoV);
      Fr += clearCoatLobe * (specularAO * pixel.clearCoat);
  #endif
  }
  
negative.code:     }
  
      return indirectSpecular;
  }
  
  vec3 isEvaluateDiffuseIBL(const PixelParams pixel, vec3 n, vec3 v) {
      const uint numSamples = uint(IBL_INTEGRATION_IMPORTANCE_SAMPLING_COUNT);
      const float invNumSamples = 1.0 / float(numSamples);
      const vec3 up = vec3(0.0, 0.0, 1.0);
  
      // TODO: for a true anisotropic BRDF, we need a real tangent space
      // tangent space
      mat3 T;
      T[0] = normalize(cross(up, n));
      T[1] = cross(n, T[0]);
      T[2] = n;
  
      // Random rotation around N per pixel
      const vec3 m = vec3(0.06711056, 0.00583715, 52.9829189);
      float a = 2.0 * PI * fract(m.z * fract(dot(gl_FragCoord.xy, m.xy)));
      float c = cos(a);
      float s = sin(a);
      mat3 R;
      R[0] = vec3( c, s, 0);
      R[1] = vec3(-s, c, 0);
      R[2] = vec3( 0, 0, 1);
      T *= R;
  
      float dim = float(textureSize(light_iblSpecular, 0).x);
      float omegaP = (4.0 * PI) / (6.0 * dim * dim);
  
      vec3 indirectDiffuse = vec3(0.0);
      for (uint i = 0u; i < numSamples; i++) {
          vec2 u = hammersley(i);
          vec3 h = T * hemisphereCosSample(u);
  
          // Since anisotropy doesn't work with prefiltering, we use the same "faux" anisotropy
          // we do when we use the prefiltered cubemap
          vec3 l = getReflectedVector(pixel, v, h);
  
          // Compute this sample's contribution to the brdf
          float NoL = saturate(dot(n, l));
          if (NoL > 0.0) {
              // PDF inverse (we must use D_GGX() here, which is used to generate samples)
              float ipdf = PI / NoL;
              // we have to bias the mipLevel (+1) to help with very strong highlights
              float mipLevel = prefilteredImportanceSampling(ipdf, omegaP) + 1.0;
              vec3 L = decodeDataForIBL(textureLod(light_iblSpecular, l, mipLevel));
              indirectDiffuse += L;
          }
      }
  
      return indirectDiffuse * invNumSamples; // we bake 1/PI here, which cancels out
  }
  
  void isEvaluateClearCoatIBL(const PixelParams pixel, float specularAO, inout vec3 Fd, inout vec3 Fr) {
  