[Bf-blender-cvs] [d35c24f87b1] blender2.8: Eevee: Transparency: Add support for blend ADD and MULTIPLY.

Clément Foucault noreply at git.blender.org
Tue Jul 11 12:46:07 CEST 2017


Commit: d35c24f87b133202abf85f8d0f2512a20caf0cda
Author: Clément Foucault
Date:   Mon Jul 10 11:41:33 2017 +0200
Branches: blender2.8
https://developer.blender.org/rBd35c24f87b133202abf85f8d0f2512a20caf0cda

Eevee: Transparency: Add support for blend ADD and MULTIPLY.

This introduces a new transparency pass.
It bypass the radial distance encoding in alpha for the transparent shaders.

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

M	source/blender/draw/engines/eevee/eevee_engine.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/bsdf_common_lib.glsl
M	source/blender/draw/engines/eevee/shaders/default_frag.glsl
M	source/blender/gpu/shaders/gpu_shader_material.glsl
M	source/blender/makesrna/intern/rna_material.c

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

diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 3475bbb7fad..c8f85d3ae87 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -81,7 +81,6 @@ static void EEVEE_cache_init(void *vedata)
 
 static void EEVEE_cache_populate(void *vedata, Object *ob)
 {
-	EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
 	EEVEE_SceneLayerData *sldata = EEVEE_scene_layer_data_get();
 
 	const DRWContextState *draw_ctx = DRW_context_state_get();
@@ -161,6 +160,9 @@ static void EEVEE_draw_scene(void *vedata)
 	/* Volumetrics */
 	EEVEE_effects_do_volumetrics(sldata, vedata);
 
+	/* Transparent */
+	DRW_draw_pass(psl->transparent_pass);
+
 	/* Post Process */
 	EEVEE_draw_effects(vedata);
 }
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index b85745732e1..929e0932144 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -206,6 +206,12 @@ static char *eevee_get_defines(int options)
 	if ((options & VAR_MAT_HASH) != 0) {
 		BLI_dynstr_appendf(ds, "#define USE_ALPHA_HASH\n");
 	}
+	if ((options & VAR_MAT_BLEND) != 0) {
+		BLI_dynstr_appendf(ds, "#define USE_ALPHA_BLEND\n");
+	}
+	if ((options & VAR_MAT_MULT) != 0) {
+		BLI_dynstr_appendf(ds, "#define USE_MULTIPLY\n");
+	}
 
 	str = BLI_dynstr_get_cstring(ds);
 	BLI_dynstr_free(ds);
@@ -470,13 +476,15 @@ 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_ao, bool use_bent_normals, bool use_blend, bool use_multiply)
 {
 	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;
 
 	GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine, options);
 	if (mat) {
@@ -558,6 +566,34 @@ struct GPUMaterial *EEVEE_material_hair_get(
 	return mat;
 }
 
+/**
+ * Create a default shading group inside the given pass.
+ **/
+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)
+{
+	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;
+
+	if (e_data.default_lit[options] == NULL) {
+		create_default_shader(options);
+	}
+
+	DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], pass);
+	add_standard_uniforms(shgrp, sldata, vedata);
+
+	return shgrp;
+}
+
+/**
+ * Create a default shading group inside the default pass without standard uniforms.
+ **/
 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)
@@ -666,6 +702,11 @@ void EEVEE_materials_cache_init(EEVEE_Data *vedata)
 		DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE;
 		psl->material_pass = DRW_pass_create("Material Shader 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);
+	}
 }
 
 #define ADD_SHGROUP_CALL(shgrp, ob, geom) do { \
@@ -677,6 +718,12 @@ void EEVEE_materials_cache_init(EEVEE_Data *vedata)
 	} \
 } while (0)
 
