Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2011-03-08 19:08:43 +0300
committerTon Roosendaal <ton@blender.org>2011-03-08 19:08:43 +0300
commit3a43e08deb4354175e5d40a37dc4dafea476176b (patch)
tree5a99ad3e6aa7dac70f344ccbf97dfc1fd0adb64a /source/blender/render
parent3d05311d3cfa0b0fd0cde284ec59880179e292a1 (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.c89
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;
+ }
}
}
}