[Bf-blender-cvs] [659be387607] blender2.8: Eevee: Rework GTAO
Clément Foucault
noreply at git.blender.org
Fri Aug 18 15:42:51 CEST 2017
Commit: 659be38760784b51cf17c768cdf74cdd5718ba71
Author: Clément Foucault
Date: Fri Aug 18 15:06:51 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB659be38760784b51cf17c768cdf74cdd5718ba71
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).
===================================================================
M release/scripts/startup/bl_ui/properties_render.py
M release/scripts/startup/bl_ui/properties_render_layer.py
M source/blender/draw/CMakeLists.txt
M source/blender/draw/engines/eevee/eevee_effects.c
M source/blender/draw/engines/eevee/eevee_engine.c
M source/blender/draw/engines/eevee/eevee_lightprobes.c
M source/blender/draw/engines/eevee/eevee_materials.c
M source/blender/draw/engines/eevee/eevee_private.h
M source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
A source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl
M source/blender/makesrna/intern/rna_scene.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index e6dbd8c8eab..5ef1424ca0f 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -657,9 +657,12 @@ class RENDER_PT_eevee_postprocess_settings(RenderButtonsPanel, Panel):
col.label("Ambient Occlusion:")
col.prop(props, "gtao_use_bent_normals")
+ col.prop(props, "gtao_denoise")
+ col.prop(props, "gtao_bounce")
col.prop(props, "gtao_samples")
col.prop(props, "gtao_distance")
col.prop(props, "gtao_factor")
+ col.prop(props, "gtao_quality")
col.separator()
col.label("Motion Blur:")
diff --git a/release/scripts/startup/bl_ui/properties_render_layer.py b/release/scripts/startup/bl_ui/properties_render_layer.py
index edbaddc4f6c..06598db2650 100644
--- a/release/scripts/startup/bl_ui/properties_render_layer.py
+++ b/release/scripts/startup/bl_ui/properties_render_layer.py
@@ -192,9 +192,12 @@ class RENDERLAYER_PT_eevee_postprocess_settings(RenderLayerButtonsPanel, Panel):
col = layout.column()
col.label("Ambient Occlusion:")
col.template_override_property(layer_props, scene_props, "gtao_use_bent_normals")
+ col.template_override_property(layer_props, scene_props, "gtao_denoise")
+ col.template_override_property(layer_props, scene_props, "gtao_bounce")
col.template_override_property(layer_props, scene_props, "gtao_samples")
col.template_override_property(layer_props, scene_props, "gtao_distance")
col.template_override_property(layer_props, scene_props, "gtao_factor")
+ col.template_override_property(layer_props, scene_props, "gtao_quality")
col.separator()
col.label("Motion Blur:")
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index d5e4a402330..2a22715baf3 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -141,6 +141,7 @@ data_to_c_simple(engines/eevee/shaders/effect_dof_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_dof_geom.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_dof_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_downsample_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/effect_gtao_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_motion_blur_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_ssr_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl SRC)
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index 2922e4622ad..f16393eb35a 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -99,11 +99,16 @@ static struct {
/* Simple Downsample */
struct GPUShader *downsample_sh;
+ /* Ground Truth Ambient Occlusion */
+ struct GPUShader *gtao_sh;
+ struct GPUShader *gtao_debug_sh;
+
struct GPUTexture *depth_src;
struct GPUTexture *color_src;
int depth_src_layer;
} e_data = {NULL}; /* Engine data */
+extern char datatoc_ambient_occlusion_lib_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_bsdf_sampling_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
@@ -115,6 +120,7 @@ extern char datatoc_effect_dof_vert_glsl[];
extern char datatoc_effect_dof_geom_glsl[];
extern char datatoc_effect_dof_frag_glsl[];
extern char datatoc_effect_downsample_frag_glsl[];
+extern char datatoc_effect_gtao_frag_glsl[];
extern char datatoc_lightprobe_lib_glsl[];
extern char datatoc_raytrace_lib_glsl[];
extern char datatoc_tonemap_frag_glsl[];
@@ -229,6 +235,18 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
/* Shaders */
if (!e_data.motion_blur_sh) {
+ DynStr *ds_frag = BLI_dynstr_new();
+ BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
+ BLI_dynstr_append(ds_frag, datatoc_ambient_occlusion_lib_glsl);
+ BLI_dynstr_append(ds_frag, datatoc_effect_gtao_frag_glsl);
+ char *frag_str = BLI_dynstr_get_cstring(ds_frag);
+ BLI_dynstr_free(ds_frag);
+
+ e_data.gtao_sh = DRW_shader_create_fullscreen(frag_str, NULL);
+ e_data.gtao_debug_sh = DRW_shader_create_fullscreen(frag_str, "#define DEBUG_AO\n");
+
+ MEM_freeN(frag_str);
+
e_data.downsample_sh = DRW_shader_create_fullscreen(datatoc_effect_downsample_frag_glsl, NULL);
e_data.volumetric_upsample_sh = DRW_shader_create_fullscreen(datatoc_volumetric_frag_glsl, "#define STEP_UPSAMPLE\n");
@@ -479,11 +497,68 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
&tex, 1);
}
- {
+ if (BKE_collection_engine_property_value_get_bool(props, "gtao_enable")) {
/* Ambient Occlusion*/
- stl->effects->ao_dist = BKE_collection_engine_property_value_get_float(props, "gtao_distance");
- stl->effects->ao_samples = BKE_collection_engine_property_value_get_int(props, "gtao_samples");
- stl->effects->ao_factor = BKE_collection_engine_property_value_get_float(props, "gtao_factor");
+ effects->enabled_effects |= EFFECT_GTAO;
+
+ effects->ao_dist = BKE_collection_engine_property_value_get_float(props, "gtao_distance");
+ effects->ao_factor = BKE_collection_engine_property_value_get_float(props, "gtao_factor");
+ effects->ao_quality = 1.0f - BKE_collection_engine_property_value_get_float(props, "gtao_quality");
+ effects->ao_samples = BKE_collection_engine_property_value_get_int(props, "gtao_samples");
+ effects->ao_samples_inv = 1.0f / effects->ao_samples;
+
+ effects->ao_settings = 1.0; /* USE_AO */
+ if (BKE_collection_engine_property_value_get_bool(props, "gtao_use_bent_normals")) {
+ effects->ao_settings += 2.0; /* USE_BENT_NORMAL */
+ }
+ if (BKE_collection_engine_property_value_get_bool(props, "gtao_denoise")) {
+ effects->ao_settings += 4.0; /* USE_DENOISE */
+ }
+
+ effects->ao_offset = 0.0f;
+ effects->ao_bounce_fac = (float)BKE_collection_engine_property_value_get_bool(props, "gtao_bounce");
+
+ effects->ao_texsize[0] = ((int)viewport_size[0]);
+ effects->ao_texsize[1] = ((int)viewport_size[1]);
+
+ /* Round up to multiple of 2 */
+ if ((effects->ao_texsize[0] & 0x1) != 0) {
+ effects->ao_texsize[0] += 1;
+ }
+ if ((effects->ao_texsize[1] & 0x1) != 0) {
+ effects->ao_texsize[1] += 1;
+ }
+
+ CLAMP(effects->ao_samples, 1, 32);
+
+ if (effects->hori_tex_layers != effects->ao_samples) {
+ DRW_TEXTURE_FREE_SAFE(txl->gtao_horizons);
+ }
+
+ if (txl->gtao_horizons == NULL) {
+ effects->hori_tex_layers = effects->ao_samples;
+ txl->gtao_horizons = DRW_texture_create_2D_array((int)viewport_size[0], (int)viewport_size[1], effects->hori_tex_layers, DRW_TEX_RG_8, 0, NULL);
+ }
+
+ DRWFboTexture tex = {&txl->gtao_horizons, DRW_TEX_RG_8, 0};
+
+ DRW_framebuffer_init(&fbl->gtao_fb, &draw_engine_eevee_type,
+ effects->ao_texsize[0], effects->ao_texsize[1],
+ &tex, 1);
+
+ if (G.debug_value == 6) {
+ DRWFboTexture tex_debug = {&stl->g_data->gtao_horizons_debug, DRW_TEX_RGBA_8, DRW_TEX_TEMP};
+
+ DRW_framebuffer_init(&fbl->gtao_debug_fb, &draw_engine_eevee_type,
+ (int)viewport_size[0], (int)viewport_size[1],
+ &tex_debug, 1);
+ }
+ }
+ else {
+ /* Cleanup */
+ DRW_TEXTURE_FREE_SAFE(txl->gtao_horizons);
+ DRW_FRAMEBUFFER_FREE_SAFE(fbl->gtao_fb);
+ effects->ao_settings = 0.0f;
}
/* MinMax Pyramid */
@@ -493,6 +568,11 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
(int)viewport_size[0] / 2, (int)viewport_size[1] / 2,
&texmin, 1);
+ /* Cannot define 2 depth texture for one framebuffer. So allocate ourself. */
+ if (txl->maxzbuffer == NULL) {
+ txl->maxzbuffer = DRW_texture_create_2D((int)viewport_size[0] / 2, (int)viewport_size[1] / 2, DRW_TEX_DEPTH_24, DRW_TEX_MIPMAP, NULL);
+ }
+
/* Compute Mipmap texel alignement. */
for (int i = 0; i < 10; ++i) {
float mip_size[2] = {viewport_size[0], viewport_size[1]};
@@ -504,11 +584,6 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
stl->g_data->mip_ratio[i][1] = viewport_size[1] / (mip_size[1] * powf(2.0f, floorf(log2f(floorf(viewport_size[1] / mip_size[1])))));
}
- /* Cannot define 2 depth texture for one framebuffer. So allocate ourself. */
- if (txl->maxzbuffer == NULL) {
- txl->maxzbuffer = DRW_texture_create_2D((int)viewport_size[0] / 2, (int)viewport_size[1] / 2, DRW_TEX_DEPTH_24, DRW_TEX_MIPMAP, NULL);
- }
-
if (BKE_collection_engine_property_value_get_bool(props, "volumetric_enable")) {
World *wo = scene->world;
@@ -617,11 +692,6 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
/* MRT for the shading pass in order to output needed data for the SSR pass. */
/* TODO create one texture layer per lobe */
- if (txl->ssr_normal_input == NULL) {
- DRWTextureFormat nor_format = DRW_TEX_RG_16;
- txl->ssr_normal_input = DRW_texture_create_2D((int)viewport_size[0], (int)viewport_size[1], nor_format, 0, NULL);
- }
-
if (txl->ssr_specrough_input == NULL) {
DRWTextureFormat specrough_format = (high_qual_input) ? DRW_TEX_RGBA_16 : DRW_TEX_RGBA_8;
txl->ssr_specrough_input = DRW_texture_create_2D((int)viewport_size[0], (int)viewport_size[1], specrough_format, 0, NULL);
@@ -629,9 +699,7 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
/* Reattach textures to the right buffer (because we are alternating between buffers) */
/* TODO multiple FBO per texture!!!! */
- DRW_framebuffer_texture_detach(txl->ssr_normal_input);
DRW_framebuffer_texture_detach(txl->ssr_specrough_input);
- DRW_framebuffer_texture_attach(fbl->main, txl->ssr_normal_input, 1, 0);
DRW_framebuffer_texture_attach(fbl->main, txl->ssr_specrough_input, 2, 0);
/* Raytracing output */
@@ -649,7 +717,6 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
}
else {
/* Cleanup to release memory */
- DRW_TEXTURE_FREE_SAFE(txl->ssr_
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list