[Bf-blender-cvs] [bc99f4903c5] master: Workbench: Add transparency support for materials

Clément Foucault noreply at git.blender.org
Tue Jan 29 15:17:08 CET 2019


Commit: bc99f4903c5f55d35b5fec32d6e18400f25089fb
Author: Clément Foucault
Date:   Tue Jan 29 03:06:59 2019 +0100
Branches: master
https://developer.blender.org/rBbc99f4903c5f55d35b5fec32d6e18400f25089fb

Workbench: Add transparency support for materials

This adds the posibility of having certain materials transparent in solid
mode. The option is (for now) per material only and thus only shows in
material color mode.

This uses the same rendering technique as Xray mode.

Note that objects are not considered transparent for selection with this.

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

M	release/scripts/startup/bl_ui/properties_material.py
M	source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl
M	source/blender/draw/engines/workbench/workbench_data.c
M	source/blender/draw/engines/workbench/workbench_deferred.c
M	source/blender/draw/engines/workbench/workbench_forward.c
M	source/blender/draw/engines/workbench/workbench_private.h
M	source/blender/makesdna/DNA_material_types.h
M	source/blender/makesrna/intern/rna_material.c

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

diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index 8d7e7ac266d..ae1cc12ba50 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -258,6 +258,7 @@ class MATERIAL_PT_viewport(MaterialButtonsPanel, Panel):
         col.prop(mat, "diffuse_color", text="Color")
         col.prop(mat, "metallic")
         col.prop(mat, "roughness")
+        col.prop(mat, "transparency")
 
     def draw(self, context):
         self.draw_shared(self, context.material)
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 cb5516ca34f..b1f08cfef15 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
@@ -5,10 +5,13 @@ uniform sampler2D transparentAccum;
 uniform sampler2D transparentRevealage;
 uniform vec2 invertedViewportSize;
 
+#ifndef ALPHA_COMPOSITE
 layout(std140) uniform world_block {
 	WorldData world_data;
 };
+#endif
 
+/* TODO: Bypass the whole shader if there is no xray pass and no outline pass. */
 void main()
 {
 	ivec2 texel = ivec2(gl_FragCoord.xy);
@@ -19,17 +22,21 @@ void main()
 	float trans_revealage = trans_accum.a;
 	trans_accum.a = texelFetch(transparentRevealage, texel, 0).r;
 
+	vec3 trans_color = trans_accum.rgb / clamp(trans_accum.a, 1e-4, 5e4);
+
+#ifndef ALPHA_COMPOSITE
 	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);
 
-#ifdef V3D_SHADING_OBJECT_OUTLINE
+#  ifdef V3D_SHADING_OBJECT_OUTLINE
 	uint object_id = texelFetch(objectId, texel, 0).r;
 	float outline = calculate_object_outline(objectId, texel, object_id);
 	color = mix(world_data.object_outline_color.rgb, color, outline);
-#endif
+#  endif
 
 	fragColor = vec4(color, 1.0);
+#else
+	fragColor = vec4(trans_color, 1.0 - trans_revealage);
+#endif
 }
diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c
index 22a8f51c23c..b009a8acb08 100644
--- a/source/blender/draw/engines/workbench/workbench_data.c
+++ b/source/blender/draw/engines/workbench/workbench_data.c
@@ -42,6 +42,7 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
 	const DRWContextState *draw_ctx = DRW_context_state_get();
 	const Scene *scene = draw_ctx->scene;
 	wpd->material_hash = BLI_ghash_ptr_new(__func__);
+	wpd->material_transp_hash = BLI_ghash_ptr_new(__func__);
 	wpd->preferences = &U;
 
 	View3D *v3d = draw_ctx->v3d;
