diff options
author | Ton Roosendaal <ton@blender.org> | 2006-09-25 13:35:04 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2006-09-25 13:35:04 +0400 |
commit | 2662c7ae79e60ffad00ef9c4a5ad1782b378c34a (patch) | |
tree | 9e8dd9f70788938172e1e98a27666aeff18721ad /source | |
parent | aec9f8969c96b1c8d6e48c20c191c2040659c5e8 (diff) |
Bugfix #5034
When using new Shadowbuffer option "Auto clip", the clipping planes could
become so narrow that sampling code - using ints - could result in
overflows (sign flip). This especially for small shadow buffers with high
bias values.
This fix adds an extra check in shadow sampling for such overflows.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/render/intern/source/shadbuf.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index 90962fd8e41..b9e2562a6c0 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -338,15 +338,17 @@ static void shadowbuf_autoclip(Render *re, LampRen *lar) /* set clipping min and max */ if(minz < maxz) { - float delta= (maxz - minz)*0.02f; /* threshold to prevent precision issues */ + float delta= (maxz - minz); /* threshold to prevent precision issues */ + //printf("minz %f maxz %f delta %f\n", minz, maxz, delta); if(lar->bufflag & LA_SHADBUF_AUTO_START) - lar->shb->d= minz - delta; + lar->shb->d= minz - delta*0.02f; /* 0.02 is arbitrary... needs more thinking! */ if(lar->bufflag & LA_SHADBUF_AUTO_END) - lar->shb->clipend= maxz + delta; + lar->shb->clipend= maxz + delta*0.1f; /* bias was calculated as percentage, we scale it to prevent animation issues */ - delta= (lar->clipend-lar->clipsta)/(maxz-minz); + delta= (lar->clipend-lar->clipsta)/(lar->shb->clipend-lar->shb->d); + //printf("bias delta %f\n", delta); lar->shb->bias= (int) (delta*(float)lar->shb->bias); } } @@ -508,10 +510,11 @@ static float readshadowbuf(ShadBuf *shb, ShadSampleBuf *shsample, int bias, int zsamp= (int) rz; } - /* if(zsamp >= 0x7FFFFE00) return 1.0; */ /* no shaduw when sampling at eternal distance */ - + /* tricky stuff here; we use ints which can overflow easily with bias values */ + if(zsamp > zs) return 1.0; /* absolute no shadow */ - else if( zsamp < zs-bias) return 0.0 ; /* absolute in shadow */ + else if(zs < - 0x7FFFFE00 + bias) return 1.0; /* extreme close to clipstart */ + else if(zsamp < zs-bias) return 0.0 ; /* absolute in shadow */ else { /* soft area */ temp= ( (float)(zs- zsamp) )/(float)bias; |