-
- lowp vec3 color = vec3(0.0);
- lowp vec3 diffuseLight = linear(texture(sDiffuseEnvSampler, n * uYDirection).rgb);
- lowp vec3 specularLight = linear(texture(sSpecularEnvSampler, reflection * uYDirection).rgb);
- // retrieve a scale and bias to F0. See [1], Figure 3
- lowp vec3 brdf = linear(texture(sbrdfLUT, vec2(NdotV, 1.0 - perceptualRoughness)).rgb);
-
- lowp vec3 diffuse = diffuseLight * diffuseColor;
- lowp vec3 specular = specularLight * (specularColor * brdf.x + brdf.y);
- color += (diffuse + specular) * uIblIntensity;
+ lowp vec3 brdf = texture(sbrdfLUT, vec2(NdotV, 1.0 - perceptualRoughness)).rgb;
+ vec3 Fr = max(vec3(1.0 - perceptualRoughness), f0) - f0;
+ vec3 k_S = f0 + Fr * pow(1.0 - NdotV, 5.0);
+ vec3 FssEss = specularWeight * (k_S * brdf.x + brdf.y);
+
+ // Specular Light
+ // uMaxLOD that means mipmap level of specular texture is used for bluring of reflection of specular following roughness.
+ float lod = perceptualRoughness * (uMaxLOD - 1.0);
+ lowp vec3 specularLight = linear(textureLod(sSpecularEnvSampler, reflection * uYDirection, lod).rgb);
+ lowp vec3 specular = specularLight * FssEss;
+
+ // Diffuse Light
+ lowp vec3 diffuseColor = mix(baseColor.rgb, vec3(0), metallic);
+ lowp vec3 irradiance = linear(texture(sDiffuseEnvSampler, n * uYDirection).rgb);
+ float Ems = (1.0 - (brdf.x + brdf.y));
+ vec3 F_avg = specularWeight * (f0 + (1.0 - f0) / 21.0);
+ vec3 FmsEms = Ems * FssEss * F_avg / (1.0 - F_avg * Ems);
+ vec3 k_D = diffuseColor * (1.0 - FssEss + FmsEms);
+ lowp vec3 diffuse = (FmsEms + k_D) * irradiance;
+
+ lowp vec3 color = (diffuse + specular) * uIblIntensity;