Blender Internal: Add material property "Cast" which can disable both ray and buffer...
authorIRIE Shinsuke <irieshinsuke@yahoo.co.jp>
Wed, 23 Apr 2014 06:02:06 +0000 (15:02 +0900)
committerIRIE Shinsuke <irieshinsuke@yahoo.co.jp>
Wed, 23 Apr 2014 06:03:34 +0000 (15:03 +0900)
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

14 files changed:
release/scripts/startup/bl_ui/properties_material.py
source/blender/blenkernel/intern/material.c
source/blender/blenloader/intern/versioning_270.c
source/blender/editors/render/render_preview.c
source/blender/editors/space_view3d/drawobject.c
source/blender/makesdna/DNA_material_types.h
source/blender/makesrna/intern/rna_material.c
source/blender/render/extern/include/RE_shader_ext.h
source/blender/render/intern/raytrace/rayobject.cpp
source/blender/render/intern/source/shadbuf.c
source/blender/render/intern/source/shadeinput.c
source/blender/render/intern/source/strand.c
source/blender/render/intern/source/zbuf.c
source/gameengine/Converter/BL_BlenderDataConversion.cpp

index 9e56c269b2b0b425039670c25bbe9d69d6536a55..03a28b609be1a381d66c264c8107e02aa8873c63 100644 (file)
@@ -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")
 
index 01bbd1db0037c02d729ac667d1c5e10af2219b3f..1ee84fb00583196e92625e580227a9485b388cfa 100644 (file)
@@ -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 */
index ab2a7271ba39132bcf57be641fe95afa73800547..a09b02eca781322c9194e6685cfaf6ca2b1c2316 100644 (file)
@@ -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;
+       }
 }
index 6eb4c5901cd0fcba4a924295c817010c9ad3f90f..0379212354ce387333ef0d1b8eb4c5d2ffc3a92f 100644 (file)
@@ -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;
                                                        }
                                                }
index dc1d762d9049ca49377bb2aadaa000881779ded1..98f728ea26cbdf3464895971bf7c8d579645ca76 100644 (file)
@@ -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;
                        }
                }
index a6478f2ae69b8372f2b754d4cf60fe3c10c2af34..6bcbabc226df7d64fb6e26ed7aac8db0ea7d3fe9 100644 (file)
@@ -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)
index 44fdfe73015a80285bdb92acebd47f808e5917cc..061f1595c8cadb7f83dccbc3c2fa7f64016588ca 100644 (file)
@@ -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",
index 70e3edccb2c431879d1bba4ee6ce3aad9a45f085..da847d235f2daa163bdbb25b577d1dd6cc0c7650 100644 (file)
@@ -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;
index 1ef44bbdd175d7fa4342bbca17124dcf079b08a7..de6b913936390171af5dcacbed52520d371acb6e 100644 (file)
@@ -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)
index 194397bb19cede3224c1ec6765c0338b7c1d050f..ed820737a0f6a94e88899ffcd49fa457842d7f71 100644 (file)
@@ -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;
                        }
index 90e5def64f69a3957f33d7a7e3c949dba73840b7..95e6cbd6354f655a7d47e855f2b12e04603b9ad8 100644 (file)
@@ -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;
index 9a6a2b8ec9cc723230eae216e66ce1a0d73fd90f..190651645db0b3450b522aec67cd8e4e8eb811e7 100644 (file)
@@ -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;
index d50d53b5f530d39bd08f252f17d7c81c9041c084..8dc4a6c65de0276c6bbc6c46c5f79bc287a9e0fc 100644 (file)
@@ -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));
                        }
index b5c9f7a9abe10b03f2868a643b07ac49203d56f5..3501addc00fec591cf95983cff4210a839a4c1d7 100644 (file)
@@ -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;