Commit: 8e36089e411391243617808413d4d2b550aeb3b3
Author: Clément Foucault
Date:   Fri Aug 4 18:43:02 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB8e36089e411391243617808413d4d2b550aeb3b3

Eevee: LUT generation.

We generate a 3D lut to precompute the btdf intensity.
I decided to use a 64*64*16 (N dot V, ior, roughness) because the btdf varies 
less with roughness than with IOR.
We also remap the ior to better use the space in the LUT.

===================================================================

M       source/blender/draw/CMakeLists.txt
M       source/blender/draw/engines/clay/clay_engine.c
M       source/blender/draw/engines/eevee/eevee_materials.c
A       source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl

===================================================================

diff --git a/source/blender/draw/CMakeLists.txt 
b/source/blender/draw/CMakeLists.txt
index e3a3ac499a1..3293b4d7241 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -155,6 +155,7 @@ 
data_to_c_simple(engines/eevee/shaders/shadow_store_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/shadow_store_geom.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/shadow_store_vert.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/bsdf_lut_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/btdf_lut_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/bsdf_direct_lib.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/bsdf_common_lib.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/irradiance_lib.glsl SRC)
diff --git a/source/blender/draw/engines/clay/clay_engine.c 
b/source/blender/draw/engines/clay/clay_engine.c
index a9192a30412..44178f66563 100644
--- a/source/blender/draw/engines/clay/clay_engine.c
+++ b/source/blender/draw/engines/clay/clay_engine.c
@@ -326,7 +326,7 @@ static struct GPUTexture *create_jitter_texture(int 
num_samples)
                jitter[i][2] = bn * num_samples_inv;
        }
 
-       UNUSED_VARS(bsdf_split_sum_ggx, ltc_mag_ggx, ltc_mat_ggx);
+       UNUSED_VARS(bsdf_split_sum_ggx, btdf_split_sum_ggx, ltc_mag_ggx, 
ltc_mat_ggx);
 
        return DRW_texture_create_2D(64, 64, DRW_TEX_RGB_16, DRW_TEX_FILTER | 
DRW_TEX_WRAP, &jitter[0][0]);
 }
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c 
b/source/blender/draw/engines/eevee/eevee_materials.c
index 046a7ea1367..65e91a38053 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -90,6 +90,7 @@ extern char datatoc_default_frag_glsl[];
 extern char datatoc_default_world_frag_glsl[];
 extern char datatoc_ltc_lib_glsl[];
 extern char datatoc_bsdf_lut_frag_glsl[];
+extern char datatoc_btdf_lut_frag_glsl[];
 extern char datatoc_bsdf_common_lib_glsl[];
 extern char datatoc_bsdf_direct_lib_glsl[];
 extern char datatoc_bsdf_sampling_lib_glsl[];
@@ -169,8 +170,97 @@ static struct GPUTexture *create_ggx_lut_texture(int 
UNUSED(w), int UNUSED(h))
 
        return tex;
 }
-#endif
 
