[Bf-blender-cvs] [05bef13b53e] blender2.8: Eevee: Add support for Alpha clip and Hashed Alpha transparency.

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


Commit: 05bef13b53e93978716aff8e2efba7ddf72264ed
Author: Clément Foucault
Date:   Sun Jul 9 12:01:29 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB05bef13b53e93978716aff8e2efba7ddf72264ed

Eevee: Add support for Alpha clip and Hashed Alpha transparency.

Hashed Alpha transparency offers a noisy output but has the benefit of being correctly ordered. Noise can be attenuated with Multisampling / AntiAliasing.

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

M	release/scripts/startup/bl_ui/properties_material.py
M	source/blender/blenkernel/intern/material.c
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/prepass_frag.glsl
M	source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
M	source/blender/gpu/shaders/gpu_shader_material.glsl
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 2991dc110ee..f008254d973 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -1155,6 +1155,26 @@ class EEVEE_MATERIAL_PT_surface(MaterialButtonsPanel, Panel):
             layout.prop(raym, "gloss_factor", text="Roughness")
 
 
+class EEVEE_MATERIAL_PT_options(MaterialButtonsPanel, Panel):
+    bl_label = "Options"
+    bl_context = "material"
+    COMPAT_ENGINES = {'BLENDER_EEVEE'}
+
+    @classmethod
+    def poll(cls, context):
+        engine = context.scene.render.engine
+        return context.material and (engine in cls.COMPAT_ENGINES)
+
+    def draw(self, context):
+        layout = self.layout
+
+        mat = context.material
+
+        layout.prop(mat, "blend_method")
+
+        if mat.blend_method == "CLIP":
+            layout.prop(mat, "alpha_threshold")
+
 classes = (
     MATERIAL_MT_sss_presets,
     MATERIAL_MT_specials,
@@ -1185,6 +1205,7 @@ classes = (
     MATERIAL_PT_custom_props,
     EEVEE_MATERIAL_PT_context_material,
     EEVEE_MATERIAL_PT_surface,
+    EEVEE_MATERIAL_PT_options,
 )
 
 if __name__ == "__main__":  # only for live edit.
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 824151f9c98..e7232322a36 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -207,6 +207,8 @@ void BKE_material_init(Material *ma)
 	ma->mode2 = MA_CASTSHADOW;
 	ma->shade_flag = MA_APPROX_OCCLUSION;
 	ma->preview = NULL;
+
+	ma->alpha_threshold = 0.5f;
 }
 
 Material *BKE_material_add(Main *bmain, const char *name)
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 9453cdb0b80..3475bbb7fad 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -92,14 +92,12 @@ static void EEVEE_cache_populate(void *vedata, Object *ob)
 		}
 	}
 
-	struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob);
-	if (geom) {
-		EEVEE_materials_cache_populate(vedata, sldata, ob, geom);
+	if (ELEM(ob->type, OB_MESH)) {
+		EEVEE_materials_cache_populate(vedata, sldata, ob);
 
 		const bool cast_shadow = true;
 
 		if (cast_shadow) {
-			EEVEE_lights_cache_shcaster_add(sldata, psl, geom, ob->obmat);
 			BLI_addtail(&sldata->shadow_casters, BLI_genericNodeN(ob));
 			EEVEE_ObjectEngineData *oedata = EEVEE_object_data_get(ob);
 			oedata->need_update = ((ob->deg_update_flag & DEG_RUNTIME_DATA_UPDATE) != 0);
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 4cc8b5ed93c..151bd05358d 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -179,8 +179,6 @@ static char *eevee_get_defines(int options)
 {
 	char *str = NULL;
 
-	BLI_assert(options < VAR_MAT_MAX);
-
 	DynStr *ds = BLI_dynstr_new();
 	BLI_dynstr_appendf(ds, SHADER_DEFINES);
 
@@ -202,6 +200,12 @@ static char *eevee_get_defines(int options)
 	if ((options & VAR_MAT_BENT) != 0) {
 		BLI_dynstr_appendf(ds, "#define USE_BENT_NORMAL\n");
 	}
+	if ((options & VAR_MAT_CLIP) != 0) {
+		BLI_dynstr_appendf(ds, "#define USE_ALPHA_CLIP\n");
+	}
+	if ((options & VAR_MAT_HASH) != 0) {
+		BLI_dynstr_appendf(ds, "#define USE_ALPHA_HASH\n");
+	}
 
 	str = BLI_dynstr_get_cstring(ds);
 	BLI_dynstr_free(ds);
@@ -491,6 +495,42 @@ struct GPUMaterial *EEVEE_material_mesh_get(
 	return mat;
 }
 
+struct GPUMaterial *EEVEE_material_mesh_depth_get(struct Scene *scene, Material *ma, bool use_hashed_alpha)
+{
+	const void *engine = &DRW_engine_viewport_eevee_type;
+	int options = VAR_MAT_MESH;
+
+	if (use_hashed_alpha) {
+		options |= VAR_MAT_HASH;
+	}
+	else {
+		options |= VAR_MAT_CLIP;
+	}
+
+	GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine, options);
+	if (mat) {
+		return mat;
+	}
+
+	char *defines = eevee_get_defines(options);
+
+	DynStr *ds_frag = BLI_dynstr_new();
+	BLI_dynstr_append(ds_frag, e_data.frag_shader_lib);
+	BLI_dynstr_append(ds_frag, datatoc_prepass_frag_glsl);
+	char *frag_str = BLI_dynstr_get_cstring(ds_frag);
+	BLI_dynstr_free(ds_frag);
+
+	mat = GPU_material_from_nodetree(
+	        scene, ma->nodetree, &ma->gpumaterial, engine, options,
+	        datatoc_lit_surface_vert_glsl, NULL, frag_str,
+	        defines);
+
+	MEM_freeN(frag_str);
+	MEM_freeN(defines);
+
+	return mat;
+}
+
 struct GPUMaterial *EEVEE_material_hair_get(
         struct Scene *scene, Material *ma,
         bool use_ao, bool use_bent_normals)
@@ -637,7 +677,7 @@ void EEVEE_materials_cache_init(EEVEE_Data *vedata)
 	} \
 } while (0)
 
-void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sldata, Object *ob, struct Gwn_Batch *geom)
+void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sldata, Object *ob)
 {
 	EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
 	EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
@@ -650,12 +690,6 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
 	const bool is_sculpt_mode = is_active && (ob->mode & OB_MODE_SCULPT) != 0;
 	const bool is_default_mode_shader = is_sculpt_mode;
 
-	/* Depth Prepass */
-	DRWShadingGroup *depth_shgrp = do_cull ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp;
-	DRWShadingGroup *depth_clip_shgrp = do_cull ? stl->g_data->depth_shgrp_clip_cull : stl->g_data->depth_shgrp_clip;
-	ADD_SHGROUP_CALL(depth_shgrp, ob, geom);
-	ADD_SHGROUP_CALL(depth_clip_shgrp, ob, geom);
-
 	/* First get materials for this mesh. */
 	if (ELEM(ob->type, OB_MESH)) {
 		const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol));
