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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2008-01-29 15:20:42 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2008-01-29 15:20:42 +0300
commit8e94028ed57861595e959d30476a74c48868a991 (patch)
tree6e773858db822dba27b314f76356650a67418462
parent5bf5b030e5dd87d4ff80fc44a5b5fb242ad385c2 (diff)
Bounding box clipping in the render engine.
Now bounding boxes are computed per object, and checked first before zbuffering objects. For strands, bounding boxes are computed per original face in the mesh. Overall the speed improvement from this is quite small (zbuffering is rarely the bottleneck), but it seems a sensible thing to do anyway.
-rw-r--r--source/blender/blenkernel/intern/particle_system.c22
-rw-r--r--source/blender/render/intern/include/render_types.h11
-rw-r--r--source/blender/render/intern/include/renderdatabase.h1
-rw-r--r--source/blender/render/intern/include/strand.h1
-rw-r--r--source/blender/render/intern/source/convertblender.c61
-rw-r--r--source/blender/render/intern/source/renderdatabase.c27
-rw-r--r--source/blender/render/intern/source/strand.c96
-rw-r--r--source/blender/render/intern/source/zbuf.c87
8 files changed, 210 insertions, 96 deletions
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 3db42f091d4..c0ffb7c62f8 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -780,6 +780,21 @@ void *exec_distribution(void *data)
return 0;
}
+/* not thread safe, but qsort doesn't take userdata argument */
+static int *COMPARE_ORIG_INDEX = NULL;
+static int compare_orig_index(const void *p1, const void *p2)
+{
+ int index1 = COMPARE_ORIG_INDEX[*(const int*)p1];
+ int index2 = COMPARE_ORIG_INDEX[*(const int*)p2];
+
+ if(index1 < index2)
+ return -1;
+ else if(index1 == index2)
+ return 0;
+ else
+ return 1;
+}
+
/* creates a distribution of coordinates on a DerivedMesh */
/* */
/* 1. lets check from what we are emitting */
@@ -1157,6 +1172,13 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm
MEM_freeN(sum);
+ /* for hair, sort by origindex, allows optimizations in rendering */
+ if(part->type == PART_HAIR) {
+ COMPARE_ORIG_INDEX= dm->getFaceDataArray(dm, CD_ORIGINDEX);
+ if(COMPARE_ORIG_INDEX)
+ qsort(index, totpart, sizeof(int), compare_orig_index);
+ }
+
/* weights are no longer used except for FROM_PARTICLE, which needs them zeroed for indexing */
if(from==PART_FROM_PARTICLE){
for(i=0; i<tot; i++)
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 3a8a491a852..7b68552e5fb 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -247,13 +247,15 @@ typedef struct ObjectRen {
struct Scene *sce;
int index, psysindex, flag, lay;
+ float boundbox[2][3];
+
int totvert, totvlak, totstrand, tothalo;
int vertnodeslen, vlaknodeslen, strandnodeslen, blohalen;
struct VertTableNode *vertnodes;
struct VlakTableNode *vlaknodes;
struct StrandTableNode *strandnodes;
struct HaloRen **bloha;
- ListBase strandbufs;
+ struct StrandBuffer *strandbuf;
char (*mtface)[32];
char (*mcol)[32];
@@ -346,7 +348,7 @@ typedef struct StrandSurface {
int (*face)[4];
float (*co)[3];
/* for occlusion caching */
- float (*col)[3]; /* for occlusion */
+ float (*col)[3];
/* for speedvectors */
float (*prevco)[3], (*nextco)[3];
int totvert, totface;
@@ -354,13 +356,14 @@ typedef struct StrandSurface {
typedef struct StrandBound {
int start, end;
- float bbox[2][3];
+ float boundbox[2][3];
} StrandBound;
typedef struct StrandBuffer {
struct StrandBuffer *next, *prev;
struct StrandVert *vert;
- int totvert;
+ struct StrandBound *bound;
+ int totvert, totbound;
struct ObjectRen *obr;
struct Material *ma;
diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h
index cfcbb4e7775..a204aa7876b 100644
--- a/source/blender/render/intern/include/renderdatabase.h
+++ b/source/blender/render/intern/include/renderdatabase.h
@@ -85,6 +85,7 @@ void free_renderdata_vlaknodes(struct VlakTableNode *vlaknodes);
void set_normalflags(struct Render *re, struct ObjectRen *obr);
void project_renderdata(struct Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, float xoffs, int do_buckets);
+int clip_render_object(float boundbox[][3], float *bounds, float mat[][4]);
/* functions are not exported... so wrong names */
diff --git a/source/blender/render/intern/include/strand.h b/source/blender/render/intern/include/strand.h
index f001bc42112..ebe026e3fec 100644
--- a/source/blender/render/intern/include/strand.h
+++ b/source/blender/render/intern/include/strand.h
@@ -93,6 +93,7 @@ typedef struct StrandShadeCache StrandShadeCache;
void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint);
void render_strand_segment(struct Render *re, float winmat[][4], struct StrandPart *spart, struct ZSpan *zspan, int totzspan, StrandSegment *sseg);
+void strand_minmax(struct StrandRen *strand, float *min, float *max);
struct StrandSurface *cache_strand_surface(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, float mat[][4], int timeoffset);
void free_strand_surface(struct Render *re);
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 6a8059bbdab..7b81acdbc1c 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -111,6 +111,7 @@
#include "strand.h"
#include "texture.h"
#include "sss.h"
+#include "strand.h"
#include "zbuf.h"
#ifndef DISABLE_YAFRAY /* disable yafray */
@@ -1482,6 +1483,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
ParticleCacheKey *cache=0;
StrandBuffer *strandbuf=0;
StrandVert *svert=0;
+ StrandBound *sbound= 0;
StrandRen *strand=0;
RNG *rng= 0;
float loc[3],loc1[3],loc0[3],vel[3],mat[4][4],nmat[3][3],co[3],nor[3],time;
@@ -1491,6 +1493,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
int i, a, k, max_k=0, totpart, totuv=0, override_uv=-1, dosimplify = 0, dosurfacecache = 0;
int path_possible=0, keys_possible=0, baked_keys=0, totchild=psys->totchild;
int seed, path_nbr=0, path=0, orco1=0, adapt=0, uv[3]={0,0,0}, num;
+ int totface, *origindex = 0;
char **uv_name=0;
/* 1. check that everything is ok & updated */
@@ -1653,6 +1656,18 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
else if((re->wrld.mode & WO_AMB_OCC) && (re->wrld.ao_gather_method == WO_AOGATHER_APPROX))
if(ma->amb != 0.0f)
dosurfacecache= 1;
+
+ totface= psmd->dm->getNumFaces(psmd->dm);
+ origindex= psmd->dm->getFaceDataArray(psmd->dm, CD_ORIGINDEX);
+ if(origindex) {
+ for(a=0; a<totface; a++)
+ strandbuf->totbound= MAX2(strandbuf->totbound, origindex[a]);
+ strandbuf->totbound++;
+ }
+ strandbuf->totbound++;
+ strandbuf->bound= MEM_callocN(sizeof(StrandBound)*strandbuf->totbound, "StrandBound");
+ sbound= strandbuf->bound;
+ sbound->start= sbound->end= 0;
}
}
}
@@ -1802,6 +1817,13 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
cache = psys->childcache[a-totpart];
max_k = (int)cache->steps;
}
+
+ if(strandbuf) {
+ if(origindex[cpa->num]+1 > sbound - strandbuf->bound) {
+ sbound= strandbuf->bound + origindex[cpa->num]+1;
+ sbound->start= sbound->end= obr->totstrand;
+ }
+ }
}
/* surface normal shading setup */
@@ -1845,6 +1867,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
}
}
}
+
+ sbound->end++;
}
/* strandco computation setup */
@@ -3841,6 +3865,11 @@ static void check_non_flat_quads(ObjectRen *obr)
static void finalize_render_object(Render *re, ObjectRen *obr, int timeoffset)
{
Object *ob= obr->ob;
+ VertRen *ver= NULL;
+ StrandRen *strand= NULL;
+ StrandBound *sbound= NULL;
+ float min[3], max[3], smin[3], smax[3];
+ int a, b;
if(obr->totvert || obr->totvlak || obr->tothalo || obr->totstrand) {
/* the exception below is because displace code now is in init_render_mesh call,
@@ -3858,6 +3887,36 @@ static void finalize_render_object(Render *re, ObjectRen *obr, int timeoffset)
check_non_flat_quads(obr);
set_fullsample_flag(re, obr);
+
+ /* compute bounding boxes for clipping */
+ INIT_MINMAX(min, max);
+ for(a=0; a<obr->totvert; a++) {
+ if((a & 255)==0) ver= obr->vertnodes[a>>8].vert;
+ else ver++;
+
+ DO_MINMAX(ver->co, min, max);
+ }
+
+ if(obr->strandbuf) {
+ sbound= obr->strandbuf->bound;
+ for(b=0; b<obr->strandbuf->totbound; b++, sbound++) {
+ INIT_MINMAX(smin, smax);
+
+ for(a=sbound->start; a<sbound->end; a++) {
+ strand= RE_findOrAddStrand(obr, a);
+ strand_minmax(strand, smin, smax);
+ }
+
+ VECCOPY(sbound->boundbox[0], smin);
+ VECCOPY(sbound->boundbox[1], smax);
+
+ DO_MINMAX(smin, min, max);
+ DO_MINMAX(smax, min, max);
+ }
+ }
+
+ VECCOPY(obr->boundbox[0], min);
+ VECCOPY(obr->boundbox[1], max);
}
}
}
@@ -4674,7 +4733,7 @@ static void calculate_speedvectors(Render *re, ObjectInstanceRen *obi, float *ve
}
if(obr->strandnodes) {
- strandbuf= obr->strandbufs.first;
+ strandbuf= obr->strandbuf;
mesh= (strandbuf)? strandbuf->surface: NULL;
/* compute speed vectors at surface vertices */
diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c
index 9495360f089..5a749515416 100644
--- a/source/blender/render/intern/source/renderdatabase.c
+++ b/source/blender/render/intern/source/renderdatabase.c
@@ -711,7 +711,7 @@ StrandBuffer *RE_addStrandBuffer(ObjectRen *obr, int totvert)
strandbuf->totvert= totvert;
strandbuf->obr= obr;
- BLI_addtail(&obr->strandbufs, strandbuf);
+ obr->strandbuf= strandbuf;
return strandbuf;
}
@@ -842,9 +842,12 @@ void free_renderdata_tables(Render *re)
obr->strandnodeslen= 0;
}
- for(strandbuf=obr->strandbufs.first; strandbuf; strandbuf=strandbuf->next)
+ strandbuf= obr->strandbuf;
+ if(strandbuf) {
if(strandbuf->vert) MEM_freeN(strandbuf->vert);
- BLI_freelistN(&obr->strandbufs);
+ if(strandbuf->bound) MEM_freeN(strandbuf->bound);
+ MEM_freeN(strandbuf);
+ }
if(obr->mtface)
MEM_freeN(obr->mtface);
@@ -1342,13 +1345,11 @@ void RE_makeRenderInstances(Render *re)
re->instancetable= newlist;
}
-#if 0
-int clip_render_object(ObjectInstanceRen *obi, float *bounds, float winmat[][4])
+int clip_render_object(float boundbox[][3], float *bounds, float winmat[][4])
{
- float mat[4][4], vec[4], max, min, (*boundbox)[3];
+ float mat[4][4], vec[4];
int a, fl, flag= -1;
- boundbox= obi->obr->boundbox;
Mat4CpyMat4(mat, winmat);
for(a=0; a<8; a++) {
@@ -1374,22 +1375,10 @@ int clip_render_object(ObjectInstanceRen *obi, float *bounds, float winmat[][4])
if(vec[2] < -vec[3]) fl |= 16;
if(vec[2] > vec[3]) fl |= 32;
-#if 0
- max= vec[3];
- min= -vec[3];
-
- wco= ho[3];
- if(vec[0] < min) fl |= 1;
- if(vec[0] > max) fl |= 2;
- if(vec[1] < min) fl |= 4;
- if(vec[1] > max) fl |= 8;
-#endif
-
flag &= fl;
if(flag==0) return 0;
}
return flag;
}
-#endif
diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c
index 91b3dfbe621..e66d12de15b 100644
--- a/source/blender/render/intern/source/strand.c
+++ b/source/blender/render/intern/source/strand.c
@@ -750,12 +750,13 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, RenderLayer *rl, APixstrand
ZSpan zspan;
StrandRen *strand=0;
StrandVert *svert;
+ StrandBound *sbound;
StrandPart spart;
StrandSegment sseg;
StrandSortSegment *sortsegments = NULL, *sortseg, *firstseg;
MemArena *memarena;
float z[4], bounds[4], winmat[4][4];
- int a, b, i, totsegment, clip[4];
+ int a, b, c, i, totsegment, clip[4];
if(re->test_break())
return 0;
@@ -800,58 +801,66 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, RenderLayer *rl, APixstrand
sortseg= sortsegments;
totsegment= 0;
+ /* for all object instances */
for(obi=re->instancetable.first, i=0; obi; obi=obi->next, i++) {
obr= obi->obr;
+ if(!obr->strandbuf || !(obr->strandbuf->lay & rl->lay))
+ continue;
+
+ /* compute matrix and try clipping whole object */
if(obi->flag & R_TRANSFORMED)
zbuf_make_winmat(re, obi->mat, winmat);
else
zbuf_make_winmat(re, NULL, winmat);
- for(a=0; a<obr->totstrand; a++) {
- if((a & 255)==0) strand= obr->strandnodes[a>>8].strand;
- else strand++;
+ if(clip_render_object(obi->obr->boundbox, bounds, winmat))
+ continue;
- if(re->test_break())
- break;
-
- if(!(strand->buffer->lay & rl->lay))
+ /* for each bounding box containing a number of strands */
+ sbound= obr->strandbuf->bound;
+ for(c=0; c<obr->strandbuf->totbound; c++, sbound++) {
+ if(clip_render_object(sbound->boundbox, bounds, winmat))
continue;
- svert= strand->vert;
-
- /* keep clipping and z depth for 4 control points */
- clip[1]= strand_test_clip(winmat, &zspan, bounds, svert->co, &z[1]);
- clip[2]= strand_test_clip(winmat, &zspan, bounds, (svert+1)->co, &z[2]);
- clip[0]= clip[1]; z[0]= z[1];
-
- for(b=0; b<strand->totvert-1; b++, svert++) {
- /* compute 4th point clipping and z depth */
- if(b < strand->totvert-2) {
- clip[3]= strand_test_clip(winmat, &zspan, bounds, (svert+2)->co, &z[3]);
- }
- else {
- clip[3]= clip[2]; z[3]= z[2];
- }
-
- /* check clipping and add to sortsegments buffer */
- if(!(clip[0] & clip[1] & clip[2] & clip[3])) {
- sortseg= BLI_memarena_alloc(memarena, sizeof(StrandSortSegment));
- sortseg->obi= i;
- sortseg->strand= strand->index;
- sortseg->segment= b;
+ /* for each strand in this bounding box */
+ for(a=sbound->start; a<sbound->end; a++) {
+ strand= RE_findOrAddStrand(obr, a);
+ svert= strand->vert;
- sortseg->z= 0.5f*(z[1] + z[2]);
+ /* keep clipping and z depth for 4 control points */
+ clip[1]= strand_test_clip(winmat, &zspan, bounds, svert->co, &z[1]);
+ clip[2]= strand_test_clip(winmat, &zspan, bounds, (svert+1)->co, &z[2]);
+ clip[0]= clip[1]; z[0]= z[1];
- sortseg->next= firstseg;
- firstseg= sortseg;
- totsegment++;
+ for(b=0; b<strand->totvert-1; b++, svert++) {
+ /* compute 4th point clipping and z depth */
+ if(b < strand->totvert-2) {
+ clip[3]= strand_test_clip(winmat, &zspan, bounds, (svert+2)->co, &z[3]);
+ }
+ else {
+ clip[3]= clip[2]; z[3]= z[2];
+ }
+
+ /* check clipping and add to sortsegments buffer */
+ if(!(clip[0] & clip[1] & clip[2] & clip[3])) {
+ sortseg= BLI_memarena_alloc(memarena, sizeof(StrandSortSegment));
+ sortseg->obi= i;
+ sortseg->strand= strand->index;
+ sortseg->segment= b;
+
+ sortseg->z= 0.5f*(z[1] + z[2]);
+
+ sortseg->next= firstseg;
+ firstseg= sortseg;
+ totsegment++;
+ }
+
+ /* shift clipping and z depth */
+ clip[0]= clip[1]; z[0]= z[1];
+ clip[1]= clip[2]; z[1]= z[2];
+ clip[2]= clip[3]; z[2]= z[3];
}
-
- /* shift clipping and z depth */
- clip[0]= clip[1]; z[0]= z[1];
- clip[1]= clip[2]; z[1]= z[2];
- clip[2]= clip[3]; z[2]= z[3];
}
}
}
@@ -973,3 +982,12 @@ void free_strand_surface(Render *re)
BLI_freelistN(&re->strandsurface);
}
+void strand_minmax(StrandRen *strand, float *min, float *max)
+{
+ StrandVert *svert;
+ int a;
+
+ for(a=0, svert=strand->vert; a<strand->totvert; a++, svert++)
+ DO_MINMAX(svert->co, min, max)
+}
+
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 21c31d55e87..080a66e46a7 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -2081,6 +2081,9 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart*,
else
zbuf_make_winmat(&R, NULL, winmat);
+ if(clip_render_object(obi->obr->boundbox, bounds, winmat))
+ continue;
+
zbuf_project_cache_clear(cache, obr->totvert);
for(v=0; v<obr->totvlak; v++) {
@@ -2337,8 +2340,9 @@ void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int
StrandSegment sseg;
StrandRen *strand= NULL;
StrandVert *svert;
+ StrandBound *sbound;
float obwinmat[4][4], ho1[4], ho2[4], ho3[4], ho4[4];
- int a, b, i, c1, c2, c3, c4, ok=1, lay= -1;
+ int a, b, c, i, c1, c2, c3, c4, ok=1, lay= -1;
if(lar->mode & LA_LAYER) lay= lar->lay;
@@ -2374,6 +2378,9 @@ void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int
else
Mat4CpyMat4(obwinmat, winmat);
+ if(clip_render_object(obi->obr->boundbox, NULL, obwinmat))
+ continue;
+
zbuf_project_cache_clear(cache, obr->totvert);
/* faces */
@@ -2417,45 +2424,54 @@ void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int
}
/* strands */
- for(a=0; a<obr->totstrand; a++) {
- if((a & 255)==0) strand= obr->strandnodes[a>>8].strand;
- else strand++;
+ if(obr->strandbuf) {
+ /* for each bounding box containing a number of strands */
+ sbound= obr->strandbuf->bound;
+ for(c=0; c<obr->strandbuf->totbound; c++, sbound++) {
+ if(clip_render_object(sbound->boundbox, NULL, obwinmat))
+ continue;
- sseg.obi= obi;
- sseg.buffer= strand->buffer;
- sseg.sqadaptcos= sseg.buffer->adaptcos;
- sseg.sqadaptcos *= sseg.sqadaptcos;
- sseg.strand= strand;
- svert= strand->vert;
+ /* for each strand in this bounding box */
+ for(a=sbound->start; a<sbound->end; a++) {
+ strand= RE_findOrAddStrand(obr, a);
+
+ sseg.obi= obi;
+ sseg.buffer= strand->buffer;
+ sseg.sqadaptcos= sseg.buffer->adaptcos;
+ sseg.sqadaptcos *= sseg.sqadaptcos;
+ sseg.strand= strand;
+ svert= strand->vert;
+
+ /* note, these conditions are copied in shadowbuf_autoclip() */
+ if(sseg.buffer->ma!= ma) {
+ ma= sseg.buffer->ma;
+ ok= 1;
+ if((ma->mode & MA_SHADBUF)==0) ok= 0;
+ }
- /* note, these conditions are copied in shadowbuf_autoclip() */
- if(sseg.buffer->ma!= ma) {
- ma= sseg.buffer->ma;
- ok= 1;
- if((ma->mode & MA_SHADBUF)==0) ok= 0;
- }
+ if(ok && (sseg.buffer->lay & lay)) {
+ zbuf_project_cache_clear(cache, strand->totvert);
- if(ok && (sseg.buffer->lay & lay)) {
- zbuf_project_cache_clear(cache, strand->totvert);
+ for(b=0; b<strand->totvert-1; b++, svert++) {
+ sseg.v[0]= (b > 0)? (svert-1): svert;
+ sseg.v[1]= svert;
+ sseg.v[2]= svert+1;
+ sseg.v[3]= (b < strand->totvert-2)? svert+2: svert+1;
- for(b=0; b<strand->totvert-1; b++, svert++) {
- sseg.v[0]= (b > 0)? (svert-1): svert;
- sseg.v[1]= svert;
- sseg.v[2]= svert+1;
- sseg.v[3]= (b < strand->totvert-2)? svert+2: svert+1;
+ c1= zbuf_shadow_project(cache, sseg.v[0]-strand->vert, obwinmat, sseg.v[0]->co, ho1);
+ c2= zbuf_shadow_project(cache, sseg.v[1]-strand->vert, obwinmat, sseg.v[1]->co, ho2);
+ c3= zbuf_shadow_project(cache, sseg.v[2]-strand->vert, obwinmat, sseg.v[2]->co, ho3);
+ c4= zbuf_shadow_project(cache, sseg.v[3]-strand->vert, obwinmat, sseg.v[3]->co, ho4);
- c1= zbuf_shadow_project(cache, sseg.v[0]-strand->vert, obwinmat, sseg.v[0]->co, ho1);
- c2= zbuf_shadow_project(cache, sseg.v[1]-strand->vert, obwinmat, sseg.v[1]->co, ho2);
- c3= zbuf_shadow_project(cache, sseg.v[2]-strand->vert, obwinmat, sseg.v[2]->co, ho3);
- c4= zbuf_shadow_project(cache, sseg.v[3]-strand->vert, obwinmat, sseg.v[3]->co, ho4);
+ if(!(c1 & c2 & c3 & c4))
+ render_strand_segment(re, winmat, NULL, &zspan, 1, &sseg);
+ }
+ }
- if(!(c1 & c2 & c3 & c4))
- render_strand_segment(re, winmat, NULL, &zspan, 1, &sseg);
+ if((a & 255)==255 && re->test_break())
+ break;
}
}
-
- if((a & 255)==255 && re->test_break())
- break;
}
if(re->test_break())
@@ -2599,6 +2615,9 @@ void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(vo
else
zbuf_make_winmat(&R, NULL, winmat);
+ if(clip_render_object(obi->obr->boundbox, bounds, winmat))
+ continue;
+
zbuf_project_cache_clear(cache, obr->totvert);
for(v=0; v<obr->totvlak; v++) {
@@ -3286,7 +3305,6 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, un
/* to center the sample position */
zspan->zofsx -= 0.5f;
zspan->zofsy -= 0.5f;
-
}
/* we use this to test if nothing was filled in */
@@ -3303,6 +3321,9 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, un
else
zbuf_make_winmat(&R, NULL, winmat);
+ if(clip_render_object(obi->obr->boundbox, bounds, winmat))
+ continue;
+
zbuf_project_cache_clear(cache, obr->totvert);
for(v=0; v<obr->totvlak; v++) {