[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