@@ -740,6 +774,47 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
 		if (mat_geom) {
 			for (int i = 0; i < materials_len; ++i) {
 				ADD_SHGROUP_CALL(shgrp_array[i], ob, mat_geom[i]);
+
+				/* Depth Prepass */
+				DRWShadingGroup *depth_shgrp = NULL;
+				DRWShadingGroup *depth_clip_shgrp;
+
+				Material *ma = give_current_material(ob, i + 1);
+
+				if (ma != NULL && (ma->use_nodes && ma->nodetree)) {
+					if (ELEM(ma->blend_method, MA_BM_CLIP, MA_BM_HASHED)) {
+						Scene *scene = draw_ctx->scene;
+						DRWPass *depth_pass, *depth_clip_pass;
+						struct GPUMaterial *gpumat = EEVEE_material_mesh_depth_get(scene, ma, (ma->blend_method == MA_BM_HASHED));
+
+						depth_pass = do_cull ? psl->depth_pass_cull : psl->depth_pass;
+						depth_clip_pass = do_cull ? psl->depth_pass_clip_cull : psl->depth_pass_clip;
+
+						/* Use same shader for both. */
+						depth_shgrp = DRW_shgroup_material_create(gpumat, depth_pass);
+						depth_clip_shgrp = DRW_shgroup_material_create(gpumat, depth_clip_pass);
+
+						if (ma->blend_method == MA_BM_CLIP) {
+							DRW_shgroup_uniform_float(depth_shgrp, "alphaThreshold", &ma->alpha_threshold, 1);
+							DRW_shgroup_uniform_float(depth_clip_shgrp, "alphaThreshold", &ma->alpha_threshold, 1);
+						}
+					}
+
+					/* Shadow Pass */
+					/* TODO clipped shadow map */
+					EEVEE_lights_cache_shcaster_add(sldata, psl, mat_geom[i], ob->obmat);
+				}
+
+				if (depth_shgrp == NULL) {
+					depth_shgrp = do_cull ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp;
+					depth_clip_shgrp = do_cull ? stl->g_data->depth_shgrp_clip_cull : stl->g_data->depth_shgrp_clip;
+
+					/* Shadow Pass */
+					EEVEE_lights_cache_shcaster_add(sldata, psl, mat_geom[i], ob->obmat);
+				}
+
+				ADD_SHGROUP_CALL(depth_shgrp, ob, mat_geom[i]);
+				ADD_SHGROUP_CALL(depth_clip_shgrp, ob, mat_geom[i]);
 			}
 		}
 	}
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 7f45e72c713..92a4df27718 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -69,7 +69,11 @@ enum {
 	/* Max number of variation */
 	/* IMPORTANT : Leave it last and set
 	 * it's value accordingly. */
-	VAR_MAT_MAX      = (1 << 6)
+	VAR_MAT_MAX      = (1 << 6),
+	/* 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),
 };
 
 typedef struct EEVEE_PassList {
@@ -438,14 +442,14 @@ EEVEE_LampEngineData *EEVEE_lamp_data_get(Object *ob);
 struct GPUTexture *EEVEE_materials_get_util_tex(void); /* XXX */
 void EEVEE_materials_init(EEVEE_StorageList *stl);
 void EEVEE_materials_cache_init(EEVEE_Data *vedata);
-void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sldata, Object *ob, struct Gwn_Batch *geom);
+void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sldata, Object *ob);
 void EEVEE_materials_cache_finish(EEVEE_Data *vedata);
 struct GPUMaterial *EEVEE_material_world_lightprobe_get(struct Scene *scene, struct World *wo);
 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_lightprobe_get(struct Scene *scene, Material *ma);
 struct GPUMaterial *EEVEE_material_mesh_get(struct Scene *scene, Material *ma, bool use_ao, bool use_bent_normals);
+struct GPUMaterial *EEVEE_material_mesh_depth_get(struct Scene *scene, Material *ma, bool use_hashed_alpha);
 struct GPUMaterial *EEVEE_material_hair_get(struct Scene *scene, Material *ma, bool use_ao, bool use_bent_normals);
 void EEVEE_materials_free(void);
 void EEVEE_draw_default_passes(EEVEE_PassList *psl);
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
index b15c3b6d452..edf13b911dc 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list