Bugfix & Feature fix: Only Shadow Material options
Patch from Miika Hämäläinen. The old Material "Only Shadow" used an ancient 'best guess' formula using Lamp Distance and some averaging for converting shadow values to alpha. A couple of bug reporters already complained about the not very predictable renders. Miika fixed this by adding two new options, to only give the true shadow factor exclusively, or to give a result including light intensity values. More info: http://projects.blender.org/tracker/index.php?func=detail&aid=26413&group_id=9&atid=127
This commit is contained in:
parent
3d05311d3c
commit
3a43e08deb
|
@ -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'}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue