From 4ec58659adaf693994e09dda00bcaa8f58674adb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 4 Aug 2017 18:30:13 +0200 Subject: Eevee: Add precomputed BTDF LUT. --- source/blender/draw/engines/eevee/eevee_materials.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'source/blender/draw/engines/eevee/eevee_materials.c') diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 8cd9dd4829d..046a7ea1367 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -358,7 +358,7 @@ void EEVEE_materials_init(EEVEE_StorageList *stl) MEM_freeN(frag_str); /* Textures */ - const int layers = 3; + const int layers = 3 + 16; float (*texels)[4] = MEM_mallocN(sizeof(float[4]) * 64 * 64 * layers, "utils texels"); float (*texels_layer)[4] = texels; @@ -382,6 +382,16 @@ void EEVEE_materials_init(EEVEE_StorageList *stl) texels_layer[i][3] = sinf(blue_noise[i][1] * 2.0 * M_PI); } + for (int j = 0; j < 16; ++j) { + texels_layer += 64 * 64; + for (int i = 0; i < 64 * 64; i++) { + texels_layer[i][0] = btdf_split_sum_ggx[j*2][i]; + texels_layer[i][1] = btdf_split_sum_ggx[j*2][i]; + texels_layer[i][2] = btdf_split_sum_ggx[j*2][i]; + texels_layer[i][3] = btdf_split_sum_ggx[j*2][i]; + } + } + e_data.util_tex = DRW_texture_create_2D_array(64, 64, layers, DRW_TEX_RGBA_16, DRW_TEX_FILTER | DRW_TEX_WRAP, (float *)texels); MEM_freeN(texels); } -- cgit v1.2.3 From 8e36089e411391243617808413d4d2b550aeb3b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 4 Aug 2017 18:43:02 +0200 Subject: 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. --- .../blender/draw/engines/eevee/eevee_materials.c | 92 +++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) (limited to 'source/blender/draw/engines/eevee/eevee_materials.c') 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) { -- cgit v1.2.3 From d16342e5fd1f51c01bc1f9becc6ec0704d783de8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 9 Aug 2017 16:54:18 +0200 Subject: Eevee: Add Screen Space Refraction. For the moment the only way to enable this is to: - enable Screen Space REFLECTIONS. - enable Screen Space Refraction in the SSR parameters. - enable Screen Space Refraction in the material tab. --- .../blender/draw/engines/eevee/eevee_materials.c | 51 +++++++++++++++++----- 1 file changed, 39 insertions(+), 12 deletions(-) (limited to 'source/blender/draw/engines/eevee/eevee_materials.c') diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 65e91a38053..b961591178a 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -98,6 +98,8 @@ extern char datatoc_irradiance_lib_glsl[]; extern char datatoc_octahedron_lib_glsl[]; extern char datatoc_lit_surface_frag_glsl[]; extern char datatoc_lit_surface_vert_glsl[]; +extern char datatoc_raytrace_lib_glsl[]; +extern char datatoc_ssr_lib_glsl[]; extern char datatoc_shadow_vert_glsl[]; extern char datatoc_shadow_geom_glsl[]; extern char datatoc_lightprobe_geom_glsl[]; @@ -307,6 +309,9 @@ static char *eevee_get_defines(int options) if ((options & VAR_MAT_MULT) != 0) { BLI_dynstr_appendf(ds, "#define USE_MULTIPLY\n"); } + if ((options & VAR_MAT_REFRACT) != 0) { + BLI_dynstr_appendf(ds, "#define USE_REFRACTION\n"); + } str = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); @@ -346,7 +351,9 @@ static char *eevee_get_volume_defines(int options) /** * ssr_id can be null to disable ssr contribution. **/ -static void add_standard_uniforms(DRWShadingGroup *shgrp, EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, int *ssr_id) +static void add_standard_uniforms( + DRWShadingGroup *shgrp, EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, + int *ssr_id, float *refract_thickness) { if (ssr_id == NULL) { static int no_ssr = -1.0f; @@ -372,9 +379,20 @@ static void add_standard_uniforms(DRWShadingGroup *shgrp, EEVEE_SceneLayerData * DRW_shgroup_uniform_buffer(shgrp, "shadowCubes", &sldata->shadow_depth_cube_pool); DRW_shgroup_uniform_buffer(shgrp, "shadowCascades", &sldata->shadow_depth_cascade_pool); DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1); + if (vedata->stl->effects->use_ao || refract_thickness) { + DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float *)vedata->stl->g_data->viewvecs, 2); + DRW_shgroup_uniform_buffer(shgrp, "maxzBuffer", &vedata->txl->maxzbuffer); + } + if (refract_thickness) { + DRW_shgroup_uniform_buffer(shgrp, "colorBuffer", &vedata->txl->refract_color); + DRW_shgroup_uniform_float(shgrp, "refractionThickness", refract_thickness, 1); + DRW_shgroup_uniform_vec4(shgrp, "ssrParameters", &vedata->stl->effects->ssr_quality, 1); + DRW_shgroup_uniform_float(shgrp, "borderFadeFactor", &vedata->stl->effects->ssr_border_fac, 1); + DRW_shgroup_uniform_float(shgrp, "maxRoughness", &vedata->stl->effects->ssr_max_roughness, 1); + DRW_shgroup_uniform_vec2(shgrp, "mipRatio[0]", (float *)vedata->stl->g_data->mip_ratio, 10); + DRW_shgroup_uniform_int(shgrp, "rayCount", &vedata->stl->effects->ssr_ray_count, 1); + } if (vedata->stl->effects->use_ao) { - DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float *)&vedata->stl->g_data->viewvecs, 2); - DRW_shgroup_uniform_buffer(shgrp, "minMaxDepthTex", &vedata->txl->maxzbuffer); DRW_shgroup_uniform_vec3(shgrp, "aoParameters", &vedata->stl->effects->ao_dist, 1); } } @@ -403,7 +421,10 @@ void EEVEE_materials_init(EEVEE_StorageList *stl) /* Shaders */ DynStr *ds_frag = BLI_dynstr_new(); BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl); + BLI_dynstr_append(ds_frag, datatoc_bsdf_sampling_lib_glsl); BLI_dynstr_append(ds_frag, datatoc_ambient_occlusion_lib_glsl); + BLI_dynstr_append(ds_frag, datatoc_raytrace_lib_glsl); + BLI_dynstr_append(ds_frag, datatoc_ssr_lib_glsl); BLI_dynstr_append(ds_frag, datatoc_octahedron_lib_glsl); BLI_dynstr_append(ds_frag, datatoc_irradiance_lib_glsl); BLI_dynstr_append(ds_frag, datatoc_lightprobe_lib_glsl); @@ -591,7 +612,8 @@ struct GPUMaterial *EEVEE_material_world_volume_get( struct GPUMaterial *EEVEE_material_mesh_get( struct Scene *scene, Material *ma, - bool use_ao, bool use_bent_normals, bool use_blend, bool use_multiply) + bool use_ao, bool use_bent_normals, bool use_blend, + bool use_multiply, bool use_refract) { const void *engine = &DRW_engine_viewport_eevee_type; int options = VAR_MAT_MESH; @@ -600,6 +622,7 @@ struct GPUMaterial *EEVEE_material_mesh_get( if (use_bent_normals) options |= VAR_MAT_BENT; if (use_blend) options |= VAR_MAT_BLEND; if (use_multiply) options |= VAR_MAT_MULT; + if (use_refract) options |= VAR_MAT_REFRACT; GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine, options); if (mat) { @@ -710,7 +733,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_create( } DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], pass); - add_standard_uniforms(shgrp, sldata, vedata, &ssr_id); + add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL); return shgrp; } @@ -740,7 +763,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get( vedata->psl->default_pass[options] = DRW_pass_create("Default Lit Pass", state); DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]); - add_standard_uniforms(shgrp, sldata, vedata, &ssr_id); + add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL); } return DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]); @@ -884,7 +907,7 @@ static void material_opaque( /* This will have been created already, just perform a lookup. */ *gpumat = (use_gpumat) ? EEVEE_material_mesh_get( - scene, ma, stl->effects->use_ao, stl->effects->use_bent_normals, false, false) : NULL; + scene, ma, stl->effects->use_ao, stl->effects->use_bent_normals, false, false, false) : NULL; *gpumat_depth = (use_gpumat) ? EEVEE_material_mesh_depth_get( scene, ma, (ma->blend_method == MA_BM_HASHED), false) : NULL; return; @@ -893,13 +916,13 @@ static void material_opaque( if (use_gpumat) { /* Shading */ *gpumat = EEVEE_material_mesh_get(scene, ma, - stl->effects->use_ao, stl->effects->use_bent_normals, false, false); + stl->effects->use_ao, stl->effects->use_bent_normals, false, false, false); *shgrp = DRW_shgroup_material_create(*gpumat, psl->material_pass); if (*shgrp) { static int ssr_id; ssr_id = (stl->effects->use_ssr) ? 0 : -1; - add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id); + add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, NULL); } else { /* Shader failed : pink color */ @@ -960,6 +983,8 @@ static void material_transparent( EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl; EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl; + const bool use_refract = ((ma->blend_flag & MA_BL_REFRACTION) != 0) && ((stl->effects->enabled_effects & EFFECT_REFRACT) != 0); + float *color_p = &ma->r; float *metal_p = &ma->ray_mirror; float *spec_p = &ma->spec; @@ -969,12 +994,14 @@ static void material_transparent( /* Shading */ *gpumat = EEVEE_material_mesh_get(scene, ma, stl->effects->use_ao, stl->effects->use_bent_normals, - true, (ma->blend_method == MA_BM_MULTIPLY)); + true, (ma->blend_method == MA_BM_MULTIPLY), use_refract); *shgrp = DRW_shgroup_material_create(*gpumat, psl->transparent_pass); if (*shgrp) { static int ssr_id = -1; /* TODO transparent SSR */ - add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id); + static float refract_thickness = 0.0f; /* TODO Param */ + add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, + (use_refract) ? &refract_thickness : NULL); } else { /* Shader failed : pink color */ @@ -1208,7 +1235,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl shgrp = DRW_shgroup_material_create(gpumat, psl->material_pass); if (shgrp) { - add_standard_uniforms(shgrp, sldata, vedata, NULL); + add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL); BLI_ghash_insert(material_hash, ma, shgrp); -- cgit v1.2.3 From 7641f92710a09ea089748896bbad0bf5383ba349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 9 Aug 2017 23:48:42 +0200 Subject: Eevee: Refraction: Make it available for opaque materials. Theses Materials are rendered after the SSR pass. The only difference with previous method is that they have a depth prepass (less overdraw) and are not sorted. --- .../blender/draw/engines/eevee/eevee_materials.c | 55 ++++++++++++++++++---- 1 file changed, 46 insertions(+), 9 deletions(-) (limited to 'source/blender/draw/engines/eevee/eevee_materials.c') diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index b961591178a..cf27cba0b1a 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -854,6 +854,29 @@ void EEVEE_materials_cache_init(EEVEE_Data *vedata) psl->material_pass = DRW_pass_create("Material Shader Pass", state); } + { + DRWState state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_WIRE; + psl->refract_depth_pass = DRW_pass_create("Refract Depth Pass", state); + stl->g_data->refract_depth_shgrp = DRW_shgroup_create(e_data.default_prepass_sh, psl->refract_depth_pass); + + state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK; + psl->refract_depth_pass_cull = DRW_pass_create("Refract Depth Pass Cull", state); + stl->g_data->refract_depth_shgrp_cull = DRW_shgroup_create(e_data.default_prepass_sh, psl->refract_depth_pass_cull); + + state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE; + psl->refract_depth_pass_clip = DRW_pass_create("Refract Depth Pass Clip", state); + stl->g_data->refract_depth_shgrp_clip = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->refract_depth_pass_clip); + + state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CLIP_PLANES | DRW_STATE_CULL_BACK; + psl->refract_depth_pass_clip_cull = DRW_pass_create("Refract Depth Pass Cull Clip", state); + stl->g_data->refract_depth_shgrp_clip_cull = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->refract_depth_pass_clip_cull); + } + + { + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE; + psl->refract_pass = DRW_pass_create("Opaque Refraction Pass", state); + } + { DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE; psl->transparent_pass = DRW_pass_create("Material Transparent Pass", state); @@ -897,6 +920,7 @@ static void material_opaque( float *rough_p = &ma->gloss_mir; const bool use_gpumat = (ma->use_nodes && ma->nodetree); + const bool use_refract = ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) && ((stl->effects->enabled_effects & EFFECT_REFRACT) != 0); EeveeMaterialShadingGroups *emsg = BLI_ghash_lookup(material_hash, (const void *)ma); @@ -907,7 +931,7 @@ static void material_opaque( /* This will have been created already, just perform a lookup. */ *gpumat = (use_gpumat) ? EEVEE_material_mesh_get( - scene, ma, stl->effects->use_ao, stl->effects->use_bent_normals, false, false, false) : NULL; + scene, ma, stl->effects->use_ao, stl->effects->use_bent_normals, false, false, use_refract) : NULL; *gpumat_depth = (use_gpumat) ? EEVEE_material_mesh_depth_get( scene, ma, (ma->blend_method == MA_BM_HASHED), false) : NULL; return; @@ -916,13 +940,14 @@ static void material_opaque( if (use_gpumat) { /* Shading */ *gpumat = EEVEE_material_mesh_get(scene, ma, - stl->effects->use_ao, stl->effects->use_bent_normals, false, false, false); + stl->effects->use_ao, stl->effects->use_bent_normals, false, false, use_refract); - *shgrp = DRW_shgroup_material_create(*gpumat, psl->material_pass); + *shgrp = DRW_shgroup_material_create(*gpumat, use_refract ? psl->refract_pass : psl->material_pass); if (*shgrp) { static int ssr_id; + static float refract_thickness = 0.0f; /* TODO Param */ ssr_id = (stl->effects->use_ssr) ? 0 : -1; - add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, NULL); + add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, (use_refract) ? &refract_thickness : NULL); } else { /* Shader failed : pink color */ @@ -939,8 +964,14 @@ static void material_opaque( *gpumat_depth = EEVEE_material_mesh_depth_get(scene, ma, (ma->blend_method == MA_BM_HASHED), false); - *shgrp_depth = DRW_shgroup_material_create(*gpumat_depth, do_cull ? psl->depth_pass_cull : psl->depth_pass); - *shgrp_depth_clip = DRW_shgroup_material_create(*gpumat_depth, do_cull ? psl->depth_pass_clip_cull : psl->depth_pass_clip); + if (use_refract) { + *shgrp_depth = DRW_shgroup_material_create(*gpumat_depth, (do_cull) ? psl->refract_depth_pass_cull : psl->refract_depth_pass); + *shgrp_depth_clip = DRW_shgroup_material_create(*gpumat_depth, (do_cull) ? psl->refract_depth_pass_clip_cull : psl->refract_depth_pass_clip); + } + else { + *shgrp_depth = DRW_shgroup_material_create(*gpumat_depth, (do_cull) ? psl->depth_pass_cull : psl->depth_pass); + *shgrp_depth_clip = DRW_shgroup_material_create(*gpumat_depth, (do_cull) ? psl->depth_pass_clip_cull : psl->depth_pass_clip); + } if (*shgrp != NULL) { if (ma->blend_method == MA_BM_CLIP) { @@ -963,8 +994,14 @@ static void material_opaque( /* Fallback default depth prepass */ if (*shgrp_depth == NULL) { - *shgrp_depth = do_cull ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp; - *shgrp_depth_clip = do_cull ? stl->g_data->depth_shgrp_clip_cull : stl->g_data->depth_shgrp_clip; + if (use_refract) { + *shgrp_depth = (do_cull) ? stl->g_data->refract_depth_shgrp_cull : stl->g_data->refract_depth_shgrp; + *shgrp_depth_clip = (do_cull) ? stl->g_data->refract_depth_shgrp_clip_cull : stl->g_data->refract_depth_shgrp_clip; + } + else { + *shgrp_depth = (do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp; + *shgrp_depth_clip = (do_cull) ? stl->g_data->depth_shgrp_clip_cull : stl->g_data->depth_shgrp_clip; + } } emsg = MEM_mallocN(sizeof("EeveeMaterialShadingGroups"), "EeveeMaterialShadingGroups"); @@ -983,7 +1020,7 @@ static void material_transparent( EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl; EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl; - const bool use_refract = ((ma->blend_flag & MA_BL_REFRACTION) != 0) && ((stl->effects->enabled_effects & EFFECT_REFRACT) != 0); + const bool use_refract = ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) && ((stl->effects->enabled_effects & EFFECT_REFRACT) != 0); float *color_p = &ma->r; float *metal_p = &ma->ray_mirror; -- cgit v1.2.3 From 6e2f17ea02be5caa9eee8a68ccd558474030b29a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 10 Aug 2017 15:43:15 +0200 Subject: Eevee: Refraction: Add "thickness" parameter. This enables to fake a second refraction event. This is great to simulate thin planar objects such as glass panels. --- .../blender/draw/engines/eevee/eevee_materials.c | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'source/blender/draw/engines/eevee/eevee_materials.c') diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index cf27cba0b1a..517d7780719 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -353,7 +353,7 @@ static char *eevee_get_volume_defines(int options) **/ static void add_standard_uniforms( DRWShadingGroup *shgrp, EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, - int *ssr_id, float *refract_thickness) + int *ssr_id, float *refract_depth, bool use_ssrefraction) { if (ssr_id == NULL) { static int no_ssr = -1.0f; @@ -379,13 +379,15 @@ static void add_standard_uniforms( DRW_shgroup_uniform_buffer(shgrp, "shadowCubes", &sldata->shadow_depth_cube_pool); DRW_shgroup_uniform_buffer(shgrp, "shadowCascades", &sldata->shadow_depth_cascade_pool); DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1); - if (vedata->stl->effects->use_ao || refract_thickness) { + if (refract_depth != NULL) { + DRW_shgroup_uniform_float(shgrp, "refractionDepth", refract_depth, 1); + } + if (vedata->stl->effects->use_ao || use_ssrefraction) { DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float *)vedata->stl->g_data->viewvecs, 2); DRW_shgroup_uniform_buffer(shgrp, "maxzBuffer", &vedata->txl->maxzbuffer); } - if (refract_thickness) { + if (use_ssrefraction) { DRW_shgroup_uniform_buffer(shgrp, "colorBuffer", &vedata->txl->refract_color); - DRW_shgroup_uniform_float(shgrp, "refractionThickness", refract_thickness, 1); DRW_shgroup_uniform_vec4(shgrp, "ssrParameters", &vedata->stl->effects->ssr_quality, 1); DRW_shgroup_uniform_float(shgrp, "borderFadeFactor", &vedata->stl->effects->ssr_border_fac, 1); DRW_shgroup_uniform_float(shgrp, "maxRoughness", &vedata->stl->effects->ssr_max_roughness, 1); @@ -733,7 +735,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_create( } DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], pass); - add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL); + add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false); return shgrp; } @@ -763,7 +765,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get( vedata->psl->default_pass[options] = DRW_pass_create("Default Lit Pass", state); DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]); - add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL); + add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false); } return DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]); @@ -944,10 +946,10 @@ static void material_opaque( *shgrp = DRW_shgroup_material_create(*gpumat, use_refract ? psl->refract_pass : psl->material_pass); if (*shgrp) { - static int ssr_id; - static float refract_thickness = 0.0f; /* TODO Param */ - ssr_id = (stl->effects->use_ssr) ? 0 : -1; - add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, (use_refract) ? &refract_thickness : NULL); + static int no_ssr = -1; + static int first_ssr = 0; + int *ssr_id = (stl->effects->use_ssr && !use_refract) ? &first_ssr : &no_ssr; + add_standard_uniforms(*shgrp, sldata, vedata, ssr_id, &ma->refract_depth, use_refract); } else { /* Shader failed : pink color */ @@ -1036,9 +1038,7 @@ static void material_transparent( *shgrp = DRW_shgroup_material_create(*gpumat, psl->transparent_pass); if (*shgrp) { static int ssr_id = -1; /* TODO transparent SSR */ - static float refract_thickness = 0.0f; /* TODO Param */ - add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, - (use_refract) ? &refract_thickness : NULL); + add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, &ma->refract_depth, use_refract); } else { /* Shader failed : pink color */ @@ -1272,7 +1272,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl shgrp = DRW_shgroup_material_create(gpumat, psl->material_pass); if (shgrp) { - add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL); + add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL, false); BLI_ghash_insert(material_hash, ma, shgrp); -- cgit v1.2.3 From e3468d7ec2ce4be2ffc3e22bf86a6ace143c2f16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Sun, 13 Aug 2017 14:30:24 +0200 Subject: Eevee: Optimize and improve GTAO Horizon search This fix a bug when occluder are on the edge of the screen and occludes more than they should. Grouped the texture fetches together and clamp the ray at the border of the screen. Also add a few util functions. --- source/blender/draw/engines/eevee/eevee_materials.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/draw/engines/eevee/eevee_materials.c') diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 517d7780719..e8bf461e91f 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -385,13 +385,13 @@ static void add_standard_uniforms( if (vedata->stl->effects->use_ao || use_ssrefraction) { DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float *)vedata->stl->g_data->viewvecs, 2); DRW_shgroup_uniform_buffer(shgrp, "maxzBuffer", &vedata->txl->maxzbuffer); + DRW_shgroup_uniform_vec2(shgrp, "mipRatio[0]", (float *)vedata->stl->g_data->mip_ratio, 10); } if (use_ssrefraction) { DRW_shgroup_uniform_buffer(shgrp, "colorBuffer", &vedata->txl->refract_color); DRW_shgroup_uniform_vec4(shgrp, "ssrParameters", &vedata->stl->effects->ssr_quality, 1); DRW_shgroup_uniform_float(shgrp, "borderFadeFactor", &vedata->stl->effects->ssr_border_fac, 1); DRW_shgroup_uniform_float(shgrp, "maxRoughness", &vedata->stl->effects->ssr_max_roughness, 1); - DRW_shgroup_uniform_vec2(shgrp, "mipRatio[0]", (float *)vedata->stl->g_data->mip_ratio, 10); DRW_shgroup_uniform_int(shgrp, "rayCount", &vedata->stl->effects->ssr_ray_count, 1); } if (vedata->stl->effects->use_ao) { -- cgit v1.2.3 From 659be38760784b51cf17c768cdf74cdd5718ba71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 18 Aug 2017 15:06:51 +0200 Subject: Eevee: Rework GTAO This includes big improvement: - The horizon search is decoupled from the BSDF evaluation. This means using multiple BSDF nodes have a much lower impact when enbaling AO. - The horizon search is optimized by splitting the search into 4 corners searching similar directions to help which GPU cache coherence. - The AO options are now uniforms and do not trigger shader recompilation (aka. freeze UI). - Include a quality slider similar to the SSR one. - Add a switch for disabling bounce light approximation. - Fix problem with Bent Normals when occlusion get very dark. - Add a denoise option to that takes the neighbors pixel values via glsl derivatives. This reduces noise but exhibit 2x2 blocky artifacts. The downside : Separating the horizon search uses more memory (~3MB for each samples on HD viewport). We could lower the bit depth to 4bit per horizon but it produce noticeable banding (might be fixed with some dithering). --- .../blender/draw/engines/eevee/eevee_materials.c | 49 +++++++--------------- 1 file changed, 14 insertions(+), 35 deletions(-) (limited to 'source/blender/draw/engines/eevee/eevee_materials.c') diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index e8bf461e91f..ef330c424ab 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -285,15 +285,9 @@ static char *eevee_get_defines(int options) if ((options & VAR_MAT_PROBE) != 0) { BLI_dynstr_appendf(ds, "#define PROBE_CAPTURE\n"); } - if ((options & VAR_MAT_AO) != 0) { - BLI_dynstr_appendf(ds, "#define USE_AO\n"); - } if ((options & VAR_MAT_FLAT) != 0) { BLI_dynstr_appendf(ds, "#define USE_FLAT_NORMAL\n"); } - if ((options & VAR_MAT_BENT) != 0) { - BLI_dynstr_appendf(ds, "#define USE_BENT_NORMAL\n"); - } if ((options & VAR_MAT_CLIP) != 0) { BLI_dynstr_appendf(ds, "#define USE_ALPHA_CLIP\n"); } @@ -379,6 +373,7 @@ static void add_standard_uniforms( DRW_shgroup_uniform_buffer(shgrp, "shadowCubes", &sldata->shadow_depth_cube_pool); DRW_shgroup_uniform_buffer(shgrp, "shadowCascades", &sldata->shadow_depth_cascade_pool); DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1); + DRW_shgroup_uniform_vec4(shgrp, "aoParameters[0]", &vedata->stl->effects->ao_dist, 2); if (refract_depth != NULL) { DRW_shgroup_uniform_float(shgrp, "refractionDepth", refract_depth, 1); } @@ -395,7 +390,8 @@ static void add_standard_uniforms( DRW_shgroup_uniform_int(shgrp, "rayCount", &vedata->stl->effects->ssr_ray_count, 1); } if (vedata->stl->effects->use_ao) { - DRW_shgroup_uniform_vec3(shgrp, "aoParameters", &vedata->stl->effects->ao_dist, 1); + DRW_shgroup_uniform_buffer(shgrp, "horizonBuffer", &vedata->txl->gtao_horizons); + DRW_shgroup_uniform_ivec2(shgrp, "aoHorizonTexSize", (int *)vedata->stl->effects->ao_texsize, 1); } } @@ -614,14 +610,11 @@ struct GPUMaterial *EEVEE_material_world_volume_get( struct GPUMaterial *EEVEE_material_mesh_get( struct Scene *scene, Material *ma, - bool use_ao, bool use_bent_normals, bool use_blend, - bool use_multiply, bool use_refract) + bool use_blend, bool use_multiply, bool use_refract) { const void *engine = &DRW_engine_viewport_eevee_type; int options = VAR_MAT_MESH; - if (use_ao) options |= VAR_MAT_AO; - if (use_bent_normals) options |= VAR_MAT_BENT; if (use_blend) options |= VAR_MAT_BLEND; if (use_multiply) options |= VAR_MAT_MULT; if (use_refract) options |= VAR_MAT_REFRACT; @@ -687,15 +680,11 @@ struct GPUMaterial *EEVEE_material_mesh_depth_get( } struct GPUMaterial *EEVEE_material_hair_get( - struct Scene *scene, Material *ma, - bool use_ao, bool use_bent_normals) + struct Scene *scene, Material *ma) { const void *engine = &DRW_engine_viewport_eevee_type; int options = VAR_MAT_MESH | VAR_MAT_HAIR; - if (use_ao) options |= VAR_MAT_AO; - if (use_bent_normals) options |= VAR_MAT_BENT; - GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine, options); if (mat) { return mat; @@ -718,15 +707,13 @@ struct GPUMaterial *EEVEE_material_hair_get( **/ static struct DRWShadingGroup *EEVEE_default_shading_group_create( EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, DRWPass *pass, - bool is_hair, bool is_flat_normal, bool use_ao, bool use_bent_normals, bool use_blend, bool use_ssr) + bool is_hair, bool is_flat_normal, bool use_blend, bool use_ssr) { static int ssr_id; ssr_id = (use_ssr) ? 0 : -1; int options = VAR_MAT_MESH; if (is_hair) options |= VAR_MAT_HAIR; - if (use_ao) options |= VAR_MAT_AO; - if (use_bent_normals) options |= VAR_MAT_BENT; if (is_flat_normal) options |= VAR_MAT_FLAT; if (use_blend) options |= VAR_MAT_BLEND; @@ -745,15 +732,13 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_create( **/ static struct DRWShadingGroup *EEVEE_default_shading_group_get( EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, - bool is_hair, bool is_flat_normal, bool use_ao, bool use_bent_normals, bool use_ssr) + bool is_hair, bool is_flat_normal, bool use_ssr) { static int ssr_id; ssr_id = (use_ssr) ? 0 : -1; int options = VAR_MAT_MESH; if (is_hair) options |= VAR_MAT_HAIR; - if (use_ao) options |= VAR_MAT_AO; - if (use_bent_normals) options |= VAR_MAT_BENT; if (is_flat_normal) options |= VAR_MAT_FLAT; if (e_data.default_lit[options] == NULL) { @@ -933,7 +918,7 @@ static void material_opaque( /* This will have been created already, just perform a lookup. */ *gpumat = (use_gpumat) ? EEVEE_material_mesh_get( - scene, ma, stl->effects->use_ao, stl->effects->use_bent_normals, false, false, use_refract) : NULL; + scene, ma, false, false, use_refract) : NULL; *gpumat_depth = (use_gpumat) ? EEVEE_material_mesh_depth_get( scene, ma, (ma->blend_method == MA_BM_HASHED), false) : NULL; return; @@ -941,8 +926,7 @@ static void material_opaque( if (use_gpumat) { /* Shading */ - *gpumat = EEVEE_material_mesh_get(scene, ma, - stl->effects->use_ao, stl->effects->use_bent_normals, false, false, use_refract); + *gpumat = EEVEE_material_mesh_get(scene, ma, false, false, use_refract); *shgrp = DRW_shgroup_material_create(*gpumat, use_refract ? psl->refract_pass : psl->material_pass); if (*shgrp) { @@ -986,8 +970,7 @@ static void material_opaque( /* Fallback to default shader */ if (*shgrp == NULL) { - *shgrp = EEVEE_default_shading_group_get(sldata, vedata, false, use_flat_nor, - stl->effects->use_ao, stl->effects->use_bent_normals, stl->effects->use_ssr); + *shgrp = EEVEE_default_shading_group_get(sldata, vedata, false, use_flat_nor, stl->effects->use_ssr); DRW_shgroup_uniform_vec3(*shgrp, "basecol", color_p, 1); DRW_shgroup_uniform_float(*shgrp, "metallic", metal_p, 1); DRW_shgroup_uniform_float(*shgrp, "specular", spec_p, 1); @@ -1031,9 +1014,7 @@ static void material_transparent( if (ma->use_nodes && ma->nodetree) { /* Shading */ - *gpumat = EEVEE_material_mesh_get(scene, ma, - stl->effects->use_ao, stl->effects->use_bent_normals, - true, (ma->blend_method == MA_BM_MULTIPLY), use_refract); + *gpumat = EEVEE_material_mesh_get(scene, ma, true, (ma->blend_method == MA_BM_MULTIPLY), use_refract); *shgrp = DRW_shgroup_material_create(*gpumat, psl->transparent_pass); if (*shgrp) { @@ -1054,7 +1035,7 @@ static void material_transparent( if (*shgrp == NULL) { *shgrp = EEVEE_default_shading_group_create( sldata, vedata, psl->transparent_pass, - false, use_flat_nor, stl->effects->use_ao, stl->effects->use_bent_normals, true, false); + false, use_flat_nor, true, false); DRW_shgroup_uniform_vec3(*shgrp, "basecol", color_p, 1); DRW_shgroup_uniform_float(*shgrp, "metallic", metal_p, 1); DRW_shgroup_uniform_float(*shgrp, "specular", spec_p, 1); @@ -1267,8 +1248,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl } else { if (ma->use_nodes && ma->nodetree) { - struct GPUMaterial *gpumat = EEVEE_material_hair_get(scene, ma, - stl->effects->use_ao, stl->effects->use_bent_normals); + struct GPUMaterial *gpumat = EEVEE_material_hair_get(scene, ma); shgrp = DRW_shgroup_material_create(gpumat, psl->material_pass); if (shgrp) { @@ -1290,8 +1270,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl /* Fallback to default shader */ if (shgrp == NULL) { - shgrp = EEVEE_default_shading_group_get(sldata, vedata, true, false, - stl->effects->use_ao, stl->effects->use_bent_normals, stl->effects->use_ssr); + shgrp = EEVEE_default_shading_group_get(sldata, vedata, true, false, stl->effects->use_ssr); DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1); DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1); DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1); -- cgit v1.2.3