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>2017-08-04 19:43:02 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-08-10 16:43:47 +0300
commit8e36089e411391243617808413d4d2b550aeb3b3 (patch)
treed6fe9c02d90271aab0fc98a27325d417d88af0f5 /source/blender/draw/engines/eevee
parent4ec58659adaf693994e09dda00bcaa8f58674adb (diff)
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.
Diffstat (limited to 'source/blender/draw/engines/eevee')
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c92
-rw-r--r--source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl59
2 files changed, 150 insertions, 1 deletions
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