Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2021-02-13 20:50:09 +0300
committerClément Foucault <foucault.clem@gmail.com>2021-02-13 20:52:19 +0300
commit83ac8628c490eda4fa5237b7a4256bc670dc0682 (patch)
tree89563a6d46dcea4ea51b70d23b3a73e7637161a6 /source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl
parent06492fd61984c1a92fb1f93d30028de97ead451f (diff)
EEVEE: Update LUT GGX generation shader
This modifies the principled BSDF and the Glass BSDF which now have better fit to multiscatter GGX. Code to generate the LUT have been updated and can run at runtime. The refraction LUT has been changed to have the critical angle always centered around one pixel so that interpolation can be mitigated. Offline LUT data will be updated in another commit This simplify the BTDF retreival removing the manual clean cut at low roughness. This maximize the precision of the LUT by scalling the sides by the critical angle. I also touched the ior > 1.0 approximation to be smoother. Also incluse some cleanup of bsdf_sampling.glsl
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl')
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl75
1 files changed, 42 insertions, 33 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl
index 1e051994693..46ea8b747c8 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl
@@ -1,48 +1,57 @@
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
-out vec4 FragColor;
+uniform float sampleCount;
+
+out vec2 FragColor;
void main()
{
- vec3 N, T, B, V;
-
- float NV = (1.0 - (clamp(gl_FragCoord.y / LUT_SIZE, 1e-4, 0.9999)));
- float sqrtRoughness = clamp(gl_FragCoord.x / LUT_SIZE, 1e-4, 0.9999);
- float a = sqrtRoughness * sqrtRoughness;
- float a2 = a * a;
+ /* Make sure coordinates are covering the whole [0..1] range at texel center. */
+ float y = floor(gl_FragCoord.y) / (LUT_SIZE - 1);
+ float x = floor(gl_FragCoord.x) / (LUT_SIZE - 1);
- N = vec3(0.0, 0.0, 1.0);
- T = vec3(1.0, 0.0, 0.0);
- B = vec3(0.0, 1.0, 0.0);
- V = vec3(sqrt(1.0 - NV * NV), 0.0, NV);
+ float NV = clamp(1.0 - y * y, 1e-4, 0.9999);
+ float a = x * x;
+ float a2 = clamp(a * a, 1e-4, 0.9999);
- setup_noise();
+ vec3 V = vec3(sqrt(1.0 - NV * NV), 0.0, NV);
/* Integrating BRDF */
float brdf_accum = 0.0;
float fresnel_accum = 0.0;
- for (float i = 0; i < sampleCount; i++) {
- vec3 H = sample_ggx(i, a2, N, T, B); /* Microfacet normal */
- vec3 L = -reflect(V, H);
- float NL = L.z;
-
- if (NL > 0.0) {
- float NH = max(H.z, 0.0);
- float VH = max(dot(V, H), 0.0);
-
- float G1_v = G1_Smith_GGX(NV, a2);
- float G1_l = G1_Smith_GGX(NL, a2);
- float G_smith = 4.0 * NV * NL / (G1_v * G1_l); /* See G1_Smith_GGX for explanations. */
-
- float brdf = (G_smith * VH) / (NH * NV);
- float Fc = pow(1.0 - VH, 5.0);
-
- brdf_accum += (1.0 - Fc) * brdf;
- fresnel_accum += Fc * brdf;
+ for (float j = 0.0; j < sampleCount; j++) {
+ for (float i = 0.0; i < sampleCount; i++) {
+ vec3 Xi = (vec3(i, j, 0.0) + 0.5) / sampleCount;
+ Xi.yz = vec2(cos(Xi.y * M_2PI), sin(Xi.y * M_2PI));
+
+ vec3 H = sample_ggx(Xi, a2); /* Microfacet normal */
+ vec3 L = -reflect(V, H);
+ float NL = L.z;
+
+ if (NL > 0.0) {
+ float NH = max(H.z, 0.0);
+ float VH = max(dot(V, H), 0.0);
+
+ float G1_v = G1_Smith_GGX(NV, a2);
+ float G1_l = G1_Smith_GGX(NL, a2);
+ float G_smith = 4.0 * NV * NL / (G1_v * G1_l); /* See G1_Smith_GGX for explanations. */
+
+ float brdf = (G_smith * VH) / (NH * NV);
+
+ /* Follow maximum specular value for principled bsdf. */
+ const float specular = 1.0;
+ const float eta = (2.0 / (1.0 - sqrt(0.08 * specular))) - 1.0;
+ float fresnel = F_eta(eta, VH);
+ float Fc = F_color_blend(eta, fresnel, vec3(0)).r;
+
+ brdf_accum += (1.0 - Fc) * brdf;
+ fresnel_accum += Fc * brdf;
+ }
}
}
- brdf_accum /= sampleCount;
- fresnel_accum /= sampleCount;
+ brdf_accum /= sampleCount * sampleCount;
+ fresnel_accum /= sampleCount * sampleCount;
- FragColor = vec4(brdf_accum, fresnel_accum, 0.0, 1.0);
+ FragColor = vec2(brdf_accum, fresnel_accum);
}