+static struct GPUTexture *create_ggx_refraction_lut_texture(int w, int h)
+{
+       struct GPUTexture *tex;
+       struct GPUTexture *hammersley = create_hammersley_sample_texture(8192);
+       struct GPUFrameBuffer *fb = NULL;
+       static float samples_ct = 8192.0f;
+       static float a2 = 0.0f;
+       static float inv_samples_ct = 1.0f / 8192.0f;
+
+       char *frag_str = NULL;
+
+       DynStr *ds_vert = BLI_dynstr_new();
+       BLI_dynstr_append(ds_vert, datatoc_bsdf_common_lib_glsl);
+       BLI_dynstr_append(ds_vert, datatoc_bsdf_sampling_lib_glsl);
+       BLI_dynstr_append(ds_vert, datatoc_btdf_lut_frag_glsl);
+       frag_str = BLI_dynstr_get_cstring(ds_vert);
+       BLI_dynstr_free(ds_vert);
+
+       struct GPUShader *sh = DRW_shader_create_fullscreen(frag_str,
+               "#define HAMMERSLEY_SIZE 8192\n"
+               "#define BRDF_LUT_SIZE 64\n"
+               "#define NOISE_SIZE 64\n"
+               "#define LUT_SIZE 64\n");
+
+       MEM_freeN(frag_str);
+
+       DRWPass *pass = DRW_pass_create("LightProbe Filtering", 
DRW_STATE_WRITE_COLOR);
+       DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
+       DRW_shgroup_uniform_float(grp, "a2", &a2, 1);
+       DRW_shgroup_uniform_float(grp, "sampleCount", &samples_ct, 1);
+       DRW_shgroup_uniform_float(grp, "invSampleCount", &inv_samples_ct, 1);
+       DRW_shgroup_uniform_texture(grp, "texHammersley", hammersley);
+       DRW_shgroup_uniform_texture(grp, "utilTex", e_data.util_tex);
+
+       struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
+       DRW_shgroup_call_add(grp, geom, NULL);
+
+       float *texels = MEM_mallocN(sizeof(float[2]) * w * h, "lut");
+
+       tex = DRW_texture_create_2D(w, h, DRW_TEX_R_16, DRW_TEX_FILTER, (float 
*)texels);
+
+       DRWFboTexture tex_filter = {&tex, DRW_TEX_R_16, DRW_TEX_FILTER};
+       DRW_framebuffer_init(&fb, &draw_engine_eevee_type, w, h, &tex_filter, 
1);
+
+       DRW_framebuffer_bind(fb);
+
+       float *data = MEM_mallocN(sizeof(float[3]) * w * h, "lut");
+
+       float inc = 1.0f / 31.0f;
+       float roughness = 1e-8f - inc;
+       FILE *f = BLI_fopen("btdf_split_sum_ggx.h", "w");
+       fprintf(f, "static float btdf_split_sum_ggx[32][64 * 64] = {\n");
+       do {
+               roughness += inc;
+               CLAMP(roughness, 1e-4f, 1.0f);
+               a2 = powf(roughness, 4.0f);
+               DRW_draw_pass(pass);
+
+               DRW_framebuffer_read_data(0, 0, w, h, 3, 0, data);
+
+       #if 1
+               fprintf(f, "\t{\n\t\t");
+               for (int i = 0; i < w*h * 3; i+=3) {
+                       fprintf(f, "%ff,", data[i]);
+                       if (((i/3)+1) % 12 == 0) fprintf(f, "\n\t\t");
+                       else fprintf(f, " ");
+               }
+               fprintf(f, "\n\t},\n");
+       #else
+               for (int i = 0; i < w*h * 3; i+=3) {
+                       if (data[i] < 0.01) printf(" ");
+                       else if (data[i] < 0.3) printf(".");
+                       else if (data[i] < 0.6) printf("+");
+                       else if (data[i] < 0.9) printf("%%");
+                       else printf("#");
+                       if ((i/3+1) % 64 == 0) printf("\n");
+               }
+       #endif
+
+       } while (roughness < 1.0f);
+       fprintf(f, "\n};\n");
+
+       fclose(f);
+
+       MEM_freeN(texels);
+       MEM_freeN(data);
+
+       return tex;
+}
+#endif
 /* XXX TODO define all shared resources in a shared place without duplication 
*/
 struct GPUTexture *EEVEE_materials_get_util_tex(void)
 {
diff --git a/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl 
b/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl
new file mode 100644
index 00000000000..2c604d69641
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl
@@ -0,0 +1,59 @@
+
+uniform float a2;
+
+out vec4 FragColor;
+
+void main() {
+       vec3 N, T, B, V;
+
+       float x = gl_FragCoord.x / BRDF_LUT_SIZE;
+       float y = gl_FragCoord.y / BRDF_LUT_SIZE;
+       /* There is little variation if ior > 1.0 so we
+        * maximize LUT precision for ior < 1.0 */
+       x = x * 1.1;
+       float ior = (x > 1.0) ? ior_from_f0((x-1.0) * 10.0) : sqrt(x);
+       float NV = (1.0 - (clamp(y, 1e-4, 0.9999)));
+
+       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);
+
+       setup_noise();
+
+       /* Integrating BTDF */
+       float btdf_accum = 0.0;
+       for (float i = 0.0; i < sampleCount; i++) {
+               vec3 H = sample_ggx(i, a2, N, T, B); /* Microfacet normal */
+
+               float VH = dot(V, H);
+
+               /* Check if there is total internal reflections. */
+               float c = abs(VH);
+               float g = ior * ior - 1.0 + c * c;
+
+               float eta = 1.0/ior;
+               if (dot(H, V) < 0.0) {
+                       H = -H;
+                       eta = ior;
+               }
+
+               vec3 L = refract(-V, H, eta);
+               float NL = -dot(N, L);
+
+               if ((NL > 0.0) && (g > 0.0)) {
+                       float LH = dot(L, H);
+
+                       float G1_l = NL * 2.0 / G1_Smith_GGX(NL, a2); /* 
Balancing the adjustments made in G1_Smith */
+
+                       /* btdf = abs(VH*LH) * (ior*ior) * D * G(V) * G(L) / 
(Ht2 * NV)
+                        * pdf = (VH * abs(LH)) * (ior*ior) * D * G(V) / (Ht2 * 
NV) */
+                       float btdf = G1_l * abs(VH*LH) / (VH * abs(LH));
+
+                       btdf_accum += btdf;
+               }
+       }
+       btdf_accum /= sampleCount;
+
+       FragColor = vec4(btdf_accum, 0.0, 0.0, 1.0);
+}
\ No newline at end of file

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to