From fc28732ba65a57bccd47940249999809c2c93eb0 Mon Sep 17 00:00:00 2001 From: IRIE Shinsuke Date: Wed, 23 Apr 2014 15:02:06 +0900 Subject: Blender Internal: Add material property "Cast" which can disable both ray and buffer shadows. Also refactor: - Material property UI related to shadows - Preparation of OR-ed mode flags (ma->mode_l) of render materials Reviewers: brecht Reviewed By: brecht Differential Revision: https://developer.blender.org/D313 --- .../scripts/startup/bl_ui/properties_material.py | 29 ++++++++++------ source/blender/blenkernel/intern/material.c | 39 +++++++++++++++------- source/blender/blenloader/intern/versioning_270.c | 7 ++++ source/blender/editors/render/render_preview.c | 2 +- source/blender/editors/space_view3d/drawobject.c | 2 +- source/blender/makesdna/DNA_material_types.h | 8 +++++ source/blender/makesrna/intern/rna_material.c | 6 ++++ .../blender/render/extern/include/RE_shader_ext.h | 4 +-- .../blender/render/intern/raytrace/rayobject.cpp | 2 +- source/blender/render/intern/source/shadbuf.c | 4 +-- source/blender/render/intern/source/shadeinput.c | 1 + source/blender/render/intern/source/strand.c | 2 +- source/blender/render/intern/source/zbuf.c | 6 ++-- .../Converter/BL_BlenderDataConversion.cpp | 2 +- 14 files changed, 80 insertions(+), 34 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py index 9e56c269b2b..03a28b609be 100644 --- a/release/scripts/startup/bl_ui/properties_material.py +++ b/release/scripts/startup/bl_ui/properties_material.py @@ -216,15 +216,18 @@ class MATERIAL_PT_pipeline(MaterialButtonsPanel, Panel): sub.active = mat_type sub.prop(mat, "use_sky") sub.prop(mat, "invert_z") + col.prop(mat, "pass_index") col = split.column() col.active = mat_type + col.prop(mat, "use_cast_shadows", text="Cast") col.prop(mat, "use_cast_shadows_only", text="Cast Only") - col.prop(mat, "shadow_cast_alpha", text="Casting Alpha") col.prop(mat, "use_cast_buffer_shadows") + sub = col.column() + sub.active = mat.use_cast_buffer_shadows + sub.prop(mat, "shadow_cast_alpha", text="Casting Alpha") col.prop(mat, "use_cast_approximate") - col.prop(mat, "pass_index") class MATERIAL_PT_diffuse(MaterialButtonsPanel, Panel): @@ -814,24 +817,30 @@ class MATERIAL_PT_shadow(MaterialButtonsPanel, Panel): col = split.column() col.prop(mat, "use_shadows", text="Receive") col.prop(mat, "use_transparent_shadows", text="Receive Transparent") - if simple_material(base_mat): - col.prop(mat, "use_cast_shadows_only", text="Cast Only") - col.prop(mat, "shadow_cast_alpha", text="Casting Alpha") col.prop(mat, "use_only_shadow", text="Shadows Only") sub = col.column() sub.active = mat.use_only_shadow sub.prop(mat, "shadow_only_type", text="") - col = split.column() + if not simple_material(base_mat): + col = split.column() + + col.prop(mat, "use_ray_shadow_bias", text="Auto Ray Bias") + sub = col.column() + sub.active = (not mat.use_ray_shadow_bias) + sub.prop(mat, "shadow_ray_bias", text="Ray Bias") + if simple_material(base_mat): + col = split.column() + + col.prop(mat, "use_cast_shadows", text="Cast") + col.prop(mat, "use_cast_shadows_only", text="Cast Only") col.prop(mat, "use_cast_buffer_shadows") sub = col.column() sub.active = mat.use_cast_buffer_shadows + if simple_material(base_mat): + sub.prop(mat, "shadow_cast_alpha", text="Casting Alpha") sub.prop(mat, "shadow_buffer_bias", text="Buffer Bias") - col.prop(mat, "use_ray_shadow_bias", text="Auto Ray Bias") - sub = col.column() - sub.active = (not mat.use_ray_shadow_bias) - sub.prop(mat, "shadow_ray_bias", text="Ray Bias") if simple_material(base_mat): col.prop(mat, "use_cast_approximate") diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 01bbd1db003..1ee84fb0058 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -203,6 +203,7 @@ void init_material(Material *ma) ma->game.face_orientation = 0; ma->mode = MA_TRACEBLE | MA_SHADBUF | MA_SHADOW | MA_RAYBIAS | MA_TANGENT_STR | MA_ZTRANSP; + ma->mode2 = MA_CASTSHADOW; ma->shade_flag = MA_APPROX_OCCLUSION; ma->preview = NULL; } @@ -1009,16 +1010,6 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb) ma->ambg = ma->amb * amb[1]; ma->ambb = ma->amb * amb[2]; } - /* will become or-ed result of all node modes */ - ma->mode_l = ma->mode; - ma->mode_l &= ~MA_SHLESS; - - if (ma->strand_surfnor > 0.0f) - ma->mode_l |= MA_STR_SURFDIFF; - - /* parses the geom+tex nodes */ - if (ma->nodetree && ma->use_nodes) - ntreeShaderGetTexcoMode(ma->nodetree, r_mode, &ma->texco, &ma->mode_l); /* local group override */ if ((ma->shade_flag & MA_GROUP_LOCAL) && ma->id.lib && ma->group && ma->group->id.lib) { @@ -1043,8 +1034,16 @@ static void init_render_nodetree(bNodeTree *ntree, Material *basemat, int r_mode if (ma != basemat) { do_init_render_material(ma, r_mode, amb); basemat->texco |= ma->texco; - basemat->mode_l |= ma->mode_l & ~(MA_TRANSP | MA_ZTRANSP | MA_RAYTRANSP); } + + basemat->mode_l |= ma->mode & ~(MA_MODE_PIPELINE | MA_SHLESS); + basemat->mode2_l |= ma->mode2 & ~MA_MODE2_PIPELINE; + /* basemat only considered shadeless if all node materials are too */ + if(!(ma->mode & MA_SHLESS)) + basemat->mode_l &= ~MA_SHLESS; + + if (ma->strand_surfnor > 0.0f) + basemat->mode_l |= MA_STR_SURFDIFF; } else if (node->type == NODE_GROUP) init_render_nodetree((bNodeTree *)node->id, basemat, r_mode, amb); @@ -1058,11 +1057,27 @@ void init_render_material(Material *mat, int r_mode, float *amb) do_init_render_material(mat, r_mode, amb); if (mat->nodetree && mat->use_nodes) { + /* mode_l will take the pipeline options from the main material, and the or-ed + * result of non-pipeline options from the nodes. shadeless is an exception, + * mode_l will have it set when all node materials are shadeless. */ + mat->mode_l = (mat->mode & MA_MODE_PIPELINE) | MA_SHLESS; + mat->mode2_l = mat->mode2 & MA_MODE2_PIPELINE; + + /* parses the geom+tex nodes */ + ntreeShaderGetTexcoMode(mat->nodetree, r_mode, &mat->texco, &mat->mode_l); + init_render_nodetree(mat->nodetree, mat, r_mode, amb); if (!mat->nodetree->execdata) mat->nodetree->execdata = ntreeShaderBeginExecTree(mat->nodetree); } + else { + mat->mode_l = mat->mode; + mat->mode2_l = mat->mode2; + + if (mat->strand_surfnor > 0.0f) + mat->mode_l |= MA_STR_SURFDIFF; + } } void init_render_materials(Main *bmain, int r_mode, float *amb) @@ -1087,7 +1102,7 @@ void init_render_materials(Main *bmain, int r_mode, float *amb) init_render_material(ma, r_mode, amb); } - do_init_render_material(&defmaterial, r_mode, amb); + init_render_material(&defmaterial, r_mode, amb); } /* only needed for nodes now */ diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index ab2a7271ba3..a09b02eca78 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -179,4 +179,11 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) linestyle->integration_type = LS_INTEGRATION_MEAN; } } + + if (!DNA_struct_elem_find(fd->filesdna, "Material", "int", "mode2")) { /* will be replaced with version check when other new flag is added to mode2 */ + Material *ma; + + for (ma = main->mat.first; ma; ma = ma->id.next) + ma->mode2 = MA_CASTSHADOW; + } } diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 6eb4c5901cd..0379212354c 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -350,7 +350,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre if (base->object->id.name[2] == 'c') { Material *shadmat = give_current_material(base->object, base->object->actcol); if (shadmat) { - if (mat->mode & MA_SHADBUF) shadmat->septex = 0; + if (mat->mode2 & MA_CASTSHADOW) shadmat->septex = 0; else shadmat->septex |= 1; } } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index dc1d762d904..98f728ea26c 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -3768,7 +3768,7 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3 if (v3d->flag2 & V3D_RENDER_SHADOW) { for (i = 0; i < ob->totcol; ++i) { Material *ma = give_current_material(ob, i); - if (ma && !(ma->mode & MA_SHADBUF)) { + if (ma && !(ma->mode2 & MA_CASTSHADOW)) { return true; } } diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index a6478f2ae69..6bcbabc226d 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -117,6 +117,7 @@ typedef struct Material { short shade_flag; /* like Cubic interpolation */ int mode, mode_l; /* mode_l is the or-ed result of all layer modes */ + int mode2, mode2_l; /* additional mode flags */ short flarec, starc, linec, ringc; float hasize, flaresize, subsize, flareboost; float strand_sta, strand_end, strand_ease, strand_surfnor; @@ -278,6 +279,13 @@ typedef struct Material { #define MA_STR_SURFDIFF 0x80000000 #define MA_MODE_MASK 0x6fffffff /* all valid mode bits */ +#define MA_MODE_PIPELINE (MA_TRANSP | MA_ZTRANSP | MA_RAYTRANSP \ + | MA_TRACEBLE | MA_FULL_OSA | MA_ENV | MA_ZINV \ + | MA_ONLYCAST | MA_SHADBUF) + +/* mode2 (is int) */ +#define MA_CASTSHADOW (1 << 0) +#define MA_MODE2_PIPELINE (MA_CASTSHADOW) /* mapflag */ #define MA_MAPFLAG_UVPROJECT (1 << 0) diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 44fdfe73015..061f1595c8c 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -1907,6 +1907,12 @@ void RNA_def_material(BlenderRNA *brna) "Replace the object's base alpha value with alpha from UV map image textures"); RNA_def_property_update(prop, 0, "rna_Material_update"); + prop = RNA_def_property(srna, "use_cast_shadows", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "mode2", MA_CASTSHADOW); + RNA_def_property_ui_text(prop, "Cast Shadows", + "Allow this material to cast shadows"); + RNA_def_property_update(prop, 0, "rna_Material_update"); + prop = RNA_def_property(srna, "use_cast_shadows_only", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_ONLYCAST); RNA_def_property_ui_text(prop, "Cast Shadows Only", diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index 70e3edccb2c..da847d235f2 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -81,7 +81,7 @@ struct ShadeInputCopy { short osatex; float vn[3], vno[3]; /* actual render normal, and a copy to restore it */ float n1[3], n2[3], n3[3]; /* vertex normals, corrected */ - int mode; /* base material mode (OR-ed result of entire node tree) */ + int mode, mode2; /* base material mode (OR-ed result of entire node tree) */ }; typedef struct ShadeInputUV { @@ -113,7 +113,7 @@ typedef struct ShadeInput { short osatex; float vn[3], vno[3]; /* actual render normal, and a copy to restore it */ float n1[3], n2[3], n3[3]; /* vertex normals, corrected */ - int mode; /* base material mode (OR-ed result of entire node tree) */ + int mode, mode2; /* base material mode (OR-ed result of entire node tree) */ /* internal face coordinates */ float u, v, dx_u, dx_v, dy_u, dy_v; diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp index 1ef44bbdd17..de6b9139363 100644 --- a/source/blender/render/intern/raytrace/rayobject.cpp +++ b/source/blender/render/intern/raytrace/rayobject.cpp @@ -119,7 +119,7 @@ MALWAYS_INLINE int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRe if (is->mode == RE_RAY_MIRROR) return !(vlr->mat->mode & MA_ONLYCAST); else - return (is->lay & obi->lay); + return (vlr->mat->mode2 & MA_CASTSHADOW) && (is->lay & obi->lay); } MALWAYS_INLINE int vlr_check_intersect_solid(Isect *UNUSED(is), ObjectInstanceRen *UNUSED(obi), VlakRen *vlr) diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index 194397bb19c..ed820737a0f 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -660,7 +660,7 @@ static void shadowbuf_autoclip(Render *re, LampRen *lar) if (vlr->mat!= ma) { ma= vlr->mat; ok= 1; - if ((ma->mode & MA_SHADBUF)==0) ok= 0; + if ((ma->mode2 & MA_CASTSHADOW)==0 || (ma->mode & MA_SHADBUF)==0) ok= 0; } if (ok && (obi->lay & lay)) { @@ -2013,7 +2013,7 @@ static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root) if (vlr->mat!= ma) { ma= vlr->mat; ok= 1; - if ((ma->mode & MA_SHADBUF)==0) ok= 0; + if ((ma->mode2 & MA_CASTSHADOW)==0 || (ma->mode & MA_SHADBUF)==0) ok= 0; if (ma->material_type == MA_TYPE_WIRE) ok= 0; zspanstrand.shad_alpha= zspan.shad_alpha= ma->shad_alpha; } diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index 90e5def64f6..95e6cbd6354 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -276,6 +276,7 @@ void shade_input_set_triangle_i(ShadeInput *shi, ObjectInstanceRen *obi, VlakRen shi->osatex = (shi->mat->texco & TEXCO_OSA); shi->mode = shi->mat->mode_l; /* or-ed result for all nodes */ + shi->mode2 = shi->mat->mode2_l; /* facenormal copy, can get flipped */ shi->flippednor = 0; diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index 9a6a2b8ec9c..190651645db 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -862,7 +862,7 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBa /* test if we should skip it */ ma = obr->strandbuf->ma; - if (shadow && !(ma->mode & MA_SHADBUF)) + if (shadow && (!(ma->mode2 & MA_CASTSHADOW) || !(ma->mode & MA_SHADBUF))) continue; else if (!shadow && (ma->mode & MA_ONLYCAST)) continue; diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index d50d53b5f53..8dc4a6c65de 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -2367,7 +2367,7 @@ void zbuffer_shadow(Render *re, float winmat[4][4], LampRen *lar, int *rectz, in if (vlr->mat!= ma) { ma= vlr->mat; ok= 1; - if ((ma->mode & MA_SHADBUF)==0) ok= 0; + if ((ma->mode2 & MA_CASTSHADOW)==0 || (ma->mode & MA_SHADBUF)==0) ok= 0; } if (ok && (obi->lay & lay) && !(vlr->flag & R_HIDDEN)) { @@ -2420,7 +2420,7 @@ void zbuffer_shadow(Render *re, float winmat[4][4], LampRen *lar, int *rectz, in if (sseg.buffer->ma!= ma) { ma= sseg.buffer->ma; ok= 1; - if ((ma->mode & MA_SHADBUF)==0) ok= 0; + if ((ma->mode2 & MA_CASTSHADOW)==0 || (ma->mode & MA_SHADBUF)==0) ok= 0; } if (ok && (sseg.buffer->lay & lay)) { @@ -3348,7 +3348,7 @@ static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase * if (vlr->mat!=ma) { ma= vlr->mat; if (shadow) - dofill= (ma->mode & MA_SHADBUF); + dofill= (ma->mode2 & MA_CASTSHADOW) && (ma->mode & MA_SHADBUF); else dofill= (((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP)) && !(ma->mode & MA_ONLYCAST)); } diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index b5c9f7a9abe..3501addc00f 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -612,7 +612,7 @@ static bool ConvertMaterial( material->ras_mode |= ( mat->game.flag & GEMAT_BACKCULL )?0:TWOSIDED; // cast shadows? - material->ras_mode |= ( mat->mode & MA_SHADBUF )?CAST_SHADOW:0; + material->ras_mode |= ( (mat->mode2 & MA_CASTSHADOW) && (mat->mode & MA_SHADBUF) )?CAST_SHADOW:0; // only shadows? material->ras_mode |= ( mat->mode & MA_ONLYCAST )?ONLY_SHADOW:0; -- cgit v1.2.3