diff options
author | Ton Roosendaal <ton@blender.org> | 2011-03-08 19:08:43 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2011-03-08 19:08:43 +0300 |
commit | 3a43e08deb4354175e5d40a37dc4dafea476176b (patch) | |
tree | 5a99ad3e6aa7dac70f344ccbf97dfc1fd0adb64a /source/blender/render | |
parent | 3d05311d3cfa0b0fd0cde284ec59880179e292a1 (diff) |
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
Diffstat (limited to 'source/blender/render')
-rw-r--r-- | source/blender/render/intern/source/shadeoutput.c | 89 |
1 files changed, 72 insertions, 17 deletions
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; + } } } } |