[Bf-blender-cvs] [95894421cb4] blender2.8: Workbench: Xray: Optimize and fix implementation.

Clément Foucault noreply at git.blender.org
Sun Jun 10 19:56:44 CEST 2018


Commit: 95894421cb4e9ccabb4cff393b561625b9bc4280
Author: Clément Foucault
Date:   Sun Jun 10 15:30:49 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB95894421cb4e9ccabb4cff393b561625b9bc4280

Workbench: Xray: Optimize and fix implementation.

There was a method explained in the Weighted Blended Order-Independent
Transparency paper to support hardware that does not support per render
target blending function.

So now only 2 geometry passes are required instead of 3 (one being the
outline/depth fill pass).

This also fix how the blending is done. There was some premult confusion
in the implementation.

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

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
D	source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_revealage_frag.glsl
M	source/blender/draw/engines/workbench/workbench_forward.c
M	source/blender/draw/engines/workbench/workbench_materials.c
M	source/blender/draw/engines/workbench/workbench_private.h
M	source/blender/draw/intern/DRW_render.h
M	source/blender/draw/intern/draw_manager_exec.c

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

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index b7eaecb7ab6..f049fc87205 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -227,7 +227,6 @@ data_to_c_simple(engines/workbench/shaders/workbench_deferred_composite_frag.gls
 data_to_c_simple(engines/workbench/shaders/workbench_forward_composite_frag.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_forward_depth_frag.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl SRC)
-data_to_c_simple(engines/workbench/shaders/workbench_forward_transparent_revealage_frag.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_object_outline_lib.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_prepass_vert.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_prepass_frag.glsl SRC)
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
index 8908891d7e6..0b494aa019f 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
@@ -65,11 +65,11 @@ void fresnel(vec3 I, vec3 N, float ior, out float kr)
 	// kt = 1 - kr;
 }
 