@@ -216,6 +217,7 @@ void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, floa
 void workbench_private_data_free(WORKBENCH_PrivateData *wpd)
 {
 	BLI_ghash_free(wpd->material_hash, NULL, MEM_freeN);
+	BLI_ghash_free(wpd->material_transp_hash, NULL, MEM_freeN);
 	DRW_UBO_FREE_SAFE(wpd->world_ubo);
 	DRW_UBO_FREE_SAFE(wpd->dof_ubo);
 	GPU_BATCH_DISCARD_SAFE(wpd->world_clip_planes_batch);
diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c
index 2e421595998..6f97c9df74d 100644
--- a/source/blender/draw/engines/workbench/workbench_deferred.c
+++ b/source/blender/draw/engines/workbench/workbench_deferred.c
@@ -71,7 +71,11 @@ static struct {
 	struct GPUShader *shadow_pass_manifold_sh;
 	struct GPUShader *shadow_caps_sh;
 	struct GPUShader *shadow_caps_manifold_sh;
+	struct GPUShader *oit_resolve_sh;
 
+	/* TODO(fclem) move everything below to wpd and custom viewlayer data. */
+	struct GPUTexture *oit_accum_tx; /* ref only, not alloced */
+	struct GPUTexture *oit_revealage_tx; /* ref only, not alloced */
 	struct GPUTexture *ghost_depth_tx; /* ref only, not alloced */
 	struct GPUTexture *object_id_tx; /* ref only, not alloced */
 	struct GPUTexture *color_buffer_tx; /* ref only, not alloced */
@@ -95,6 +99,7 @@ extern char datatoc_common_world_clip_lib_glsl[];
 extern char datatoc_workbench_prepass_vert_glsl[];
 extern char datatoc_workbench_prepass_frag_glsl[];
 extern char datatoc_workbench_cavity_frag_glsl[];
+extern char datatoc_workbench_forward_composite_frag_glsl[];
 extern char datatoc_workbench_deferred_composite_frag_glsl[];
 extern char datatoc_workbench_deferred_background_frag_glsl[];
 extern char datatoc_workbench_ghost_resolve_frag_glsl[];
@@ -417,6 +422,17 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
 
 	workbench_dof_engine_init(vedata, camera);
 
+	if (OIT_ENABLED(wpd)) {
+		if (e_data.oit_resolve_sh == NULL) {
+			e_data.oit_resolve_sh = DRW_shader_create_fullscreen(
+			        datatoc_workbench_forward_composite_frag_glsl,
+			        "#define ALPHA_COMPOSITE\n");
+		}
+
+		workbench_forward_choose_shaders(wpd);
+		workbench_forward_outline_shaders_ensure(wpd);
+	}
+
 	{
 		const float *viewport_size = DRW_viewport_size_get();
 		const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
@@ -444,6 +460,10 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
 		if (CAVITY_ENABLED(wpd)) {
 			e_data.cavity_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R16, &draw_engine_workbench_solid);
 		}
+		if (OIT_ENABLED(wpd)) {
+			e_data.oit_accum_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_solid);
+			e_data.oit_revealage_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R16F, &draw_engine_workbench_solid);
+		}
 
 		GPU_framebuffer_ensure_config(&fbl->prepass_fb, {
 			GPU_ATTACHMENT_TEXTURE(dtxl->depth),
@@ -479,6 +499,13 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
 				GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx),
 			});
 		}