+#define ADD_SHGROUP_CALL_SAFE(shgrp, ob, geom) do { \
+	if (shgrp) { \
+		ADD_SHGROUP_CALL(shgrp, ob, geom); \
+	} \
+} while (0)
+
 typedef struct EeveeMaterialShadingGroups{
 	struct DRWShadingGroup *shading_grp;
 	struct DRWShadingGroup *depth_grp;
@@ -709,16 +756,16 @@ static void material_opaque(
 
 		/* This will have been created already, just perform a lookup. */
 		*gpumat = (use_gpumat) ? EEVEE_material_mesh_get(
-		        draw_ctx->scene, ma, stl->effects->use_ao, stl->effects->use_bent_normals) : NULL;
+		        scene, ma, stl->effects->use_ao, stl->effects->use_bent_normals, false, false) : NULL;
 		*gpumat_depth = (use_gpumat) ? EEVEE_material_mesh_depth_get(
-		        draw_ctx->scene, ma, (ma->blend_method == MA_BM_HASHED)) : NULL;
+		        scene, ma, (ma->blend_method == MA_BM_HASHED)) : NULL;
 		return;
 	}
 
 	if (use_gpumat) {
 		/* Shading */
 		*gpumat = EEVEE_material_mesh_get(scene, ma,
-		        stl->effects->use_ao, stl->effects->use_bent_normals);
+		        stl->effects->use_ao, stl->effects->use_bent_normals, false, false);
 
 		*shgrp = DRW_shgroup_material_create(*gpumat, psl->material_pass);
 		if (*shgrp) {
@@ -774,7 +821,70 @@ static void material_opaque(
 	BLI_ghash_insert(material_hash, ma, emsg);
 }
 
-// void EEVEE_materials_cache_blended();
+static void material_transparent(
+        Material *ma, EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata,
+        bool do_cull, bool use_flat_nor, struct GPUMaterial **gpumat, struct DRWShadingGroup **shgrp)
+{
+	const DRWContextState *draw_ctx = DRW_context_state_get();
+	Scene *scene = draw_ctx->scene;
+	EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
+	EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
+
+	float *color_p = &ma->r;
+	float *metal_p = &ma->ray_mirror;
+	float *spec_p = &ma->spec;
+	float *rough_p = &ma->gloss_mir;
+
+	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));
+
+		*shgrp = DRW_shgroup_material_create(*gpumat, psl->transparent_pass);
+		if (*shgrp) {
+			add_standard_uniforms(*shgrp, sldata, vedata);
+		}
+		else {
+			/* Shader failed : pink color */
+			static float col[3] = {1.0f, 0.0f, 1.0f};
+			static float half = 0.5f;
+
+			color_p = col;
+			metal_p = spec_p = rough_p = ½
+		}
+	}
+
+	/* Fallback to default shader */
+	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);
+		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);
+		DRW_shgroup_uniform_float(*shgrp, "roughness", rough_p, 1);
+	}
+
+	DRWState cur_state = (do_cull) ? DRW_STATE_CULL_BACK : 0;
+	DRWState all_state = DRW_STATE_CULL_BACK | DRW_STATE_BLEND | DRW_STATE_ADDITIVE | DRW_STATE_MULTIPLY;
+
+	switch (ma->blend_method) {
+		case MA_BM_ADD:
+			cur_state |= DRW_STATE_ADDITIVE;
+			break;
+		case MA_BM_MULTIPLY:
+			cur_state |= DRW_STATE_MULTIPLY;
+			break;
+		default:
+			BLI_assert(0);
+			break;
+	}
+
+	/* Disable other blend modes and use the one we want. */
+	DRW_shgroup_state_disable(*shgrp, all_state);
+	DRW_shgroup_state_enable(*shgrp, cur_state);
+}
 
 void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sldata, Object *ob)
 {
@@ -830,7 +940,8 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
 					break;
 				case MA_BM_ADD:
 				case MA_BM_MULTIPLY:
-					// material_transparent(ma, material_hash, &shgrp);
+					material_transparent(ma, sldata, vedata, do_cull, use_flat_nor,
+					        &gpumat_array[i], &shgrp_array[i]);
 					break;
 			}
 		}
@@ -843,8 +954,8 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
 				ADD_SHGROUP_CALL(shgrp_array[i], ob, mat_geom[i]);
 
 				/* Depth Prepass */
-				ADD_SHGROUP_CALL(shgrp_depth_array[i], ob, mat_geom[i]);
-				ADD_SHGROUP_CALL(shgrp_depth_clip_array[i], ob, mat_geom[i]);
+				ADD_SHGROUP_CALL_SAFE(shgrp_depth_array[i], ob, mat_geom[i]);
+				ADD_SHGROUP_CALL_SAFE(shgrp_depth_clip_array[i], ob, mat_geom[i]);
 
 				/* Shadow Pass */
 				EEVEE_lights_cache_shcaster_add(sldata, psl, mat_geom[i], ob->obmat);
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 92a4df27718..5e0d3ea177b 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -66,14 +66,16 @@ enum {
 	VAR_MAT_AO       = (1 << 3),
 	VAR_MAT_FLAT     = (1 << 4),
 	VAR_MAT_BENT     = (1 << 5),
+	VAR_MAT_BLEND    = (1 << 6),
 	/* Max number of variation */
 	/* IMPORTANT : Leave it last and set
 	 * it's value accordingly. */
-	VAR_MAT_MAX      = (1 << 6),
+	VAR_MAT_MAX      = (1 << 7),
 	/* These are options that are not counted in VAR_MAT_MAX
 	 * because they are not cumulative with the others above. */
-	VAR_MAT_CLIP     = (1 << 7),
-	VAR_MAT_HASH     = (1 << 8),
+	VAR_MAT_CLIP     = (1 << 8),
+	VAR_MAT_HASH     = (1 << 9),
+	VAR_MAT_MULT     = (1 << 10),
 };
 
 typedef struct EEVEE_PassList {
@@ -113,6 +115,7 @@ typedef struct EEVEE_PassList {
 	struct DRWPass *depth_pass_clip_cull;
 	struct DRWPass *default_pass[VAR_MAT_MAX];
 	struct DRWPass *material_pass;
+	struct DRWPass *transparent_pass;
 	struct DRWPass *background_pass;
 } EEVEE_PassList;
 
@@ -448,7 +451,8 @@ struct GPUMaterial *EEVEE_material_world_lightprobe_get(struct Scene *scene, str
 struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, struct World *wo);
 struct GPUMaterial *EEVEE_material_world_volume_get(
         struct Scene *scene, struct World *wo, bool use_lights, bool use_volume_shadows, bool is_homogeneous, bool use_color_transmit);
-struct GPUMaterial *EEVEE_material_mesh_get(struct Scene *scene, Material *ma, bool use_ao, bool use_bent_normals);
+struct GPUMaterial *EEVEE_material_mesh_get(
+        struct Scene *scene, Material *ma, bool use_ao, bool use_bent_normals, bool us

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list