diff options
author | Matt Ebb <matt@mke3.net> | 2010-11-29 10:07:08 +0300 |
---|---|---|
committer | Matt Ebb <matt@mke3.net> | 2010-11-29 10:07:08 +0300 |
commit | 5fe2a16385ca343c6230a87e39e38055da1caa39 (patch) | |
tree | 716276660e3e971a557b9faeade98fab44e4b5a4 /source | |
parent | e8397e6193452f6e93a19c5aa31d5effaff54f25 (diff) |
Fix [#20241] half-transparent objects in volume have no shadow.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/render/intern/source/rayshade.c | 9 | ||||
-rw-r--r-- | source/blender/render/intern/source/volumetric.c | 24 |
2 files changed, 23 insertions, 10 deletions
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index d2e9765c722..2859862c9e6 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -1591,8 +1591,13 @@ static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int /* mix colors based on shadfac (rgb + amount of light factor) */ addAlphaLight(is->col, shr.diff, shr.alpha, d*shi.mat->filter); } else if (shi.mat->material_type == MA_TYPE_VOLUME) { - QUATCOPY(is->col, shr.combined); - is->col[3] = 1.f; + const float a = is->col[3]; + + is->col[0] = a*is->col[0] + shr.alpha*shr.combined[0]; + is->col[1] = a*is->col[1] + shr.alpha*shr.combined[1]; + is->col[2] = a*is->col[2] + shr.alpha*shr.combined[2]; + + is->col[3] = (1.0 - shr.alpha)*a; } if(depth>0 && is->col[3]>0.0f) { diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index f791f8728d0..1b095269416 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -115,13 +115,6 @@ static float vol_get_shadow(ShadeInput *shi, LampRen *lar, float *co) static int vol_get_bounds(ShadeInput *shi, float *co, float *vec, float *hitco, Isect *isect, int intersect_type) { - /* XXX TODO - get raytrace max distance from object instance's bounding box */ - /* need to account for scaling only, but keep coords in camera space... - * below code is WIP and doesn't work! - sub_v3_v3v3(bb_dim, shi->obi->obr->boundbox[1], shi->obi->obr->boundbox[2]); - mul_m3_v3(shi->obi->nmat, bb_dim); - maxsize = len_v3(bb_dim); - */ VECCOPY(isect->start, co); VECCOPY(isect->vec, vec ); @@ -743,6 +736,7 @@ void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct float tr[3] = {1.0,1.0,1.0}; Isect is; float *startco, *endco; + int intersect_type = VOL_BOUNDS_DEPTH; memset(shr, 0, sizeof(ShadeResult)); @@ -751,10 +745,12 @@ void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct if (shi->flippednor) { startco = last_is->start; endco = shi->co; + intersect_type = VOL_BOUNDS_SS; } + /* trace to find a backface, the other side bounds of the volume */ /* (ray intersect ignores front faces here) */ - else if (vol_get_bounds(shi, shi->co, shi->view, hitco, &is, VOL_BOUNDS_DEPTH)) { + else if (vol_get_bounds(shi, shi->co, shi->view, hitco, &is, intersect_type)) { startco = shi->co; endco = hitco; } @@ -765,9 +761,21 @@ void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct } vol_get_transmittance(shi, tr, startco, endco); + + + /* if we hit another face in the same volume bounds */ + /* shift raytrace coordinates to the hit point, to avoid shading volume twice */ + /* due to idiosyncracy in ray_trace_shadow_tra() */ + if (is.hit.ob == shi->obi) { + copy_v3_v3(shi->co, hitco); + last_is->labda -= is.labda; + shi->vlr = (VlakRen *)is.hit.face; + } + copy_v3_v3(shr->combined, tr); shr->combined[3] = 1.0f - luminance(tr); + shr->alpha = shr->combined[3]; } |