diff options
author | Ton Roosendaal <ton@blender.org> | 2005-04-18 23:36:34 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2005-04-18 23:36:34 +0400 |
commit | 99ee8915969ad4cdb55c88c025e674f4c1cb89fd (patch) | |
tree | 922bf47c382eaa33280496664e38ef1cf27df4bd /source/blender/render/intern | |
parent | 5d31c72020956ab8a372f60a2d8f1ecf85477896 (diff) |
Fixed several annoyances with halo render + unified render (bug 1989+2382)
- Maximum faces/halos per pixel was 500, which wasn't correctly applied in
all cases, causing errors in AA
- Moved maximum up to 1000 now
- made halos become clipped away from filling in buffers when behind a
solid face. That saves a lot of rendertime!
Unified remains weak with halos...
Diffstat (limited to 'source/blender/render/intern')
5 files changed, 67 insertions, 93 deletions
diff --git a/source/blender/render/intern/include/vanillaRenderPipe_types.h b/source/blender/render/intern/include/vanillaRenderPipe_types.h index cf4f2ffb289..df24ed01f5e 100644 --- a/source/blender/render/intern/include/vanillaRenderPipe_types.h +++ b/source/blender/render/intern/include/vanillaRenderPipe_types.h @@ -37,7 +37,7 @@ /* Render defines */ #define RE_MAX_OSA_COUNT 16 /* The max. number of possible oversamples */ -#define RE_MAX_FACES_PER_PIXEL 500 /* max. nr of faces rendered behind one */ +#define RE_MAX_FACES_PER_PIXEL 1000 /* max. nr of faces rendered behind one */ /* pixel */ enum RE_SkyAlphaBlendingType { diff --git a/source/blender/render/intern/include/zbufferdatastruct.h b/source/blender/render/intern/include/zbufferdatastruct.h index 790cce2cb77..2cef53dc9f6 100644 --- a/source/blender/render/intern/include/zbufferdatastruct.h +++ b/source/blender/render/intern/include/zbufferdatastruct.h @@ -71,7 +71,6 @@ RE_APixstrExt *addpseA(void); * Add an object to a zbuffer entry. */ void insertObject(int teller, -/* int opaque, */ int obindex, int obtype, int dist, diff --git a/source/blender/render/intern/include/zbufferdatastruct_types.h b/source/blender/render/intern/include/zbufferdatastruct_types.h index 0607f19bbc9..5048adfa8bc 100644 --- a/source/blender/render/intern/include/zbufferdatastruct_types.h +++ b/source/blender/render/intern/include/zbufferdatastruct_types.h @@ -55,10 +55,12 @@ typedef struct RE_APixstrExt { /* but this should definitely be done in a better way. An enum may */ /* be some help, but masking is still a nice feature... */ /* object types to buffer in the z buffer */ -#define RE_NONE 0 -#define RE_POLY 1 -#define RE_HALO 2 -#define RE_SKY 4 +/* RE_SOLID is flag for RE_POLY, as speedup */ +#define RE_NONE 0 +#define RE_POLY 1 +#define RE_HALO 2 +#define RE_SKY 4 +#define RE_SOLID 8 /* unique indices for each field */ #define RE_ZMIN 0 diff --git a/source/blender/render/intern/source/vanillaRenderPipe.c b/source/blender/render/intern/source/vanillaRenderPipe.c index 500da84dedb..91a5173c353 100644 --- a/source/blender/render/intern/source/vanillaRenderPipe.c +++ b/source/blender/render/intern/source/vanillaRenderPipe.c @@ -197,6 +197,7 @@ static void freeRenderBuffers(void) { static void zBufferFillFace(unsigned int zvlnr, float *v1, float *v2, float *v3) { /* Coordinates of the vertices are specified in ZCS */ + VlakRen *vlr; int apteller, apoffsetteller; double z0; /* used as temp var*/ double xx1; @@ -205,13 +206,17 @@ static void zBufferFillFace(unsigned int zvlnr, float *v1, float *v2, float *v3) register int zverg,zvlak,x; int my0,my2,sn1,sn2,rectx,zd; int y,omsl,xs0,xs1,xs2,xs3, dx0,dx1,dx2, mask; - + int obtype; /* These used to be doubles. We may want to change them back if the */ /* loss of accuracy proves to be a problem? There does not seem to be */ /* any performance issues here, so I'll just keep the doubles. */ /* float vec0[3], vec1[3], vec2[3]; */ double vec0[3], vec1[3], vec2[3]; - + + vlr= RE_findOrAddVlak( (zvlnr-1) & 0x7FFFFF); + if(vlr->mat->mode & MA_ZTRA) obtype= RE_POLY; + else obtype= RE_POLY|RE_SOLID; + /* MIN MAX */ /* sort vertices for min mid max y value */ if(v1[1]<v2[1]) { @@ -351,7 +356,7 @@ static void zBufferFillFace(unsigned int zvlnr, float *v1, float *v2, float *v3) zverg-= Azvoordeel; while(x>=0) { - insertObject(apteller, /* RE_treat_face_as_opaque, */ zvlnr, RE_POLY, zverg, mask); + insertObject(apteller, zvlnr, obtype, zverg, mask); zverg+= zd; apteller++; x--; @@ -392,7 +397,7 @@ static void zBufferFillFace(unsigned int zvlnr, float *v1, float *v2, float *v3) zverg-= Azvoordeel; while(x>=0) { - insertObject(apteller, /* RE_treat_face_as_opaque, */ zvlnr, RE_POLY, zverg, mask); + insertObject(apteller, zvlnr, obtype, zverg, mask); zverg+= zd; apteller++; x--; @@ -455,7 +460,7 @@ static void zBufferFillEdge(unsigned int zvlnr, float *vec1, float *vec2) } if(x>=0 && y>=Aminy && y<=Amaxy) { - insertObject(apteller, /* RE_treat_face_as_opaque, */ zvlnr, RE_POLY, vergz, mask); + insertObject(apteller, zvlnr, RE_POLY, vergz, mask); } v1[1]+= dy; @@ -507,7 +512,7 @@ static void zBufferFillEdge(unsigned int zvlnr, float *vec1, float *vec2) } if(x>=0 && y>=Aminy && (x < zBufferWidth)) { - insertObject(apteller, /* RE_treat_face_as_opaque, */ zvlnr, RE_POLY, vergz, mask); + insertObject(apteller, zvlnr, RE_POLY, vergz, mask); } v1[0]+= dx; @@ -522,7 +527,7 @@ static void zBufferFillEdge(unsigned int zvlnr, float *vec1, float *vec2) * Count and sort the list behind ap into buf. Sorts on min. distance. * Low index <=> high z */ -static int countAndSortPixelFaces(int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE], +static int countAndSortPixelFaces(int zrow[][RE_PIXELFIELDSIZE], RE_APixstrExt *ap) { int totvlak; /* face counter */ @@ -582,7 +587,7 @@ static int VR_cbuf[RE_MAX_FACES_PER_PIXEL][2]; /** * Analyze the z-buffer, and pre-sample the colours. */ -static int composeStack(int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE], RE_COLBUFTYPE *collector, +static int composeStack(int zrow[][RE_PIXELFIELDSIZE], RE_COLBUFTYPE *collector, struct RE_faceField* stack, int ptr, int totvlak, float x, float y, int osaNr) { @@ -974,10 +979,18 @@ static void integratePerSubStack(float *sampcol, struct RE_faceField* stack, /* an RE_APixstrExt* array */ /* - redo the numbering to something more logical */ + +/* threadsafe global arrays, too large for stack */ +typedef struct zbufline { + int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE]; + struct RE_faceField osastack[RE_MAX_FACES_PER_PIXEL + 1]; +} zbufline; + +static zbufline zb1, zb2; + static void renderZBufLine(int y, RE_COLBUFTYPE *colbuf1, RE_COLBUFTYPE *colbuf2, RE_COLBUFTYPE *colbuf3) { - int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE]; - RE_APixstrExt *ap; /* iterator for the face-lists */ + RE_APixstrExt *ap; /* iterator for the face-lists */ RE_COLBUFTYPE collector[4]; RE_COLBUFTYPE sampcol[RE_MAX_OSA_COUNT * 4]; RE_COLBUFTYPE *j = NULL; /* generic pixel pointer */ @@ -985,9 +998,12 @@ static void renderZBufLine(int y, RE_COLBUFTYPE *colbuf1, RE_COLBUFTYPE *colbuf2 int x; /* pixel counter */ int i; /* yet another counter */ int stackDepth; /* faces-behind-this-pixel counter */ - struct RE_faceField RE_OSAstack[RE_MAX_FACES_PER_PIXEL + 1]; - int RE_OSAstack_ptr; /* Points to the lowest empty field. The indexed */ - /* field is NOT readable. */ + int osastack_ptr; /* Points to the lowest empty field. The indexed */ + zbufline *zbl; + + /* thread safe row buffers */ + if(y & 1) zbl= &zb1; + else zbl= &zb2; /* Prepare iterators */ ap = APixbufExt + (zBufferWidth * (y - Aminy)); @@ -1004,15 +1020,13 @@ static void renderZBufLine(int y, RE_COLBUFTYPE *colbuf1, RE_COLBUFTYPE *colbuf2 }; /* a. count and sort number of faces */ - stackDepth = countAndSortPixelFaces(zrow, ap); + stackDepth = countAndSortPixelFaces( zbl->zrow, ap); /* b,c. oversample all subpixels, then integrate */ - RE_OSAstack_ptr = 0; - RE_OSAstack_ptr = composeStack(zrow, collector, - RE_OSAstack, RE_OSAstack_ptr, - stackDepth, x, y, osaNr); - integratePerSubStack(sampcol, RE_OSAstack, RE_OSAstack_ptr, - x, y, osaNr); + osastack_ptr = 0; + osastack_ptr = composeStack(zbl->zrow, collector, zbl->osastack, osastack_ptr, + stackDepth, x, y, osaNr); + integratePerSubStack(sampcol, zbl->osastack, osastack_ptr, x, y, osaNr); /* d. Gamma corrected blending and Gaussian */ sampleFloatColV2FloatColVFilter(sampcol, colbuf1, colbuf2, colbuf3, osaNr); @@ -1436,6 +1450,7 @@ static void calcZBufLine(int y) /* (FORALL y: Aminy =< y =< Amaxy: y is buffered) */ if( (y < Aminy) || (y > Amaxy)) { + /* prepare buffer */ part = (y/RE_ZBUFLEN); /* These two lines are mystifying me... */ Aminy = part * RE_ZBUFLEN; /* Possibly for rounding things? */ @@ -1458,7 +1473,7 @@ static void calcZBufLine(int y) if(RE_local_test_break()) keepLooping = 0; Zsample++; } - }; + } } diff --git a/source/blender/render/intern/source/zbufferdatastruct.c b/source/blender/render/intern/source/zbufferdatastruct.c index 319393290bd..4ab8a401c20 100644 --- a/source/blender/render/intern/source/zbufferdatastruct.c +++ b/source/blender/render/intern/source/zbufferdatastruct.c @@ -61,6 +61,7 @@ #include "MEM_guardedalloc.h" #include "zbufferdatastruct.h" +#include "vanillaRenderPipe_types.h" #include "render.h" #ifdef HAVE_CONFIG_H @@ -174,7 +175,6 @@ RE_APixstrExt *addpseA(void) /* ------------------------------------------------------------------------- */ void insertObject(int apteller, -/* int opaque, */ int obindex, int obtype, int dist, @@ -182,21 +182,17 @@ void insertObject(int apteller, { /* Guard the insertion if needed? */ RE_APixstrExt* apn = &APixbufExt[apteller]; - int all_subpixels= 0; - - //if(obtype==RE_POLY) { - // VlakRen *vlr= RE_findOrAddVlak( (obindex-1) & 0x7FFFFF); - // if(vlr->flag & R_FULL_OSA) all_subpixels= 1; - //} + int all_subpixels= 0; // not used now... (ton) while(apn) { + if(apn->t[0] == RE_NONE) { apn->p[0] = obindex; apn->t[0] = obtype; apn->zmin[0] = dist; apn->zmax[0] = dist; apn->mask[0] = mask; break; } - if(all_subpixels==0) { + else if(all_subpixels==0) { if((apn->p[0] == obindex) && (apn->t[0] & obtype)) { if(dist < apn->zmin[0]) apn->zmin[0] = dist; else if(dist > apn->zmax[0]) apn->zmax[0] = dist; @@ -204,13 +200,14 @@ void insertObject(int apteller, break; } } + if(apn->t[1] == RE_NONE) { apn->p[1] = obindex; apn->t[1] = obtype; apn->zmin[1] = dist; apn->zmax[1] = dist; apn->mask[1] = mask; break; } - if(all_subpixels==0) { + else if(all_subpixels==0) { if((apn->p[1] == obindex) && (apn->t[1] & obtype)) { if(dist < apn->zmin[1]) apn->zmin[1] = dist; else if(dist > apn->zmax[1]) apn->zmax[1] = dist; @@ -218,13 +215,14 @@ void insertObject(int apteller, break; } } + if(apn->t[2] == RE_NONE) { apn->p[2] = obindex; apn->t[2] = obtype; apn->zmin[2] = dist; apn->zmax[2] = dist; apn->mask[2] = mask; break; } - if(all_subpixels==0) { + else if(all_subpixels==0) { if((apn->p[2] == obindex) && (apn->t[2] & obtype)) { if(dist < apn->zmin[2]) apn->zmin[2] = dist; else if(dist > apn->zmax[2]) apn->zmax[2] = dist; @@ -232,13 +230,14 @@ void insertObject(int apteller, break; } } + if(apn->t[3] == RE_NONE) { apn->p[3] = obindex; apn->t[3] = obtype; apn->zmin[3] = dist; apn->zmax[3] = dist; apn->mask[3] = mask; break; } - if(all_subpixels==0) { + else if(all_subpixels==0) { if((apn->p[3] == obindex) && (apn->t[3] & obtype)) { if(dist < apn->zmin[3]) apn->zmin[3] = dist; else if(dist > apn->zmax[3]) apn->zmax[3] = dist; @@ -246,66 +245,16 @@ void insertObject(int apteller, break; } } + if(apn->next==0) apn->next= addpseA(); apn= apn->next; } -} /* end of insertObject(RE_APixstrExt*, int, int, int, int) */ +} /* ------------------------------------------------------------------------- */ -void insertFlatObject(RE_APixstrExt *apn, int obindex, int obtype, int dist, int mask) -{ - while(apn) { - if(apn->t[0] == RE_NONE) { - apn->p[0] = obindex; apn->zmin[0] = dist; - apn->zmax[0] = dist; apn->mask[0] = mask; - apn->t[0] = obtype; - break; - } -#ifndef RE_INDIVIDUAL_SUBPIXELS - if( (apn->t[0] & obtype) && (apn->p[0] == obindex)) { - apn->mask[0]|= mask; break; - } -#endif - if(apn->t[1] == RE_NONE) { - apn->p[1] = obindex; apn->zmin[1] = dist; - apn->zmax[1] = dist; apn->mask[1] = mask; - apn->t[1] = obtype; - break; - } -#ifndef RE_INDIVIDUAL_SUBPIXELS - if( (apn->t[1] & obtype) && (apn->p[1] == obindex)) { - apn->mask[1]|= mask; break; - } -#endif - if(apn->t[2] == RE_NONE) { - apn->p[2] = obindex; apn->zmin[2] = dist; - apn->zmax[2] = dist; apn->mask[2] = mask; - apn->t[2] = obtype; - break; - } -#ifndef RE_INDIVIDUAL_SUBPIXELS - if( (apn->t[2] & obtype) && (apn->p[2] == obindex)) { - apn->mask[2]|= mask; break; - } -#endif - if(apn->t[3] == RE_NONE) { - apn->p[3] = obindex; apn->zmin[3] = dist; - apn->zmax[3] = dist; apn->mask[3] = mask; - apn->t[3] = obtype; - break; - } -#ifndef RE_INDIVIDUAL_SUBPIXELS - if( (apn->t[3] & obtype) && (apn->p[3] == obindex)) { - apn->mask[3]|= mask; break; - } -#endif - if(apn->next==0) apn->next= addpseA(); - apn= apn->next; - }; -} /* end of void insertFlatObject(RE_APixstrExt, int, int, int, int)*/ - /* ------------------------------------------------------------------------- */ + /* This function might be helped by an end-of-list marker */ void insertFlatObjectNoOsa(RE_APixstrExt *ap, int obindex, @@ -313,6 +262,8 @@ void insertFlatObjectNoOsa(RE_APixstrExt *ap, int dist, int mask) { + int counter; + while(ap) { if(ap->t[0] == RE_NONE) { ap->p[0] = obindex; ap->zmin[0] = dist; @@ -320,6 +271,7 @@ void insertFlatObjectNoOsa(RE_APixstrExt *ap, ap->t[0] = obtype; break; } + else if(ap->t[0] & RE_SOLID) if( dist > ap->zmin[0] ) break; if(ap->t[1] == RE_NONE) { ap->p[1] = obindex; ap->zmin[1] = dist; @@ -327,6 +279,7 @@ void insertFlatObjectNoOsa(RE_APixstrExt *ap, ap->t[1] = obtype; break; } + else if(ap->t[1] & RE_SOLID) if( dist > ap->zmin[1] ) break; if(ap->t[2] == RE_NONE) { ap->p[2] = obindex; ap->zmin[2] = dist; @@ -334,6 +287,7 @@ void insertFlatObjectNoOsa(RE_APixstrExt *ap, ap->t[2] = obtype; break; } + else if(ap->t[2] & RE_SOLID) if( dist > ap->zmin[2] ) break; if(ap->t[3] == RE_NONE) { ap->p[3] = obindex; ap->zmin[3] = dist; @@ -341,11 +295,15 @@ void insertFlatObjectNoOsa(RE_APixstrExt *ap, ap->t[3] = obtype; break; } - + else if(ap->t[3] & RE_SOLID) if( dist > ap->zmin[3] ) break; + + counter+= 4; + if(counter > RE_MAX_FACES_PER_PIXEL) break; + if(ap->next==0) ap->next= addpseA(); ap= ap->next; }; -} /* end of void insertFlatObjectNoOsa(RE_APixstrExt, int, int, int, int)*/ +} /* ------------------------------------------------------------------------- */ |