-vec4 calculate_transparent_accum(vec4 premultiplied) {
-	float a = min(1.0, premultiplied.a) * 8.0 + 0.01;
+float calculate_transparent_weight(float alpha) {
+	/* Eq 10 */
+	float a = min(1.0, alpha) * 8.0 + 0.01;
 	float b = -gl_FragCoord.z * 0.95 + 1.0;
-	float w = clamp(a * a * a * 1e8 * b * b * b, 1e-2, 3e2);
-	return premultiplied * w;
+	return alpha * clamp(a * a * a * 1e8 * b * b * b, 1e-2, 3e3);
 }
 
 vec3 view_vector_from_screen_uv(vec2 uv, vec4 viewvecs[3], mat4 proj_mat)
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl
index f335e1a15bd..1d9f37274bd 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl
@@ -2,9 +2,7 @@ out vec4 fragColor;
 
 uniform usampler2D objectId;
 uniform sampler2D transparentAccum;
-#ifdef WORKBENCH_REVEALAGE_ENABLED
 uniform sampler2D transparentRevealage;
-#endif
 uniform vec2 invertedViewportSize;
 
 layout(std140) uniform world_block {
@@ -16,29 +14,24 @@ void main()
 	ivec2 texel = ivec2(gl_FragCoord.xy);
 	vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize;
 	uint object_id = texelFetch(objectId, texel, 0).r;
-	vec4 transparent_accum = texelFetch(transparentAccum, texel, 0);
-#ifdef WORKBENCH_REVEALAGE_ENABLED
-	float transparent_revealage = texelFetch(transparentRevealage, texel, 0).r;
-#endif
-	vec4 color;
-	vec4 bg_color;
+
+	/* Listing 4 */
+	vec4 trans_accum = texelFetch(transparentAccum, texel, 0);
+	float trans_revealage = trans_accum.a;
+	trans_accum.a = texelFetch(transparentRevealage, texel, 0).r;
 
 #ifdef V3D_SHADING_OBJECT_OUTLINE
 	float outline = calculate_object_outline(objectId, texel, object_id);
 #else /* V3D_SHADING_OBJECT_OUTLINE */
 	float outline = 1.0;
 #endif /* V3D_SHADING_OBJECT_OUTLINE */
-	bg_color = vec4(background_color(world_data, uv_viewport.y), 0.0);
-	if (object_id == NO_OBJECT_ID) {
-		color = bg_color;
-	} else {
-#ifdef WORKBENCH_REVEALAGE_ENABLED
-		color = vec4((transparent_accum.xyz / max(transparent_accum.a, EPSILON)) * (1.0 - transparent_revealage), 1.0);
-		color = mix(bg_color, color, clamp(1.0 - transparent_revealage, 0.0, 1.0));
-#else
-		color = vec4(transparent_accum.xyz / max(transparent_accum.a, EPSILON), 1.0);
-#endif
-	}
-
-	fragColor = vec4(mix(world_data.object_outline_color.rgb, color.xyz, outline), 1.0);
+	vec3 bg_color = background_color(world_data, uv_viewport.y);
+
+	/* TODO: Bypass the whole shader if there is no xray pass and no outline pass. */
+	vec3 trans_color = trans_accum.rgb / clamp(trans_accum.a, 1e-4, 5e4);
+	vec3 color = mix(trans_color, bg_color, trans_revealage);
+
+	color = mix(world_data.object_outline_color.rgb, color, outline);
+
+	fragColor = vec4(color, 1.0);
 }
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
index f1eacd281b1..53903a4af76 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
@@ -26,7 +26,7 @@ layout(std140) uniform material_block {
 };
 
 layout(location=0) out vec4 transparentAccum;
-
+layout(location=1) out float revealageAccum; /* revealage actually stored in transparentAccum.a */
 
 void main()
 {
@@ -70,7 +70,13 @@ void main()
 
 	vec3 shaded_color = diffuse_light * diffuse_color.rgb + specular_color;
 
-	vec4 premultiplied = vec4(shaded_color.rgb * alpha, alpha);
-	transparentAccum = calculate_transparent_accum(premultiplied);
+	/* Based on :
+	 * McGuire and Bavoil, Weighted Blended Order-Independent Transparency, Journal of
+	 * Computer Graphics Techniques (JCGT), vol. 2, no. 2, 122–141, 2013
+	 */
+	/* Listing 4 */
+	float weight = calculate_transparent_weight(alpha);
+	transparentAccum = vec4(shaded_color * weight, alpha);
+	revealageAccum = weight;
 }
 
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_revealage_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_revealage_frag.glsl
deleted file mode 100644
index c591425b950..00000000000
--- a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_revealage_frag.glsl
+++ /dev/null
@@ -1,7 +0,0 @@
-layout(location=0) out float transparentRevealage;
-uniform float alpha = 0.5;
-void main()
-{
-	transparentRevealage = alpha;
-}
-
diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c
index 3bc016e139b..8d67a936382 100644
--- a/source/blender/draw/engines/workbench/workbench_forward.c
+++ b/source/blender/draw/engines/workbench/workbench_forward.c
@@ -50,17 +50,13 @@
 static struct {
 	struct GPUShader *composite_sh_cache[MAX_SHADERS];
 	struct GPUShader *transparent_accum_sh_cache[MAX_SHADERS];
-	struct GPUShader *transparent_revealage_sh;
-	struct GPUShader *transparent_revealage_hair_sh;
 	struct GPUShader *object_outline_sh;
 	struct GPUShader *object_outline_hair_sh;
 	struct GPUShader *checker_depth_sh;
 
 	struct GPUTexture *object_id_tx; /* ref only, not alloced */
 	struct GPUTexture *transparent_accum_tx; /* ref only, not alloced */
-#ifdef WORKBENCH_REVEALAGE_ENABLED
 	struct GPUTexture *transparent_revealage_tx; /* ref only, not alloced */
-#endif
 	struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */
 	int next_object_id;
 	float normal_world_matrix[3][3];
@@ -71,9 +67,6 @@ extern char datatoc_common_hair_lib_glsl[];
 extern char datatoc_workbench_forward_composite_frag_glsl[];
 extern char datatoc_workbench_forward_depth_frag_glsl[];
 extern char datatoc_workbench_forward_transparent_accum_frag_glsl[];
-#ifdef WORKBENCH_REVEALAGE_ENABLED
-extern char datatoc_workbench_forward_transparent_revealage_frag_glsl[];
-#endif
 extern char datatoc_workbench_data_lib_glsl[];
 extern char datatoc_workbench_background_lib_glsl[];
 extern char datatoc_workbench_checkerboard_depth_frag_glsl[];
@@ -127,22 +120,6 @@ static char *workbench_build_forward_transparent_accum_frag(void)
 	return str;
 }
 
-#ifdef WORKBENCH_REVEALAGE_ENABLED
-static char *workbench_build_forward_transparent_revealage_frag(void)
-{
-	char *str = NULL;
-
-	DynStr *ds = BLI_dynstr_new();
-
-	BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
-	BLI_dynstr_append(ds, datatoc_workbench_forward_transparent_revealage_frag_glsl);
-
-	str = BLI_dynstr_get_cstring(ds);
-	BLI_dynstr_free(ds);
-	return str;
-}
-#endif
-
 static char *workbench_build_forward_composite_frag(void)
 {
 	char *str = NULL;
@@ -310,17 +287,6 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
 		        forward_vert, NULL,
 		        forward_depth_frag, defines_hair);
 
-#ifdef WORKBENCH_REVEALAGE_ENABLED
-		char *forward_transparent_revealage_frag = workbench_build_forward_transparent_revealage_frag();
-		e_data.transparent_revealage_sh = DRW_shader_create(
-		        forward_vert, NULL,
-		        forward_transparent_revealage_frag, defines);
-		e_data.transparent_revealage_hair_sh = DRW_shader_create(
-		        forward_vert, NULL,
-		        forward_transparent_revealage_frag, defines_hair);
-		MEM_freeN(forward_transparent_revealage_frag);
-#endif
-
 		e_data.checker_depth_sh = DRW_shader_create_fullscreen(
 		        datatoc_workbench_checkerboard_depth_frag_glsl, NULL);
 		MEM_freeN(forward_vert);
@@ -337,63 +303,32 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
 	        size[0], size[1], GPU_R32UI, &draw_engine_workbench_transparent);
 	e_data.transparent_accum_tx = DRW_texture_pool_query_2D(
 	        size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_transparent);
