diff options
-rw-r--r-- | release/scripts/ui/properties_material.py | 6 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_material_types.h | 8 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_material.c | 12 | ||||
-rw-r--r-- | source/blender/render/intern/source/shadeoutput.c | 89 |
4 files changed, 96 insertions, 19 deletions
diff --git a/release/scripts/ui/properties_material.py b/release/scripts/ui/properties_material.py index d169629b6f6..5554390e3a8 100644 --- a/release/scripts/ui/properties_material.py +++ b/release/scripts/ui/properties_material.py @@ -752,10 +752,13 @@ class MATERIAL_PT_shadow(MaterialButtonsPanel, bpy.types.Panel): col = split.column() col.prop(mat, "use_shadows", text="Receive") col.prop(mat, "use_transparent_shadows", text="Receive Transparent") - col.prop(mat, "use_only_shadow", text="Shadows Only") 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="ShadowsOnly") + sub = col.column() + sub.active = mat.use_only_shadow + sub.prop(mat, "shadow_only_type", text="") col = split.column() if simple_material(base_mat): @@ -771,6 +774,7 @@ class MATERIAL_PT_shadow(MaterialButtonsPanel, bpy.types.Panel): col.prop(mat, "use_cast_approximate") + class MATERIAL_PT_transp_game(MaterialButtonsPanel, bpy.types.Panel): bl_label = "Transparency" bl_options = {'DEFAULT_CLOSED'} diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index 860da1d80a4..1489593f7f6 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -160,7 +160,8 @@ typedef struct Material { short sss_flag, sss_preset; int mapto_textured; /* render-time cache to optimise texture lookups */ - int pad4; + short shadowonly_flag; /* "shadowsonly" type */ + short pad; ListBase gpumaterial; /* runtime */ } Material; @@ -238,6 +239,11 @@ typedef struct Material { #define MA_RAYMIR_FADETOSKY 0 #define MA_RAYMIR_FADETOMAT 1 +/* shadowonly_flag */ +#define MA_SO_OLD 0 +#define MA_SO_SHADOW 1 +#define MA_SO_SHADED 2 + /* shade_flag */ #define MA_CUBIC 1 #define MA_OBCOLOR 2 diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index ce568c2af63..179b0770322 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -1583,6 +1583,12 @@ void RNA_def_material(BlenderRNA *brna) {MA_SPHERE_A, "SPHERE_A", ICON_MAT_SPHERE_SKY, "Flat", "Preview type: Large sphere with sky"}, {0, NULL, 0, NULL, NULL}}; + static EnumPropertyItem prop_shadows_only_items[] = { + {MA_SO_OLD, "SO_OLD", 0, "Shadow and Distance", ""}, + {MA_SO_SHADOW, "SO_SHADOW", 0, "Shadow Only", ""}, + {MA_SO_SHADED, "SO_SHADED", 0, "Shadow and Shading", ""}, + {0, NULL, 0, NULL, NULL}}; + srna= RNA_def_struct(brna, "Material", "ID"); RNA_def_struct_ui_text(srna, "Material", "Material datablock to defined the appearance of geometric objects for rendering"); RNA_def_struct_ui_icon(srna, ICON_MATERIAL_DATA); @@ -1713,6 +1719,12 @@ void RNA_def_material(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_ONLYSHADOW); RNA_def_property_ui_text(prop, "Only Shadow", "Renders shadows as the material's alpha value, making materials transparent except for shadowed areas"); RNA_def_property_update(prop, 0, "rna_Material_update"); + + prop= RNA_def_property(srna, "shadow_only_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "shadowonly_flag"); + RNA_def_property_enum_items(prop, prop_shadows_only_items); + RNA_def_property_ui_text(prop, "Shadow Type", "How to draw shadows"); + RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "use_face_texture", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_FACETEXTURE); diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 58284534ce9..0081f809a09 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -1502,10 +1502,10 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr) float inpr, lv[3]; float *view, shadfac[4]; float ir, accum, visifac, lampdist; + float shaded = 0.0f, lightness = 0.0f; view= shi->view; - accum= ir= 0.0f; lights= get_lights(shi); @@ -1522,27 +1522,69 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr) if(lar->shb || (lar->mode & LA_SHAD_RAY)) { visifac= lamp_get_visibility(lar, shi->co, lv, &lampdist); if(visifac <= 0.0f) { - ir+= 1.0f; - accum+= 1.0f; + if (shi->mat->shadowonly_flag == MA_SO_OLD) { + ir+= 1.0f; + accum+= 1.0f; + } continue; } inpr= INPR(shi->vn, lv); if(inpr <= 0.0f) { - ir+= 1.0f; - accum+= 1.0f; + if (shi->mat->shadowonly_flag == MA_SO_OLD) { + ir+= 1.0f; + accum+= 1.0f; + } continue; - } + } + lamp_get_shadow(lar, shi, inpr, shadfac, shi->depth); - ir+= 1.0f; - accum+= (1.0f-visifac) + (visifac)*rgb_to_grayscale(shadfac)*shadfac[3]; + if (shi->mat->shadowonly_flag == MA_SO_OLD) { + /* Old "Shadows Only" */ + ir+= 1.0f; + accum+= (1.0f-visifac) + (visifac)*rgb_to_grayscale(shadfac)*shadfac[3]; + } + else { + ir+= lar->energy; + shaded += rgb_to_grayscale(shadfac)*shadfac[3] * visifac * lar->energy; + + if (shi->mat->shadowonly_flag == MA_SO_SHADOW) { + lightness += visifac * lar->energy; + } + } } } + + /* Apply shadows as alpha */ if(ir>0.0f) { - accum/= ir; - shr->alpha= (shi->mat->alpha)*(1.0f-accum); + if (shi->mat->shadowonly_flag == MA_SO_OLD) { + accum = 1.0f - accum/ir; + } + else { + shaded/= ir; + lightness/= ir; + + if (shi->mat->shadowonly_flag == MA_SO_SHADOW) { + if (lightness > 0.0f) { + /* Get shadow value from between 0.0f and non-shadowed lightness */ + accum = (lightness - shaded) / (lightness); + } + else { + accum = 0.0f; + } + } + else { /* shadowonly_flag == MA_SO_SHADED */ + /* Use shaded value */ + accum = 1.0f - shaded; + }} + + shr->alpha= (shi->mat->alpha)*(accum); + } + else { + /* If "fully shaded", use full alpha even on areas that have no lights */ + if (shi->mat->shadowonly_flag == MA_SO_SHADED) shr->alpha=1.0f; + else shr->alpha= 0.f; } - else shr->alpha= 0.f; } /* quite disputable this... also note it doesn't mirror-raytrace */ @@ -1551,18 +1593,31 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr) if(R.wrld.mode & WO_AMB_OCC) { f= R.wrld.aoenergy*shi->amb; - + if(R.wrld.aomix==WO_AOADD) { - f= f*(1.0f - rgb_to_grayscale(shi->ao)); - shr->alpha= (shr->alpha + f)*f; + if (shi->mat->shadowonly_flag == MA_SO_OLD) { + f= f*(1.0f - rgb_to_grayscale(shi->ao)); + shr->alpha= (shr->alpha + f)*f; + } + else { + shr->alpha -= f*rgb_to_grayscale(shi->ao); + if (shr->alpha<0.0f) shr->alpha=0.0f; + } } - else + else /* AO Multiply */ shr->alpha= (1.0f - f)*shr->alpha + f*(1.0f - (1.0f - shr->alpha)*rgb_to_grayscale(shi->ao)); } if(R.wrld.mode & WO_ENV_LIGHT) { - f= R.wrld.ao_env_energy*shi->amb*(1.0f - rgb_to_grayscale(shi->env)); - shr->alpha= (shr->alpha + f)*f; + if (shi->mat->shadowonly_flag == MA_SO_OLD) { + f= R.wrld.ao_env_energy*shi->amb*(1.0f - rgb_to_grayscale(shi->env)); + shr->alpha= (shr->alpha + f)*f; + } + else { + f= R.wrld.ao_env_energy*shi->amb; + shr->alpha -= f*rgb_to_grayscale(shi->env); + if (shr->alpha<0.0f) shr->alpha=0.0f; + } } } } |