+		if (OIT_ENABLED(wpd)) {
+			GPU_framebuffer_ensure_config(&fbl->transparent_accum_fb, {
+				GPU_ATTACHMENT_TEXTURE(dtxl->depth),
+				GPU_ATTACHMENT_TEXTURE(e_data.oit_accum_tx),
+				GPU_ATTACHMENT_TEXTURE(e_data.oit_revealage_tx),
+			});
+		}
 	}
 
 	{
@@ -505,7 +532,7 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
 	/* Prepass */
 	{
 		DRWShadingGroup *grp;
-		const bool do_cull = (v3d && (v3d->shading.flag & V3D_SHADING_BACKFACE_CULLING));
+		const bool do_cull = CULL_BACKFACE_ENABLED(wpd);
 
 		int state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
 		psl->prepass_pass = DRW_pass_create("Prepass", (do_cull) ? state | DRW_STATE_CULL_BACK : state);
@@ -587,6 +614,8 @@ void workbench_deferred_engine_free(void)
 	DRW_SHADER_FREE_SAFE(e_data.background_sh[0]);
 	DRW_SHADER_FREE_SAFE(e_data.background_sh[1]);
 
+	DRW_SHADER_FREE_SAFE(e_data.oit_resolve_sh);
+
 	DRW_SHADER_FREE_SAFE(e_data.shadow_pass_sh);
 	DRW_SHADER_FREE_SAFE(e_data.shadow_pass_manifold_sh);
 	DRW_SHADER_FREE_SAFE(e_data.shadow_fail_sh);
@@ -736,6 +765,40 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
 			DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
 		}
 	}
+
+	/**
+	 * Order Independant Transparency.
+	 * Similar to workbench forward. Duplicated code to avoid
+	 * spaghetti with workbench forward. It would be great if we unify
+	 * this in a clean way.
+	 **/
+	if (OIT_ENABLED(wpd)) {
+		const bool do_cull = CULL_BACKFACE_ENABLED(wpd);
+		const int cull_state = (do_cull) ? DRW_STATE_CULL_BACK : 0;
+		/* Transparency Accum */
+		{
+			/* Same as forward but here we use depth test to
+			 * not bleed through other solid objects. */
+			int state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_OIT | DRW_STATE_DEPTH_LESS | cull_state;
+			psl->transparent_accum_pass = DRW_pass_create("Transparent Accum", state);
+		}
+		/* Depth */
+		{
+			int state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | cull_state;
+			psl->object_outline_pass = DRW_pass_create("Transparent Depth", state);
+		}
+		/* OIT Composite */
+		{
+			int state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND;
+			psl->oit_composite_pass = DRW_pass_create("OIT Composite", state);
+
+			grp = DRW_shgroup_create(e_data.oit_resolve_sh, psl->oit_composite_pass);
+			DRW_shgroup_uniform_texture_ref(grp, "transparentAccum", &e_data.oit_accum_tx);
+			DRW_shgroup_uniform_texture_ref(grp, "transparentRevealage", &e_data.oit_revealage_tx);
+			DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
+			DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+		}
+	}
 }
 
 static WORKBENCH_MaterialData *get_or_create_material_data(
@@ -860,6 +923,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
 		const bool use_hide = is_active && DRW_object_use_hide_faces(ob);
 		const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol));
 		const Mesh *me = (ob->type == OB_MESH) ? ob->data : NULL;
+		bool has_transp_mat = false;
 
 		if (!is_sculpt_mode && me && me->mloopuv && TEXTURE_DRAWING_ENABLED(wpd)) {
 			/* Draw textured */
@@ -908,7 +972,16 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
 				for (int i = 0; i < materials_len; ++i) {
 					if (geoms != NULL && geoms[i] != NULL) {
 						Material *mat = give_current_material(ob, i + 1);
-						material = get_or_create_material_data(vedata, ob, mat, NULL, V3D_SHADING_MATERIAL_COLOR, 0);
+						if (mat != NULL && mat->transparency > 0.0) {
+							/* Hack */
+							wpd->shading.xray_alpha = 1.0f - mat->transparency;
+							CLAMP(wpd->shading.xray_alpha, 0.0, 1.0);
+							material = workbench_forward_get_or_create_material_data(vedata, ob, mat, NULL, V3D_SHADING_MATERIAL_COLOR, 0);
+							has_transp_mat = true;
+						}
+						else {
+							material = get_or_create_material_data(vedata, ob, mat, NULL, V3D_SHADING_MATERIAL_COLOR, 0);
+						}
 						DRW_shgroup_call_object_add(material->shgrp, geoms[i], ob);
 					}
 				}
@@ -937,7 +1010,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
 						DRWShadingGroup *grp;
 						bool use

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list