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>2005-04-18 23:36:34 +0400
committerTon Roosendaal <ton@blender.org>2005-04-18 23:36:34 +0400
commit99ee8915969ad4cdb55c88c025e674f4c1cb89fd (patch)
tree922bf47c382eaa33280496664e38ef1cf27df4bd /source/blender/render/intern
parent5d31c72020956ab8a372f60a2d8f1ecf85477896 (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')
-rw-r--r--source/blender/render/intern/include/vanillaRenderPipe_types.h2
-rw-r--r--source/blender/render/intern/include/zbufferdatastruct.h1
-rw-r--r--source/blender/render/intern/include/zbufferdatastruct_types.h10
-rw-r--r--source/blender/render/intern/source/vanillaRenderPipe.c57
-rw-r--r--source/blender/render/intern/source/zbufferdatastruct.c90
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)*/
+}
/* ------------------------------------------------------------------------- */