Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2017-07-09 13:01:29 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-07-11 13:39:35 +0300
commit05bef13b53e93978716aff8e2efba7ddf72264ed (patch)
treef1ff4fbf5a7d4c5e1a8f934b17fa47256d40177a
parente2c0197a96dbac2aee519fbfb142441c6aed0963 (diff)
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.
-rw-r--r--release/scripts/startup/bl_ui/properties_material.py21
-rw-r--r--source/blender/blenkernel/intern/material.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c6
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c93
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h10
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl27
-rw-r--r--source/blender/draw/engines/eevee/shaders/prepass_frag.glsl82
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl10
-rw-r--r--source/blender/makesdna/DNA_material_types.h13
-rw-r--r--source/blender/makesrna/intern/rna_material.c22
11 files changed, 263 insertions, 25 deletions
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
@@ -19,8 +19,6 @@ uniform vec4 viewvecs[2];
/* ------- Structures -------- */
#ifdef VOLUMETRICS
-#define NODETREE_EXEC
-
struct Closure {
vec3 absorption;
vec3 scatter;
@@ -49,12 +47,35 @@ Closure closure_add(Closure cl1, Closure cl2)
cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */
return cl;
}
+#else
-Closure nodetree_exec(void); /* Prototype */
+struct Closure {
+ vec3 radiance;
+ float opacity;
+};
+
+#define CLOSURE_DEFAULT Closure(vec3(0.0), 0.0)
+
+Closure closure_mix(Closure cl1, Closure cl2, float fac)
+{
+ Closure cl;
+ cl.radiance = mix(cl1.radiance, cl2.radiance, fac);
+ cl.opacity = mix(cl1.opacity, cl2.opacity, fac);
+ return cl;
+}
+Closure closure_add(Closure cl1, Closure cl2)
+{
+ Closure cl;
+ cl.radiance = cl1.radiance + cl2.radiance;
+ cl.opacity = cl1.opacity + cl2.opacity;
+ return cl;
+}
#endif /* VOLUMETRICS */
+Closure nodetree_exec(void); /* Prototype */
+
struct LightData {
vec4 position_influence; /* w : InfluenceRadius */
diff --git a/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl b/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl
index 6317dcea0e9..f921d56e3bc 100644
--- a/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl
@@ -1,7 +1,85 @@
+#ifdef USE_ALPHA_HASH
+
+/* From the paper "Hashed Alpha Testing" by Chris Wyman and Morgan McGuire */
+float hash(vec2 a) {
+ return fract(1e4 * sin(17.0 * a.x + 0.1 * a.y) * (0.1 + abs(sin(13.0 * a.y + a.x))));
+}
+
+float hash3d(vec3 a) {
+ return hash(vec2(hash(a.xy), a.z));
+}
+
+//uniform float hashScale;
+float hashScale = 0.001;
+
+float hashed_alpha_threshold(vec3 co)
+{
+ /* Find the discretized derivatives of our coordinates. */
+ float max_deriv = max(length(dFdx(co)), length(dFdy(co)));
+ float pix_scale = 1.0 / (hashScale * max_deriv);
+
+ /* Find two nearest log-discretized noise scales. */
+ float pix_scale_log = log2(pix_scale);
+ vec2 pix_scales;
+ pix_scales.x = exp2(floor(pix_scale_log));
+ pix_scales.y = exp2(ceil(pix_scale_log));
+
+ /* Compute alpha thresholds at our two noise scales. */
+ vec2 alpha;
+ alpha.x = hash3d(floor(pix_scales.x * co));
+ alpha.y = hash3d(floor(pix_scales.y * co));
+
+ /* Factor to interpolate lerp with. */
+ float fac = fract(log2(pix_scale));
+
+ /* Interpolate alpha threshold from noise at two scales. */
+ float x = mix(alpha.x, alpha.y, fac);
+
+ /* Pass into CDF to compute uniformly distrib threshold. */
+ float a = min(fac, 1.0 - fac);
+ float one_a = 1.0 - a;
+ float denom = 1.0 / (2 * a * one_a);
+ float one_x = (1 - x);
+ vec3 cases = vec3(
+ (x * x) * denom,
+ (x - 0.5 * a) / one_a,
+ 1.0 - (one_x * one_x * denom)
+ );
+
+ /* Find our final, uniformly distributed alpha threshold. */
+ float threshold = (x < one_a) ? ((x < a) ? cases.x : cases.y) : cases.z;
+
+ /* Avoids threshold == 0. */
+ threshold = clamp(threshold, 1.0e-6, 1.0);
+
+ return threshold;
+}
+
+#endif
+
+#ifdef USE_ALPHA_CLIP
+uniform float alphaThreshold;
+#endif
+
void main()
{
/* For now do nothing.
- * In the future, output object motion blur.
- * This pass could also be controlled but nodetree (pixel depth offset, stochastic transparency). */
+ * In the future, output object motion blur. */
+
+#if defined(USE_ALPHA_HASH) || defined(USE_ALPHA_CLIP)
+#define NODETREE_EXEC
+
+ Closure cl = nodetree_exec();
+
+#if defined(USE_ALPHA_HASH)
+ /* Hashed Alpha Testing */
+ if (cl.opacity < hashed_alpha_threshold(worldPosition))
+ discard;
+#elif defined(USE_ALPHA_CLIP)
+ /* Alpha clip */
+ if (cl.opacity <= alphaThreshold)
+ discard;
+#endif
+#endif
}
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
index a99769c7fec..7f44dd53163 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
@@ -1,6 +1,8 @@
#ifdef VOLUMETRICS
+#define NODETREE_EXEC
+
#define VOLUMETRIC_INTEGRATION_MAX_STEP 256
#define VOLUMETRIC_SHADOW_MAX_STEP 128
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index e9f7fb338c9..3235dad8d04 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -14,7 +14,7 @@ uniform vec4 CameraTexCoFactors;
/* Old glsl mode compat. */
-#ifndef NODETREE_EXEC
+#ifndef CLOSURE_DEFAULT
struct Closure {
vec3 radiance;
@@ -41,7 +41,7 @@ Closure closure_add(Closure cl1, Closure cl2)
Closure nodetree_exec(void); /* Prototype */
-#endif /* NODETREE_EXEC */
+#endif /* CLOSURE_DEFAULT */
/* Converters */
@@ -2890,7 +2890,7 @@ void node_bsdf_transparent(vec4 color, out Closure result)
{
/* this isn't right */
result.radiance = color.rgb;
- result.opacity = 0.0;
+ result.opacity = color.a;
}
void node_bsdf_velvet(vec4 color, float sigma, vec3 N, out Closure result)
@@ -4031,7 +4031,11 @@ void node_eevee_specular(
void node_output_eevee_material(Closure surface, out Closure result)
{
+#if defined(USE_ALPHA_HASH) || defined(USE_ALPHA_CLIP)
+ result = surface;
+#else
result = Closure(surface.radiance, length(viewPosition));
+#endif
}
#endif /* EEVEE_ENGINE */
diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h
index 09a4e42cb8f..fc0f4df4170 100644
--- a/source/blender/makesdna/DNA_material_types.h
+++ b/source/blender/makesdna/DNA_material_types.h
@@ -211,6 +211,10 @@ typedef struct Material {
char nmap_tangent_names[9][64]; /* [MAX_MTFACE+1][MAX_NAME]; +1 for empty name */
int nmap_tangent_names_count, pad5;
+ /* Transparency */
+ float alpha_threshold;
+ char blend_method, pad6[3];
+
/* image to use for image/uv space, also bake target
* (not to be used shading/rendering pipeline, this is editor featyure only!). */
struct Image *edit_image;
@@ -491,5 +495,14 @@ typedef struct Material {
#define MA_VOL_SHADE_MULTIPLE 3
#define MA_VOL_SHADE_SHADEDPLUSMULTIPLE 4
+/* blend_method */
+enum {
+ MA_BM_SOLID,
+ MA_BM_ADD,
+ MA_BM_MULTIPLY,
+ MA_BM_CLIP,
+ MA_BM_HASHED,
+};
+
#endif
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index e60832d86e6..a3c1ae7378e 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -1805,6 +1805,15 @@ void RNA_def_material(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem prop_eevee_blend_items[] = {
+ {MA_BM_SOLID, "OPAQUE", 0, "Opaque", "Render surface without transparency"},
+ // {MA_BM_ADD, "ADD", 0, "Additive", "Render surface and blend the result with additive blending"},
+ // {MA_BM_MULTIPLY, "MULTIPLY", 0, "Multiply", "Render surface and blend the result with multiplicative blending"},
+ {MA_BM_CLIP, "CLIP", 0, "Alpha Clip", "Use the alpha threshold to clip the visibility (binary visibility)"},
+ {MA_BM_HASHED, "HASHED", 0, "Alpha Hashed", "Use noise to dither the binary visibility (works well with multi-samples)"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
srna = RNA_def_struct(brna, "Material", "ID");
RNA_def_struct_ui_text(srna, "Material",
"Material data-block to define the appearance of geometric objects for rendering");
@@ -1827,7 +1836,18 @@ void RNA_def_material(BlenderRNA *brna)
RNA_def_property_enum_items(prop, transparency_items);
RNA_def_property_ui_text(prop, "Transparency Method", "Method to use for rendering transparency");
RNA_def_property_update(prop, 0, "rna_Material_update");
-
+
+ /* Blending (only Eevee for now) */
+ prop = RNA_def_property(srna, "blend_method", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, prop_eevee_blend_items);
+ RNA_def_property_ui_text(prop, "Blend Mode", "Blend Mode for Transparent Faces");
+ RNA_def_property_update(prop, 0, "rna_Material_draw_update");
+
+ prop = RNA_def_property(srna, "alpha_threshold", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_range(prop, 0, 1);
+ RNA_def_property_ui_text(prop, "Clip Threshold", "A pixel is rendered only if its alpha value is above this threshold");
+ RNA_def_property_update(prop, 0, "rna_Material_update");
+
/* For Preview Render */
prop = RNA_def_property(srna, "preview_render_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "pr_type");