Work on shadowbuffer system... right now only new filtertypes for
sampling have been activated for UI. Check the pictures here: http://www.blender.org/bf/filters/index2.html I also did do tests with anti-aliased shadowbuffers: http://www.blender.org/bf/filters/index3.html But this needs more thinking over still...
This commit is contained in:
@@ -56,12 +56,12 @@ typedef struct Lamp {
|
||||
float haint;
|
||||
float att1, att2;
|
||||
|
||||
short bufsize, samp;
|
||||
float clipsta, clipend, shadspotsize;
|
||||
float bias, soft;
|
||||
short bufsize, samp, buffers, filtertype, pad;
|
||||
|
||||
short ray_samp, ray_sampy, ray_sampz, ray_samp_type;
|
||||
short area_shape, pad;
|
||||
short area_shape;
|
||||
float area_size, area_sizey, area_sizez;
|
||||
|
||||
/* texact is for buttons */
|
||||
@@ -72,7 +72,7 @@ typedef struct Lamp {
|
||||
short YF_phdepth, YF_useqmc, YF_bufsize, YF_pad;
|
||||
float YF_causticblur, YF_ltradius;
|
||||
/* yafray: glow params */
|
||||
float YF_glowint, YF_glowofs, YF_pad3;
|
||||
float YF_glowint, YF_glowofs;
|
||||
short YF_glowtype, YF_pad2;
|
||||
|
||||
struct MTex *mtex[10];
|
||||
@@ -111,6 +111,11 @@ typedef struct Lamp {
|
||||
/* Since it is used with LOCAL lamp, can't use LA_SHAD */
|
||||
#define LA_YF_SOFT 16384
|
||||
|
||||
/* filtertype */
|
||||
#define LA_SHADBUF_BOX 0
|
||||
#define LA_SHADBUF_TENT 1
|
||||
#define LA_SHADBUF_GAUSS 2
|
||||
|
||||
/* area shape */
|
||||
#define LA_AREA_SQUARE 0
|
||||
#define LA_AREA_RECT 1
|
||||
|
||||
@@ -176,18 +176,22 @@ struct Render
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
typedef struct ShadSampleBuf {
|
||||
struct ShadSampleBuf *next, *prev;
|
||||
long *zbuf;
|
||||
char *cbuf;
|
||||
} ShadSampleBuf;
|
||||
|
||||
typedef struct ShadBuf {
|
||||
short samp, shadhalostep;
|
||||
short samp, shadhalostep, totbuf;
|
||||
float persmat[4][4];
|
||||
float viewmat[4][4];
|
||||
float winmat[4][4];
|
||||
float *jit;
|
||||
float d,clipend,pixsize,soft;
|
||||
float *jit, *weight;
|
||||
float d, clipend, pixsize, soft;
|
||||
int co[3];
|
||||
int size,bias;
|
||||
long *zbuf;
|
||||
char *cbuf;
|
||||
int size, bias;
|
||||
ListBase buffers;
|
||||
} ShadBuf;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@@ -287,6 +291,8 @@ typedef struct LampRen
|
||||
short samp;
|
||||
/** Softness factor for shadow */
|
||||
float soft;
|
||||
/** amount of subsample buffers */
|
||||
short buffers, filtertype;
|
||||
/** shadow plus halo: detail level */
|
||||
short shadhalostep;
|
||||
/** Near clip of the lamp */
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
* @param lar The vector of lamps
|
||||
*/
|
||||
void makeshadowbuf(struct Render *re, LampRen *lar);
|
||||
void freeshadowbuf(struct LampRen *lar);
|
||||
|
||||
/**
|
||||
* Determines the shadow factor for a face and lamp. There is some
|
||||
|
||||
@@ -47,7 +47,7 @@ void projectverto(float *v1, float winmat[][4], float *adr);
|
||||
int testclip(float *v);
|
||||
|
||||
void set_part_zbuf_clipflag(struct RenderPart *pa);
|
||||
void zbuffer_shadow(struct Render *re, struct LampRen *lar, int *rectz, int size);
|
||||
void zbuffer_shadow(struct Render *re, struct LampRen *lar, int *rectz, int size, float jitx, float jity);
|
||||
void zbuffer_solid(struct RenderPart *pa, unsigned int layer, short layflag);
|
||||
void zbuffer_transp_shade(struct RenderPart *pa, struct RenderLayer *rl, float *pass);
|
||||
void convert_zbuf_to_distbuf(struct RenderPart *pa, struct RenderLayer *rl);
|
||||
|
||||
@@ -1723,7 +1723,7 @@ static void initshadowbuf(Render *re, LampRen *lar, float mat[][4])
|
||||
|
||||
/* if(la->spsi<16) return; */
|
||||
|
||||
/* memory reservation */
|
||||
/* memory alloc */
|
||||
shb= (struct ShadBuf *)MEM_callocN( sizeof(struct ShadBuf),"initshadbuf");
|
||||
lar->shb= shb;
|
||||
|
||||
@@ -1733,6 +1733,9 @@ static void initshadowbuf(Render *re, LampRen *lar, float mat[][4])
|
||||
|
||||
/* percentage render: keep track of min and max */
|
||||
shb->size= (lar->bufsize*re->r.size)/100;
|
||||
|
||||
if(lar->buffers>1) shb->size/= 2;
|
||||
|
||||
if(shb->size<512) shb->size= 512;
|
||||
else if(shb->size > lar->bufsize) shb->size= lar->bufsize;
|
||||
|
||||
@@ -1742,16 +1745,6 @@ static void initshadowbuf(Render *re, LampRen *lar, float mat[][4])
|
||||
shb->soft= lar->soft;
|
||||
shb->shadhalostep= lar->shadhalostep;
|
||||
|
||||
shb->zbuf= (unsigned long *)MEM_mallocN( sizeof(unsigned long)*(shb->size*shb->size)/256, "initshadbuf2");
|
||||
shb->cbuf= (char *)MEM_callocN( (shb->size*shb->size)/256, "initshadbuf3");
|
||||
|
||||
if(shb->zbuf==0 || shb->cbuf==0) {
|
||||
if(shb->zbuf) MEM_freeN(shb->zbuf);
|
||||
MEM_freeN(lar->shb);
|
||||
lar->shb= 0;
|
||||
return;
|
||||
}
|
||||
|
||||
MTC_Mat4Ortho(mat);
|
||||
MTC_Mat4Invert(shb->winmat, mat); /* winmat is temp */
|
||||
|
||||
@@ -1834,6 +1827,8 @@ static void add_render_lamp(Render *re, Object *ob, int actual_render)
|
||||
|
||||
lar->bufsize = la->bufsize;
|
||||
lar->samp = la->samp;
|
||||
lar->buffers= la->buffers;
|
||||
lar->filtertype= la->filtertype;
|
||||
lar->soft = la->soft;
|
||||
lar->shadhalostep = la->shadhalostep;
|
||||
lar->clipsta = la->clipsta;
|
||||
@@ -2516,12 +2511,8 @@ static void init_render_object(Render *re, Object *ob, Object *par, int index, i
|
||||
|
||||
void RE_Database_Free(Render *re)
|
||||
{
|
||||
ShadBuf *shb;
|
||||
Object *ob = NULL;
|
||||
GroupObject *go;
|
||||
unsigned long *ztile;
|
||||
int b, v;
|
||||
char *ctile;
|
||||
|
||||
/* FREE */
|
||||
|
||||
@@ -2532,19 +2523,7 @@ void RE_Database_Free(Render *re)
|
||||
|
||||
for(go= re->lights.first; go; go= go->next) {
|
||||
struct LampRen *lar= go->lampren;
|
||||
if(lar->shb) {
|
||||
shb= lar->shb;
|
||||
v= (shb->size*shb->size)/256;
|
||||
ztile= shb->zbuf;
|
||||
ctile= shb->cbuf;
|
||||
for(b=0; b<v; b++, ztile++, ctile++) {
|
||||
if(*ctile) MEM_freeN((void *) *ztile);
|
||||
}
|
||||
|
||||
MEM_freeN(shb->zbuf);
|
||||
MEM_freeN(shb->cbuf);
|
||||
MEM_freeN(lar->shb);
|
||||
}
|
||||
freeshadowbuf(lar);
|
||||
if(lar->jitter) MEM_freeN(lar->jitter);
|
||||
MEM_freeN(lar);
|
||||
}
|
||||
|
||||
@@ -30,9 +30,12 @@
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_lamp_types.h"
|
||||
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_jitter.h"
|
||||
|
||||
#include "renderpipeline.h"
|
||||
@@ -84,7 +87,7 @@ static void copy_to_ztile(int *rectz, int size, int x1, int y1, int tile, char *
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int sizeoflampbuf(struct ShadBuf *shb)
|
||||
static int sizeoflampbuf(ShadBuf *shb)
|
||||
{
|
||||
int num,count=0;
|
||||
char *cp;
|
||||
@@ -98,6 +101,7 @@ static int sizeoflampbuf(struct ShadBuf *shb)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* not threadsafe... */
|
||||
static float *give_jitter_tab(int samp)
|
||||
{
|
||||
/* these are all possible jitter tables, takes up some
|
||||
@@ -123,65 +127,75 @@ static float *give_jitter_tab(int samp)
|
||||
|
||||
}
|
||||
|
||||
void makeshadowbuf(Render *re, LampRen *lar)
|
||||
static void make_jitter_weight_tab(ShadBuf *shb, short filtertype)
|
||||
{
|
||||
struct ShadBuf *shb= lar->shb;
|
||||
float wsize, dist;
|
||||
int *rectz, *rz, *rz1, verg, verg1;
|
||||
float *jit, totw= 0.0f;
|
||||
int a, tot=shb->samp*shb->samp;
|
||||
|
||||
shb->weight= MEM_mallocN(sizeof(float)*tot, "weight tab lamp");
|
||||
|
||||
for(jit= shb->jit, a=0; a<tot; a++, jit+=2) {
|
||||
if(filtertype==LA_SHADBUF_TENT)
|
||||
shb->weight[a]= 0.71f - sqrt(jit[0]*jit[0] + jit[1]*jit[1]);
|
||||
else if(filtertype==LA_SHADBUF_GAUSS)
|
||||
shb->weight[a]= RE_filter_value(R_FILTER_GAUSS, 1.8f*sqrt(jit[0]*jit[0] + jit[1]*jit[1]));
|
||||
else
|
||||
shb->weight[a]= 1.0f;
|
||||
|
||||
totw+= shb->weight[a];
|
||||
}
|
||||
|
||||
totw= 1.0f/totw;
|
||||
for(a=0; a<tot; a++) {
|
||||
shb->weight[a]*= totw;
|
||||
}
|
||||
}
|
||||
|
||||
/* create Z tiles (for compression): this system is 24 bits!!! */
|
||||
static void compress_shadowbuf(ShadBuf *shb, int *rectz, int square)
|
||||
{
|
||||
ShadSampleBuf *shsample;
|
||||
float dist;
|
||||
unsigned long *ztile;
|
||||
int a, x, y, minx, miny, byt1, byt2, square;
|
||||
int *rz, *rz1, verg, verg1, size= shb->size;
|
||||
int a, x, y, minx, miny, byt1, byt2;
|
||||
char *rc, *rcline, *ctile, *zt;
|
||||
|
||||
shb->jit= give_jitter_tab(shb->samp);
|
||||
|
||||
/* matrices and window: in winmat the transformation is being put,
|
||||
transforming from observer view to lamp view, including lamp window matrix */
|
||||
wsize= shb->pixsize*(shb->size/2.0);
|
||||
|
||||
i_window(-wsize, wsize, -wsize, wsize, shb->d, shb->clipend, shb->winmat);
|
||||
|
||||
MTC_Mat4MulMat4(shb->persmat, shb->viewmat, shb->winmat);
|
||||
|
||||
/* temp, will be restored */
|
||||
MTC_Mat4SwapMat4(shb->persmat, re->winmat);
|
||||
|
||||
/* zbuffering */
|
||||
rectz= MEM_mallocN(sizeof(int)*shb->size*shb->size, "makeshadbuf");
|
||||
shsample= MEM_mallocN( sizeof(ShadSampleBuf), "shad sample buf");
|
||||
BLI_addtail(&shb->buffers, shsample);
|
||||
|
||||
shsample->zbuf= MEM_mallocN( sizeof(unsigned long)*(size*size)/256, "initshadbuf2");
|
||||
shsample->cbuf= MEM_callocN( (size*size)/256, "initshadbuf3");
|
||||
|
||||
ztile= shsample->zbuf;
|
||||
ctile= shsample->cbuf;
|
||||
|
||||
/* help buffer */
|
||||
rcline= MEM_mallocN(256*4+sizeof(int), "makeshadbuf2");
|
||||
|
||||
project_renderdata(re, projectvert, 0, 0);
|
||||
|
||||
zbuffer_shadow(re, lar, rectz, shb->size);
|
||||
|
||||
square= lar->mode & LA_SQUARE;
|
||||
|
||||
/* create Z tiles (for compression): this system is 24 bits!!! */
|
||||
|
||||
ztile= shb->zbuf;
|
||||
ctile= shb->cbuf;
|
||||
for(y=0; y<shb->size; y+=16) {
|
||||
if(y< shb->size/2) miny= y+15-shb->size/2;
|
||||
else miny= y-shb->size/2;
|
||||
|
||||
for(x=0; x<shb->size; x+=16) {
|
||||
|
||||
for(y=0; y<size; y+=16) {
|
||||
if(y< size/2) miny= y+15-size/2;
|
||||
else miny= y-size/2;
|
||||
|
||||
for(x=0; x<size; x+=16) {
|
||||
|
||||
/* is tile within spotbundle? */
|
||||
a= shb->size/2;
|
||||
a= size/2;
|
||||
if(x< a) minx= x+15-a;
|
||||
else minx= x-a;
|
||||
|
||||
dist= sqrt( (float)(minx*minx+miny*miny) );
|
||||
|
||||
|
||||
if(square==0 && dist>(float)(a+12)) { /* 12, tested with a onlyshadow lamp */
|
||||
a= 256; verg= 0; /* 0x80000000; */ /* 0x7FFFFFFF; */
|
||||
rz1= (&verg)+1;
|
||||
}
|
||||
else {
|
||||
copy_to_ztile(rectz, shb->size, x, y, 16, rcline);
|
||||
copy_to_ztile(rectz, size, x, y, 16, rcline);
|
||||
rz1= (int *)rcline;
|
||||
|
||||
verg= (*rz1 & 0xFFFFFF00);
|
||||
|
||||
|
||||
for(a=0;a<256;a++,rz1++) {
|
||||
if( (*rz1 & 0xFFFFFF00) !=verg) break;
|
||||
}
|
||||
@@ -191,7 +205,7 @@ void makeshadowbuf(Render *re, LampRen *lar)
|
||||
*ztile= *(rz1-1);
|
||||
}
|
||||
else {
|
||||
|
||||
|
||||
/* ACOMP etc. are defined to work L/B endian */
|
||||
|
||||
rc= rcline;
|
||||
@@ -203,7 +217,7 @@ void makeshadowbuf(Render *re, LampRen *lar)
|
||||
for(a=1;a<256;a++,rc+=4) {
|
||||
byt1 &= (verg==rc[ACOMP]);
|
||||
byt2 &= (verg1==rc[BCOMP]);
|
||||
|
||||
|
||||
if(byt1==0) break;
|
||||
}
|
||||
if(byt1 && byt2) { /* only store byte */
|
||||
@@ -211,7 +225,7 @@ void makeshadowbuf(Render *re, LampRen *lar)
|
||||
*ztile= (unsigned long)MEM_mallocN(256+4, "tile1");
|
||||
rz= (int *)*ztile;
|
||||
*rz= *rz1;
|
||||
|
||||
|
||||
zt= (char *)(rz+1);
|
||||
rc= rcline;
|
||||
for(a=0; a<256; a++, zt++, rc+=4) *zt= rc[GCOMP];
|
||||
@@ -221,7 +235,7 @@ void makeshadowbuf(Render *re, LampRen *lar)
|
||||
*ztile= (unsigned long)MEM_mallocN(2*256+4,"Tile2");
|
||||
rz= (int *)*ztile;
|
||||
*rz= *rz1;
|
||||
|
||||
|
||||
zt= (char *)(rz+1);
|
||||
rc= rcline;
|
||||
for(a=0; a<256; a++, zt+=2, rc+=4) {
|
||||
@@ -248,6 +262,44 @@ void makeshadowbuf(Render *re, LampRen *lar)
|
||||
}
|
||||
|
||||
MEM_freeN(rcline);
|
||||
|
||||
}
|
||||
|
||||
void makeshadowbuf(Render *re, LampRen *lar)
|
||||
{
|
||||
ShadBuf *shb= lar->shb;
|
||||
float wsize, *jitbuf, twozero[2]= {0.0f, 0.0f};
|
||||
int *rectz, samples;
|
||||
|
||||
/* jitter, weights */
|
||||
shb->jit= give_jitter_tab(shb->samp);
|
||||
make_jitter_weight_tab(shb, lar->filtertype);
|
||||
|
||||
shb->totbuf= lar->buffers;
|
||||
if(shb->totbuf==4) jitbuf= give_jitter_tab(2);
|
||||
else if(shb->totbuf==9) jitbuf= give_jitter_tab(3);
|
||||
else jitbuf= twozero;
|
||||
|
||||
/* matrices and window: in winmat the transformation is being put,
|
||||
transforming from observer view to lamp view, including lamp window matrix */
|
||||
wsize= shb->pixsize*(shb->size/2.0);
|
||||
|
||||
i_window(-wsize, wsize, -wsize, wsize, shb->d, shb->clipend, shb->winmat);
|
||||
MTC_Mat4MulMat4(shb->persmat, shb->viewmat, shb->winmat);
|
||||
/* temp, will be restored */
|
||||
MTC_Mat4SwapMat4(shb->persmat, re->winmat);
|
||||
|
||||
/* zbuffering */
|
||||
rectz= MEM_mallocN(sizeof(int)*shb->size*shb->size, "makeshadbuf");
|
||||
|
||||
project_renderdata(re, projectvert, 0, 0);
|
||||
|
||||
for(samples=0; samples<shb->totbuf; samples++) {
|
||||
zbuffer_shadow(re, lar, rectz, shb->size, jitbuf[2*samples], jitbuf[2*samples+1]);
|
||||
/* create Z tiles (for compression): this system is 24 bits!!! */
|
||||
compress_shadowbuf(shb, rectz, lar->mode & LA_SQUARE);
|
||||
}
|
||||
|
||||
MEM_freeN(rectz);
|
||||
|
||||
/* old matrix back */
|
||||
@@ -256,10 +308,38 @@ void makeshadowbuf(Render *re, LampRen *lar)
|
||||
/* printf("lampbuf %d\n", sizeoflampbuf(shb)); */
|
||||
}
|
||||
|
||||
static int firstreadshadbuf(struct ShadBuf *shb, int xs, int ys, int nr)
|
||||
void freeshadowbuf(LampRen *lar)
|
||||
{
|
||||
if(lar->shb) {
|
||||
ShadBuf *shb= lar->shb;
|
||||
ShadSampleBuf *shsample;
|
||||
int b, v;
|
||||
|
||||
v= (shb->size*shb->size)/256;
|
||||
|
||||
for(shsample= shb->buffers.first; shsample; shsample= shsample->next) {
|
||||
unsigned long *ztile= shsample->zbuf;
|
||||
char *ctile= shsample->cbuf;
|
||||
|
||||
for(b=0; b<v; b++, ztile++, ctile++)
|
||||
if(*ctile) MEM_freeN((void *) *ztile);
|
||||
|
||||
MEM_freeN(shsample->zbuf);
|
||||
MEM_freeN(shsample->cbuf);
|
||||
}
|
||||
BLI_freelistN(&shb->buffers);
|
||||
|
||||
if(shb->weight) MEM_freeN(shb->weight);
|
||||
MEM_freeN(lar->shb);
|
||||
|
||||
lar->shb= NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int firstreadshadbuf(ShadBuf *shb, ShadSampleBuf *shsample, int **rz, int xs, int ys, int nr)
|
||||
{
|
||||
/* return a 1 if fully compressed shadbuf-tile && z==const */
|
||||
static int *rz;
|
||||
int ofs;
|
||||
char *ct;
|
||||
|
||||
@@ -269,13 +349,13 @@ static int firstreadshadbuf(struct ShadBuf *shb, int xs, int ys, int nr)
|
||||
|
||||
/* calc z */
|
||||
ofs= (ys>>4)*(shb->size>>4) + (xs>>4);
|
||||
ct= shb->cbuf+ofs;
|
||||
ct= shsample->cbuf+ofs;
|
||||
if(*ct==0) {
|
||||
if(nr==0) {
|
||||
rz= *( (int **)(shb->zbuf+ofs) );
|
||||
*rz= *( (int **)(shsample->zbuf+ofs) );
|
||||
return 1;
|
||||
}
|
||||
else if(rz!= *( (int **)(shb->zbuf+ofs) )) return 0;
|
||||
else if(*rz!= *( (int **)(shsample->zbuf+ofs) )) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -283,7 +363,8 @@ static int firstreadshadbuf(struct ShadBuf *shb, int xs, int ys, int nr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static float readshadowbuf(struct ShadBuf *shb, int bias, int xs, int ys, int zs) /* return 1.0 : fully in light */
|
||||
/* return 1.0 : fully in light */
|
||||
static float readshadowbuf(ShadBuf *shb, ShadSampleBuf *shsample, int bias, int xs, int ys, int zs)
|
||||
{
|
||||
float temp;
|
||||
int *rz, ofs;
|
||||
@@ -300,8 +381,8 @@ static float readshadowbuf(struct ShadBuf *shb, int bias, int xs, int ys, int zs
|
||||
|
||||
/* calc z */
|
||||
ofs= (ys>>4)*(shb->size>>4) + (xs>>4);
|
||||
ct= shb->cbuf+ofs;
|
||||
rz= *( (int **)(shb->zbuf+ofs) );
|
||||
ct= shsample->cbuf+ofs;
|
||||
rz= *( (int **)(shsample->zbuf+ofs) );
|
||||
|
||||
if(*ct==3) {
|
||||
ct= ((char *)rz)+3*16*(ys & 15)+3*(xs & 15);
|
||||
@@ -348,34 +429,35 @@ static float readshadowbuf(struct ShadBuf *shb, int bias, int xs, int ys, int zs
|
||||
|
||||
/* the externally called shadow testing (reading) function */
|
||||
/* return 1.0: no shadow at all */
|
||||
float testshadowbuf(struct ShadBuf *shb, float *rco, float *dxco, float *dyco, float inp)
|
||||
float testshadowbuf(ShadBuf *shb, float *rco, float *dxco, float *dyco, float inp)
|
||||
{
|
||||
float fac, co[4], dx[3], dy[3], aantal=0;
|
||||
float xs1,ys1, siz, *j, xres, yres;
|
||||
int xs,ys, zs, bias;
|
||||
short a,num;
|
||||
ShadSampleBuf *shsample;
|
||||
float fac, co[4], dx[3], dy[3], shadfac=0.0f;
|
||||
float xs1,ys1, siz, *jit, *weight, xres, yres;
|
||||
int xs, ys, zs, bias, *rz;
|
||||
short a, num;
|
||||
|
||||
if(inp <= 0.0) return 0.0;
|
||||
if(inp <= 0.0f) return 0.0f;
|
||||
|
||||
/* rotate renderco en osaco */
|
||||
siz= 0.5*(float)shb->size;
|
||||
siz= 0.5f*(float)shb->size;
|
||||
VECCOPY(co, rco);
|
||||
co[3]= 1.0;
|
||||
co[3]= 1.0f;
|
||||
|
||||
MTC_Mat4MulVec4fl(shb->persmat, co); /* rational hom co */
|
||||
|
||||
xs1= siz*(1.0+co[0]/co[3]);
|
||||
ys1= siz*(1.0+co[1]/co[3]);
|
||||
xs1= siz*(1.0f+co[0]/co[3]);
|
||||
ys1= siz*(1.0f+co[1]/co[3]);
|
||||
|
||||
/* Clip for z: clipsta and clipend clip values of the shadow buffer. We
|
||||
* can test for -1.0/1.0 because of the properties of the
|
||||
* coordinate transformations. */
|
||||
fac= (co[2]/co[3]);
|
||||
|
||||
if(fac>=1.0) {
|
||||
return 0.0;
|
||||
} else if(fac<= -1.0) {
|
||||
return 1.0;
|
||||
if(fac>=1.0f) {
|
||||
return 0.0f;
|
||||
} else if(fac<= -1.0f) {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
zs= ((float)0x7FFFFFFF)*fac;
|
||||
@@ -386,69 +468,73 @@ float testshadowbuf(struct ShadBuf *shb, float *rco, float *dxco, float *dyco, f
|
||||
|
||||
/* with inp==1.0, bias is half the size. correction value was 1.1, giving errors
|
||||
on cube edges, with one side being almost frontal lighted (ton) */
|
||||
bias= (1.5-inp*inp)*shb->bias;
|
||||
bias= (1.5f-inp*inp)*shb->bias;
|
||||
|
||||
if(num==1) {
|
||||
return readshadowbuf(shb, bias, (int)xs1, (int)ys1, zs);
|
||||
for(shsample= shb->buffers.first; shsample; shsample= shsample->next)
|
||||
shadfac += readshadowbuf(shb, shsample, bias, (int)xs1, (int)ys1, zs);
|
||||
|
||||
return shadfac/(float)shb->totbuf;
|
||||
}
|
||||
|
||||
co[0]= rco[0]+dxco[0];
|
||||
co[1]= rco[1]+dxco[1];
|
||||
co[2]= rco[2]+dxco[2];
|
||||
/* calculate filter size */
|
||||
VECCOPY(co, dxco);
|
||||
co[3]= 1.0;
|
||||
MTC_Mat4MulVec4fl(shb->persmat,co); /* rational hom co */
|
||||
dx[0]= xs1- siz*(1.0+co[0]/co[3]);
|
||||
dx[1]= ys1- siz*(1.0+co[1]/co[3]);
|
||||
MTC_Mat4Mul3Vecfl(shb->persmat, co);
|
||||
|
||||
dx[0]= co[0]/co[3];
|
||||
dx[1]= co[1]/co[3];
|
||||
|
||||
co[0]= rco[0]+dyco[0];
|
||||
co[1]= rco[1]+dyco[1];
|
||||
co[2]= rco[2]+dyco[2];
|
||||
VECCOPY(co, dyco);
|
||||
co[3]= 1.0;
|
||||
MTC_Mat4MulVec4fl(shb->persmat,co); /* rational hom co */
|
||||
dy[0]= xs1- siz*(1.0+co[0]/co[3]);
|
||||
dy[1]= ys1- siz*(1.0+co[1]/co[3]);
|
||||
MTC_Mat4Mul3Vecfl(shb->persmat, co);
|
||||
|
||||
dy[0]= co[0]/co[3];
|
||||
dy[1]= co[1]/co[3];
|
||||
|
||||
xres= fac*( fabs(dx[0])+fabs(dy[0]) );
|
||||
yres= fac*( fabs(dx[1])+fabs(dy[1]) );
|
||||
|
||||
if(xres<fac) xres= fac;
|
||||
if(yres<fac) yres= fac;
|
||||
|
||||
xs1-= (xres)/2;
|
||||
ys1-= (yres)/2;
|
||||
|
||||
j= shb->jit;
|
||||
|
||||
if(xres<16.0 && yres<16.0) {
|
||||
if(firstreadshadbuf(shb, (int)xs1, (int)ys1, 0)) {
|
||||
if(firstreadshadbuf(shb, (int)(xs1+xres), (int)ys1, 1)) {
|
||||
if(firstreadshadbuf(shb, (int)xs1, (int)(ys1+yres), 1)) {
|
||||
if(firstreadshadbuf(shb, (int)(xs1+xres), (int)(ys1+yres), 1)) {
|
||||
return readshadowbuf(shb, bias,(int)xs1, (int)ys1, zs);
|
||||
if(xres<16.0f && yres<16.0f) {
|
||||
shsample= shb->buffers.first;
|
||||
if(firstreadshadbuf(shb, shsample, &rz, (int)xs1, (int)ys1, 0)) {
|
||||
if(firstreadshadbuf(shb, shsample, &rz, (int)(xs1+xres), (int)ys1, 1)) {
|
||||
if(firstreadshadbuf(shb, shsample, &rz, (int)xs1, (int)(ys1+yres), 1)) {
|
||||
if(firstreadshadbuf(shb, shsample, &rz, (int)(xs1+xres), (int)(ys1+yres), 1)) {
|
||||
return readshadowbuf(shb, shsample, bias,(int)xs1, (int)ys1, zs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(a=num;a>0;a--) {
|
||||
/* instead of jit i tried random: ugly! */
|
||||
/* note: the plus 0.5 gives best sampling results, jit used to go from 0-1 */
|
||||
/* xs1 and ys1 are already corrected to be corner of sample area */
|
||||
xs= xs1 + xres*(j[0] + 0.5);
|
||||
ys= ys1 + yres*(j[1] + 0.5);
|
||||
j+=2;
|
||||
|
||||
for(shsample= shb->buffers.first; shsample; shsample= shsample->next) {
|
||||
jit= shb->jit;
|
||||
weight= shb->weight;
|
||||
|
||||
aantal+= readshadowbuf(shb, bias, xs, ys, zs);
|
||||
for(a=num; a>0; a--, jit+=2, weight++) {
|
||||
/* instead of jit i tried random: ugly! */
|
||||
/* note: the plus 0.5 gives best sampling results, jit goes from -0.5 to 0.5 */
|
||||
/* xs1 and ys1 are already corrected to be corner of sample area */
|
||||
xs= xs1 + xres*(jit[0] + 0.5f);
|
||||
ys= ys1 + yres*(jit[1] + 0.5f);
|
||||
|
||||
shadfac+= *weight * readshadowbuf(shb, shsample, bias, xs, ys, zs);
|
||||
}
|
||||
}
|
||||
|
||||
/* Renormalizes for the sample number: */
|
||||
return aantal/( (float)(num) );
|
||||
return shadfac/(float)shb->totbuf;
|
||||
}
|
||||
|
||||
/* different function... sampling behind clipend can be LIGHT, bias is negative! */
|
||||
/* return: light */
|
||||
static float readshadowbuf_halo(struct ShadBuf *shb, int xs, int ys, int zs)
|
||||
static float readshadowbuf_halo(ShadBuf *shb, ShadSampleBuf *shsample, int xs, int ys, int zs)
|
||||
{
|
||||
float temp;
|
||||
int *rz, ofs;
|
||||
@@ -464,8 +550,8 @@ static float readshadowbuf_halo(struct ShadBuf *shb, int xs, int ys, int zs)
|
||||
|
||||
/* calc z */
|
||||
ofs= (ys>>4)*(shb->size>>4) + (xs>>4);
|
||||
ct= shb->cbuf+ofs;
|
||||
rz= *( (int **)(shb->zbuf+ofs) );
|
||||
ct= shsample->cbuf+ofs;
|
||||
rz= *( (int **)(shsample->zbuf+ofs) );
|
||||
|
||||
if(*ct==3) {
|
||||
ct= ((char *)rz)+3*16*(ys & 15)+3*(xs & 15);
|
||||
@@ -524,6 +610,7 @@ float shadow_halo(LampRen *lar, float *p1, float *p2)
|
||||
{
|
||||
/* p1 p2 already are rotated in spot-space */
|
||||
ShadBuf *shb= lar->shb;
|
||||
ShadSampleBuf *shsample;
|
||||
float co[4], siz;
|
||||
float labda, labdao, labdax, labday, ldx, ldy;
|
||||
float zf, xf1, yf1, zf1, xf2, yf2, zf2;
|
||||
@@ -620,7 +707,7 @@ float shadow_halo(LampRen *lar, float *p1, float *p2)
|
||||
if(labda==labdao || labda>=1.0) break;
|
||||
|
||||
zf= zf1 + labda*(zf2-zf1);
|
||||
count+= 1.0;
|
||||
count+= (float)shb->totbuf;
|
||||
|
||||
if(zf<= -1.0) lightcount += 1.0; /* close to the spot */
|
||||
else {
|
||||
@@ -629,7 +716,8 @@ float shadow_halo(LampRen *lar, float *p1, float *p2)
|
||||
if(zf>=1.0) z= 0x7FFFF000;
|
||||
else z= (int)(0x7FFFF000*zf);
|
||||
|
||||
lightcount+= readshadowbuf_halo(shb, x, y, z);
|
||||
for(shsample= shb->buffers.first; shsample; shsample= shsample->next)
|
||||
lightcount+= readshadowbuf_halo(shb, shsample, x, y, z);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1819,7 +1819,7 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem, Re
|
||||
zbuf_free_span(&zspan);
|
||||
}
|
||||
|
||||
void zbuffer_shadow(Render *re, LampRen *lar, int *rectz, int size)
|
||||
void zbuffer_shadow(Render *re, LampRen *lar, int *rectz, int size, float jitx, float jity)
|
||||
{
|
||||
ZSpan zspan;
|
||||
VlakRen *vlr= NULL;
|
||||
@@ -1831,8 +1831,8 @@ void zbuffer_shadow(Render *re, LampRen *lar, int *rectz, int size)
|
||||
zbuf_alloc_span(&zspan, size, size);
|
||||
zspan.zmulx= ((float)size)/2.0;
|
||||
zspan.zmuly= ((float)size)/2.0;
|
||||
zspan.zofsx= 0.0f;
|
||||
zspan.zofsy= 0.0f;
|
||||
zspan.zofsx= jitx;
|
||||
zspan.zofsy= jity;
|
||||
|
||||
/* the buffers */
|
||||
zspan.rectz= rectz;
|
||||
|
||||
@@ -2127,17 +2127,25 @@ static void lamp_panel_spot(Object *ob, Lamp *la)
|
||||
uiDefButF(block, NUMSLI,B_LAMPREDRAW,"HaloInt ", 100,135,200,19,&la->haint, 0.0, 5.0, 0, 0, "Sets the intensity of the spotlight halo");
|
||||
|
||||
if(la->mode & LA_SHAD) {
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButS(block, NUM,B_SBUFF,"ShadowBufferSize:", 100,110,200,19, &la->bufsize,512,10240, 0, 0, "Sets the size of the shadow buffer to nearest multiple of 16");
|
||||
uiDefButS(block, ROW,B_NOP, "Box", 100,90,65,19, &la->filtertype, 0.0, LA_SHADBUF_BOX, 0, 0, "Apply Box filter for shadowbuffer");
|
||||
uiDefButS(block, ROW,B_NOP, "Tent", 165,90,65,19, &la->filtertype, 0.0, LA_SHADBUF_TENT, 0, 0, "Apply Tent filter for shadowbuffer");
|
||||
uiDefButS(block, ROW,B_NOP, "Gauss", 230,90,70,19, &la->filtertype, 0.0, LA_SHADBUF_GAUSS, 0, 0, "Apply Gauss filter for shadowbuffer");
|
||||
|
||||
// uiDefButS(block, ROW,B_NOP,"SubSamples: 1", 100,90,140,19, &la->buffers, 1.0, 1.0, 0, 0, "Amount of lampbuffer subsamples, a value of larger than 1 halves the shadowbuffer size");
|
||||
// uiDefButS(block, ROW,B_NOP,"4", 240,90,30,19, &la->buffers, 1.0, 4.0, 0, 0, "Amount of lampbuffer subsamples, this halves the actual shadowbuffer size");
|
||||
// uiDefButS(block, ROW,B_NOP,"9", 270,90,30,19, &la->buffers, 1.0, 9.0, 0, 0, "Amount of lampbuffer subsamples, this halves the shadowbuffer size");
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButF(block, NUM,REDRAWVIEW3D,"ClipSta:", 100,70,100,19, &la->clipsta, 0.1*grid,1000.0*grid, 10, 0, "Sets the shadow map clip start: objects closer will not generate shadows");
|
||||
uiDefButF(block, NUM,REDRAWVIEW3D,"ClipEnd:", 200,70,100,19,&la->clipend, 1.0, 5000.0*grid, 100, 0, "Sets the shadow map clip end beyond which objects will not generate shadows");
|
||||
uiDefButF(block, NUM,REDRAWVIEW3D,"ClipSta:", 100,60,100,19, &la->clipsta, 0.1*grid,1000.0*grid, 10, 0, "Sets the shadow map clip start: objects closer will not generate shadows");
|
||||
uiDefButF(block, NUM,REDRAWVIEW3D,"ClipEnd:", 200,60,100,19,&la->clipend, 1.0, 5000.0*grid, 100, 0, "Sets the shadow map clip end beyond which objects will not generate shadows");
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
uiDefButS(block, NUM,B_LAMPREDRAW,"Samples:", 100,30,100,19, &la->samp,1.0,16.0, 0, 0, "Sets the number of shadow map samples");
|
||||
uiDefButS(block, NUM,B_NOP,"Halo step:", 200,30,100,19, &la->shadhalostep, 0.0, 12.0, 0, 0, "Sets the volumetric halo sampling frequency");
|
||||
uiDefButF(block, NUM,B_LAMPREDRAW,"Bias:", 100,10,100,19, &la->bias, 0.01, 5.0, 1, 0, "Sets the shadow map sampling bias");
|
||||
uiDefButF(block, NUM,B_LAMPREDRAW,"Soft:", 200,10,100,19, &la->soft,1.0,100.0, 100, 0, "Sets the size of the shadow sample area");
|
||||
uiDefButS(block, NUM,B_LAMPREDRAW,"Samples:", 100,30,100,19, &la->samp,1.0,16.0, 0, 0, "Sets the number of shadow map samples");
|
||||
uiDefButS(block, NUM,B_NOP,"Halo step:", 200,30,100,19, &la->shadhalostep, 0.0, 12.0, 0, 0, "Sets the volumetric halo sampling frequency");
|
||||
uiDefButF(block, NUM,B_LAMPREDRAW,"Bias:", 100,10,100,19, &la->bias, 0.01, 5.0, 1, 0, "Sets the shadow map sampling bias");
|
||||
uiDefButF(block, NUM,B_LAMPREDRAW,"Soft:", 200,10,100,19, &la->soft,1.0,100.0, 100, 0, "Sets the size of the shadow sample area");
|
||||
}
|
||||
}
|
||||
else if(la->type==LA_AREA && (la->mode & LA_SHAD_RAY)) {
|
||||
|
||||
Reference in New Issue
Block a user