-#ifdef WORKBENCH_REVEALAGE_ENABLED
 	e_data.transparent_revealage_tx = DRW_texture_pool_query_2D(
 	        size[0], size[1], GPU_R16F, &draw_engine_workbench_transparent);
-#endif
 	e_data.composite_buffer_tx = DRW_texture_pool_query_2D(
 	        size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_transparent);
+
 	GPU_framebuffer_ensure_config(&fbl->object_outline_fb, {
 		GPU_ATTACHMENT_TEXTURE(dtxl->depth),
 		GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx),
 	});
+
 	GPU_framebuffer_ensure_config(&fbl->transparent_accum_fb, {
 		GPU_ATTACHMENT_NONE,
 		GPU_ATTACHMENT_TEXTURE(e_data.transparent_accum_tx),
-	});
-
-#ifdef WORKBENCH_REVEALAGE_ENABLED
-	GPU_framebuffer_ensure_config(&fbl->transparent_revealage_fb, {
-		GPU_ATTACHMENT_NONE,
 		GPU_ATTACHMENT_TEXTURE(e_data.transparent_revealage_tx),
 	});
-#endif
 
 	GPU_framebuffer_ensure_config(&fbl->composite_fb, {
 		GPU_ATTACHMENT_NONE,
 		GPU_ATTACHMENT_TEXTURE(e_data.com

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list