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>2006-02-02 20:54:22 +0300
committerTon Roosendaal <ton@blender.org>2006-02-02 20:54:22 +0300
commitf493e8ed2e6af6d1ed4d37906ce445b914374f63 (patch)
tree66dce17b2d824624ffcd9134b8982c2eb5ef12c5 /source/blender/render
parentccbc32abed93fa47f1099f9893a59b8a901b4f56 (diff)
features & fixes:
- Enabled Groups to execute in Compositor. They were ignored still. Note; inside of groups nothing is cached, so a change of a group input will recalculate it fully. This is needed because groups are linked data (instances use same internal nodes). - Made Composit node "Viewer" display correctly input for images with 1/2/3/4 channels. - Added pass rendering, tested now with only regular Materials. For Material nodes this is quite more complex... since they cannot be easily separated in passes (each Material does a full shade) In this commit all pass render is disabled though, will continue work on that later. Sneak preview: http://www.blender.org/bf/rt.jpg (temporal image) - What did remain is the 'Normal' pass output. Normal works very nice for relighting effects. Use the "Normal Node" to define where more or less light should be. (Use "Value Map" node to tweak influence of the Normal node 'dot' output.) - EVIL bug fix: I've spend almost a day finding it... when combining AO and mirror render, the event queue was totally screwing up... two things not related at all! Found out error was in ray-mirror code, which was using partially uninitialized 'ShadeInput' data to pass on to render code. - Another fix; made sure that while thread render, the threads don't get events, only the main program will do. Might fix issues reported by people on linux/windows.
Diffstat (limited to 'source/blender/render')
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h59
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h8
-rw-r--r--source/blender/render/intern/include/pixelblending.h1
-rw-r--r--source/blender/render/intern/include/rendercore.h2
-rw-r--r--source/blender/render/intern/source/pipeline.c89
-rw-r--r--source/blender/render/intern/source/pixelblending.c46
-rw-r--r--source/blender/render/intern/source/ray.c24
-rw-r--r--source/blender/render/intern/source/rendercore.c926
-rw-r--r--source/blender/render/intern/source/zbuf.c16
9 files changed, 747 insertions, 424 deletions
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index a9b75184e36..1afce546791 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -55,6 +55,12 @@ typedef struct Render Render;
and how it's converted
*/
+typedef struct RenderPass {
+ struct RenderPass *next, *prev;
+ int passtype;
+ float *rect;
+} RenderPass;
+
/* a renderlayer is a full image, but with all passes and samples */
/* size of the rects is defined in RenderResult */
typedef struct RenderLayer {
@@ -66,8 +72,6 @@ typedef struct RenderLayer {
int layflag, passflag;
float *rectf; /* 4 float, standard rgba buffer */
- float *rectz; /* 1 float, standard camera coordinate zbuffer */
- float *rectvec; /* 2 float, screen aligned speed vectors */
ListBase passes;
@@ -113,19 +117,20 @@ typedef struct RenderStats {
/* the name is used as identifier, so elsewhere in blender the result can retrieved */
/* calling a new render with same name, frees automatic existing render */
-Render *RE_NewRender (const char *name);
-Render *RE_GetRender(const char *name);
+struct Render *RE_NewRender (const char *name);
+struct Render *RE_GetRender(const char *name);
/* use free render as signal to do everything over (previews) */
-void RE_FreeRender (Render *re);
+void RE_FreeRender (struct Render *re);
/* only called on exit */
void RE_FreeAllRender (void);
/* get results and statistics */
-RenderResult *RE_GetResult(Render *re);
-void RE_GetResultImage(Render *re, RenderResult *rr);
-RenderStats *RE_GetStats(Render *re);
-void RE_ResultGet32(Render *re, unsigned int *rect);
+RenderResult *RE_GetResult(struct Render *re);
+void RE_GetResultImage(struct Render *re, RenderResult *rr);
+RenderStats *RE_GetStats(struct Render *re);
+void RE_ResultGet32(struct Render *re, unsigned int *rect);
+float *RE_RenderLayerGetPass(RenderLayer *rl, int passtype);
/* obligatory initialize call, disprect is optional */
void RE_InitState (struct Render *re, struct RenderData *rd, int winx, int winy, rcti *disprect);
@@ -134,37 +139,37 @@ void RE_InitState (struct Render *re, struct RenderData *rd, int winx, int winy,
void RE_SetDispRect (struct Render *re, rcti *disprect);
/* set up the viewplane/perspective matrix, three choices */
-void RE_SetCamera(Render *re, struct Object *camera);
-void RE_SetWindow (Render *re, rctf *viewplane, float clipsta, float clipend);
-void RE_SetOrtho (Render *re, rctf *viewplane, float clipsta, float clipend);
+void RE_SetCamera(struct Render *re, struct Object *camera);
+void RE_SetWindow (struct Render *re, rctf *viewplane, float clipsta, float clipend);
+void RE_SetOrtho (struct Render *re, rctf *viewplane, float clipsta, float clipend);
/* option to set viewmatrix before making dbase */
-void RE_SetView (Render *re, float mat[][4]);
+void RE_SetView (struct Render *re, float mat[][4]);
/* make or free the dbase */
-void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view);
-void RE_Database_Free (Render *re);
+void RE_Database_FromScene(struct Render *re, struct Scene *scene, int use_camera_view);
+void RE_Database_Free (struct Render *re);
/* project dbase again, when viewplane/perspective changed */
-void RE_DataBase_ApplyWindow(Render *re);
+void RE_DataBase_ApplyWindow(struct Render *re);
/* the main processor, assumes all was set OK! */
-void RE_TileProcessor(Render *re);
+void RE_TileProcessor(struct Render *re);
/* only RE_NewRender() needed, main Blender render calls */
-void RE_BlenderFrame(Render *re, struct Scene *scene, int frame);
-void RE_BlenderAnim(Render *re, struct Scene *scene, int sfra, int efra);
+void RE_BlenderFrame(struct Render *re, struct Scene *scene, int frame);
+void RE_BlenderAnim(struct Render *re, struct Scene *scene, int sfra, int efra);
/* display and event callbacks */
-void RE_display_init_cb (Render *re, void (*f)(RenderResult *rr));
-void RE_display_clear_cb(Render *re, void (*f)(RenderResult *rr));
-void RE_display_draw_cb (Render *re, void (*f)(RenderResult *rr, struct rcti *rect));
-void RE_stats_draw_cb (Render *re, void (*f)(RenderStats *rs));
-void RE_timecursor_cb (Render *re, void (*f)(int));
-void RE_test_break_cb (Render *re, int (*f)(void));
-void RE_test_return_cb (Render *re, int (*f)(void));
-void RE_error_cb (Render *re, void (*f)(const char *str));
+void RE_display_init_cb (struct Render *re, void (*f)(RenderResult *rr));
+void RE_display_clear_cb(struct Render *re, void (*f)(RenderResult *rr));
+void RE_display_draw_cb (struct Render *re, void (*f)(RenderResult *rr, struct rcti *rect));
+void RE_stats_draw_cb (struct Render *re, void (*f)(RenderStats *rs));
+void RE_timecursor_cb (struct Render *re, void (*f)(int));
+void RE_test_break_cb (struct Render *re, int (*f)(void));
+void RE_test_return_cb (struct Render *re, int (*f)(void));
+void RE_error_cb (struct Render *re, void (*f)(const char *str));
diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h
index b8bd46d784e..54307d933e9 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -46,11 +46,15 @@ typedef struct TexResult {
typedef struct ShadeResult
{
float combined[4];
+ float col[4];
+ float alpha;
float diff[3];
float spec[3];
- float alpha;
+ float shad[3];
+ float ao[3];
+ float ray[3];
float nor[3];
- float winspeed[2];
+ float winspeed[3];
} ShadeResult;
diff --git a/source/blender/render/intern/include/pixelblending.h b/source/blender/render/intern/include/pixelblending.h
index bc44c916701..2713b2023a9 100644
--- a/source/blender/render/intern/include/pixelblending.h
+++ b/source/blender/render/intern/include/pixelblending.h
@@ -34,6 +34,7 @@
* (float vecs to float vec)
*/
void add_filt_fmask(unsigned int mask, float *col, float *rowbuf, int row_w);
+void add_filt_fmask_pixsize(unsigned int mask, float *in, float *rowbuf, int row_w, int pixsize);
/**
* Alpha-over blending for floats.
diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h
index 793480458c6..91aeaf788c9 100644
--- a/source/blender/render/intern/include/rendercore.h
+++ b/source/blender/render/intern/include/rendercore.h
@@ -85,7 +85,7 @@ void shade_material_loop(struct ShadeInput *shi, struct ShadeResult *shr);
void zbufshade(void);
void zbufshadeDA(void); /* Delta Accum Pixel Struct */
-void *shadepixel(RenderPart *pa, float x, float y, int z, int facenr, int mask, struct ShadeResult *shr, float *rco);
+void *shadepixel(RenderPart *pa, float x, float y, int z, int facenr, int mask, struct ShadeResult *shr, float *rco, int passflag);
int count_mask(unsigned short mask);
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index c1baa04553b..558e1cc17ff 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -133,6 +133,11 @@ void RE_freeN(void *poin)
/* ********************** */
+static int g_break= 0;
+static int thread_break(void)
+{
+ return g_break;
+}
/* default callbacks, set in each new render */
static void result_nothing(RenderResult *rr) {}
@@ -148,9 +153,14 @@ static void free_render_result(RenderResult *res)
while(res->layers.first) {
RenderLayer *rl= res->layers.first;
+
if(rl->rectf) RE_freeN(rl->rectf);
- if(rl->rectz) RE_freeN(rl->rectz);
- if(rl->rectvec) RE_freeN(rl->rectvec);
+ while(rl->passes.first) {
+ RenderPass *rpass= rl->passes.first;
+ RE_freeN(rpass->rect);
+ BLI_remlink(&rl->passes, rpass);
+ RE_freeN(rpass);
+ }
BLI_remlink(&res->layers, rl);
RE_freeN(rl);
}
@@ -165,6 +175,25 @@ static void free_render_result(RenderResult *res)
RE_freeN(res);
}
+static void render_layer_add_pass(RenderLayer *rl, int rectsize, int passtype, char *mallocstr)
+{
+ RenderPass *rpass= MEM_mallocN(sizeof(RenderPass), mallocstr);
+
+ BLI_addtail(&rl->passes, rpass);
+ rpass->passtype= passtype;
+ rpass->rect= MEM_callocN(sizeof(float)*rectsize, mallocstr);
+}
+
+float *RE_RenderLayerGetPass(RenderLayer *rl, int passtype)
+{
+ RenderPass *rpass;
+
+ for(rpass=rl->passes.first; rpass; rpass= rpass->next)
+ if(rpass->passtype== passtype)
+ return rpass->rect;
+ return NULL;
+}
+
/* called by main render as well for parts */
/* will read info from Render *re to define layers */
/* called in threads */
@@ -205,10 +234,25 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
rl->passflag= srl->passflag;
rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "layer float rgba");
+
if(srl->passflag & SCE_PASS_Z)
- rl->rectz= RE_callocN(rectx*recty*sizeof(float), "layer float Z");
+ render_layer_add_pass(rl, rectx*recty, SCE_PASS_Z, "Layer float Z");
if(srl->passflag & SCE_PASS_VECTOR)
- rl->rectvec= RE_callocN(rectx*recty*sizeof(float)*2, "layer float Vector");
+ render_layer_add_pass(rl, rectx*recty*2, SCE_PASS_VECTOR, "layer float Vector");
+ if(srl->passflag & SCE_PASS_NORMAL)
+ render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_NORMAL, "layer float Normal");
+ if(srl->passflag & SCE_PASS_RGBA)
+ render_layer_add_pass(rl, rectx*recty*4, SCE_PASS_RGBA, "layer float Color");
+ if(srl->passflag & SCE_PASS_DIFFUSE)
+ render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_DIFFUSE, "layer float Diffuse");
+ if(srl->passflag & SCE_PASS_SPEC)
+ render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_SPEC, "layer float Spec");
+ if(srl->passflag & SCE_PASS_SHADOW)
+ render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_SHADOW, "layer float Shadow");
+ if(srl->passflag & SCE_PASS_AO)
+ render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_AO, "layer float AO");
+ if(srl->passflag & SCE_PASS_RAY)
+ render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_RAY, "layer float Mirror");
}
/* previewrender and envmap don't do layers, so we make a default one */
@@ -217,13 +261,11 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
BLI_addtail(&rr->layers, rl);
rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "prev/env float rgba");
- rl->rectz= RE_callocN(rectx*recty*sizeof(float), "prev/env float Z");
/* note, this has to be in sync with scene.c */
rl->lay= (1<<20) -1;
rl->layflag= 0x7FFF; /* solid ztra halo strand */
- rl->passflag= SCE_PASS_COMBINED|SCE_PASS_Z;
-
+ rl->passflag= SCE_PASS_COMBINED;
}
return rr;
@@ -277,18 +319,30 @@ static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target,
static void merge_render_result(RenderResult *rr, RenderResult *rrpart)
{
RenderLayer *rl, *rlp;
+ RenderPass *rpass, *rpassp;
for(rl= rr->layers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) {
/* combined */
if(rl->rectf && rlp->rectf)
do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4);
- /* z */
- if(rl->rectz && rlp->rectz)
- do_merge_tile(rr, rrpart, rl->rectz, rlp->rectz, 1);
- /* vector */
- if(rl->rectvec && rlp->rectvec)
- do_merge_tile(rr, rrpart, rl->rectvec, rlp->rectvec, 2);
+
+ /* passes are allocated in sync */
+ for(rpass= rl->passes.first, rpassp= rlp->passes.first; rpass && rpassp; rpass= rpass->next, rpassp= rpassp->next) {
+ switch(rpass->passtype) {
+ case SCE_PASS_Z:
+ do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 1);
+ break;
+ case SCE_PASS_VECTOR:
+ do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 2);
+ break;
+ case SCE_PASS_RGBA:
+ do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 4);
+ break;
+ default:
+ do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 3);
+ }
+ }
}
}
@@ -337,7 +391,7 @@ void RE_GetResultImage(Render *re, RenderResult *rr)
if(rr->rectf==NULL)
rr->rectf= rl->rectf;
if(rr->rectz==NULL)
- rr->rectz= rl->rectz;
+ rr->rectz= RE_RenderLayerGetPass(rl, SCE_PASS_Z);
}
}
}
@@ -683,11 +737,12 @@ static void threaded_tile_processor(Render *re)
/* assuming no new data gets added to dbase... */
R= *re;
+ /* set threadsafety */
+ R.test_break= thread_break;
malloc_lock = SDL_CreateMutex();
while(rendering) {
- /* I noted that test_break() in a thread doesn't make ghost send ESC */
if(BLI_available_threads(&threads) && !re->test_break()) {
pa= find_nicest_part(re);
if(pa) {
@@ -728,12 +783,14 @@ static void threaded_tile_processor(Render *re)
drawtimer= 0;
/* on break, wait for all slots to get freed */
- if(re->test_break() && BLI_available_threads(&threads)==maxthreads)
+ if( (g_break=re->test_break()) && BLI_available_threads(&threads)==maxthreads)
rendering= 0;
}
+ /* restore threadsafety */
if(malloc_lock) SDL_DestroyMutex(malloc_lock); malloc_lock= NULL;
+ g_break= 0;
BLI_end_threads(&threads);
freeparts(re);
diff --git a/source/blender/render/intern/source/pixelblending.c b/source/blender/render/intern/source/pixelblending.c
index ece9970e885..3048a151925 100644
--- a/source/blender/render/intern/source/pixelblending.c
+++ b/source/blender/render/intern/source/pixelblending.c
@@ -212,24 +212,18 @@ void add_filt_fmask(unsigned int mask, float *col, float *rowbuf, int row_w)
}
}
-/* filtered adding to scanlines */
-void add_filt_fmask_alphaunder(unsigned int mask, float *col, float *rowbuf, int row_w)
+void add_filt_fmask_pixsize(unsigned int mask, float *in, float *rowbuf, int row_w, int pixsize)
{
/* calc the value of mask */
float **fmask1= R.samples->fmask1, **fmask2=R.samples->fmask2;
float *rb1, *rb2, *rb3;
- float val, r, g, b, al, acol[4];
+ float val;
unsigned int a, maskand, maskshift;
- int j;
-
- r= col[0];
- g= col[1];
- b= col[2];
- al= col[3];
+ int i, j;
- rb2= rowbuf-4;
- rb3= rb2-4*row_w;
- rb1= rb2+4*row_w;
+ rb2= rowbuf-pixsize;
+ rb3= rb2-pixsize*row_w;
+ rb1= rb2+pixsize*row_w;
maskand= (mask & 255);
maskshift= (mask >>8);
@@ -240,40 +234,30 @@ void add_filt_fmask_alphaunder(unsigned int mask, float *col, float *rowbuf, int
val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
if(val!=0.0) {
- acol[0]= val*r;
- acol[1]= val*g;
- acol[2]= val*b;
- acol[3]= val*al;
- addAlphaUnderFloat(rb1, acol);
+ for(i= 0; i<pixsize; i++)
+ rb1[i]+= val*in[i];
}
a+=3;
val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
if(val!=0.0) {
- acol[0]= val*r;
- acol[1]= val*g;
- acol[2]= val*b;
- acol[3]= val*al;
- addAlphaUnderFloat(rb2, acol);
+ for(i= 0; i<pixsize; i++)
+ rb2[i]+= val*in[i];
}
a+=3;
val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
if(val!=0.0) {
- acol[0]= val*r;
- acol[1]= val*g;
- acol[2]= val*b;
- acol[3]= val*al;
- addAlphaUnderFloat(rb3, acol);
+ for(i= 0; i<pixsize; i++)
+ rb3[i]+= val*in[i];
}
- rb1+= 4;
- rb2+= 4;
- rb3+= 4;
+ rb1+= pixsize;
+ rb2+= pixsize;
+ rb3+= pixsize;
}
}
-
/* ------------------------------------------------------------------------- */
void addalphaAddFloat(float *dest, float *source)
{
diff --git a/source/blender/render/intern/source/ray.c b/source/blender/render/intern/source/ray.c
index d5d0a951604..02dcf4bb60d 100644
--- a/source/blender/render/intern/source/ray.c
+++ b/source/blender/render/intern/source/ray.c
@@ -1516,7 +1516,7 @@ static void color_combine(float *result, float fac1, float fac2, float *col1, fl
#endif
/* the main recursive tracer itself */
-static void traceray(short depth, float *start, float *vec, float *col, VlakRen *vlr, int mask, int osatex, int traflag)
+static void traceray(ShadeInput *origshi, short depth, float *start, float *vec, float *col, VlakRen *vlr, int traflag)
{
ShadeInput shi;
ShadeResult shr;
@@ -1533,9 +1533,13 @@ static void traceray(short depth, float *start, float *vec, float *col, VlakRen
if( d3dda(&isec) ) {
- shi.mask= mask;
- shi.osatex= osatex;
+ shi.mask= origshi->mask;
+ shi.osatex= origshi->osatex;
shi.depth= 1; // only now to indicate tracing
+ shi.thread= origshi->thread;
+ shi.xs= origshi->xs;
+ shi.ys= origshi->ys;
+ shi.do_preview= 0;
shade_ray(&isec, &shi, &shr);
@@ -1559,10 +1563,10 @@ static void traceray(short depth, float *start, float *vec, float *col, VlakRen
refraction(refract, shi.vn, shi.view, shi.ang);
}
traflag |= RAY_TRA;
- traceray(depth-1, shi.co, refract, tracol, shi.vlr, shi.mask, osatex, traflag ^ RAY_TRAFLIP);
+ traceray(origshi, depth-1, shi.co, refract, tracol, shi.vlr, traflag ^ RAY_TRAFLIP);
}
else
- traceray(depth-1, shi.co, shi.view, tracol, shi.vlr, shi.mask, osatex, 0);
+ traceray(origshi, depth-1, shi.co, shi.view, tracol, shi.vlr, 0);
f= shr.alpha; f1= 1.0-f;
fr= 1.0+ shi.mat->filter*(shi.r-1.0);
@@ -1591,7 +1595,7 @@ static void traceray(short depth, float *start, float *vec, float *col, VlakRen
float mircol[4];
reflection(ref, shi.vn, shi.view, NULL);
- traceray(depth-1, shi.co, ref, mircol, shi.vlr, shi.mask, osatex, 0);
+ traceray(origshi, depth-1, shi.co, ref, mircol, shi.vlr, 0);
f1= 1.0-f;
@@ -1767,10 +1771,10 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr)
if(shi->mat->mode & MA_RAYTRANSP) {
refraction(refract, shi->vn, shi->view, shi->ang);
- traceray(shi->mat->ray_depth_tra, shi->co, refract, tracol, shi->vlr, shi->mask, 0, RAY_TRA|RAY_TRAFLIP);
+ traceray(shi, shi->mat->ray_depth_tra, shi->co, refract, tracol, shi->vlr, RAY_TRA|RAY_TRAFLIP);
}
else
- traceray(shi->mat->ray_depth_tra, shi->co, shi->view, tracol, shi->vlr, shi->mask, 0, 0);
+ traceray(shi, shi->mat->ray_depth_tra, shi->co, shi->view, tracol, shi->vlr, 0);
f= shr->alpha; f1= 1.0-f;
fr= 1.0+ shi->mat->filter*(shi->r-1.0);
@@ -1796,7 +1800,7 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr)
else
reflection(vec, shi->vn, shi->view, NULL);
- traceray(shi->mat->ray_depth, shi->co, vec, mircol, shi->vlr, shi->mask, shi->osatex, 0);
+ traceray(shi, shi->mat->ray_depth, shi->co, vec, mircol, shi->vlr, 0);
f= i*fr*(1.0-shr->spec[0]); f1= 1.0-i;
shr->diff[0]= f*mircol[0] + f1*shr->diff[0];
@@ -2073,7 +2077,7 @@ void ray_ao(ShadeInput *shi, float *shadfac)
bias= 0.0;
nrm= shi->facenor;
}
-
+
vec= sphere_sampler(R.wrld.aomode, R.wrld.aosamp, shi->thread, shi->xs, shi->ys);
// warning: since we use full sphere now, and dotproduct is below, we do twice as much
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index ba45953eefc..c5d362d8c2d 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -1073,7 +1073,9 @@ static void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, floa
/* blending method */
fac= col[3]*ma->rampfac_col;
- colt[0]= shi->r; colt[1]= shi->g; colt[2]= shi->b;
+ colt[0]= shi->r;
+ colt[1]= shi->g;
+ colt[2]= shi->b;
ramp_blend(ma->rampblend_col, colt, colt+1, colt+2, fac, col);
@@ -1158,7 +1160,9 @@ static void ambient_occlusion(ShadeInput *shi, ShadeResult *shr)
else if (R.wrld.aomix==WO_AOSUB) shadfac[3] = shadfac[3]-1.0;
f= R.wrld.aoenergy*shadfac[3]*shi->amb;
- add_to_diffuse(shr->diff, shi, f, f, f, f);
+ shr->ao[0]+= f;
+ shr->ao[1]+= f;
+ shr->ao[2]+= f;
}
else {
if (R.wrld.aomix==WO_AOADDSUB) {
@@ -1172,11 +1176,453 @@ static void ambient_occlusion(ShadeInput *shi, ShadeResult *shr)
shadfac[2] = shadfac[2]-1.0;
}
f= R.wrld.aoenergy*shi->amb;
- add_to_diffuse(shr->diff, shi, f, f*shadfac[0], f*shadfac[1], f*shadfac[2]);
+ shr->ao[0]+= f*shadfac[0];
+ shr->ao[1]+= f*shadfac[1];
+ shr->ao[2]+= f*shadfac[2];
}
}
}
+/* function returns diff, spec and optional shadow */
+/* if passrender it returns shadow color, otherwise it applies it to diffuse and spec */
+static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int passrender)
+{
+ Material *ma= shi->mat;
+ VlakRen *vlr= shi->vlr;
+ float lv[3], lampdist, ld, lacol[3], shadfac[4];
+ float i, is, inp, i_noshad, *vn, *view, vnor[3], phongcorr;
+
+ vn= shi->vn;
+ view= shi->view;
+
+ /* lampdist calculation */
+ if(lar->type==LA_SUN || lar->type==LA_HEMI) {
+ VECCOPY(lv, lar->vec);
+ lampdist= 1.0;
+ }
+ else {
+ lv[0]= shi->co[0]-lar->co[0];
+ lv[1]= shi->co[1]-lar->co[1];
+ lv[2]= shi->co[2]-lar->co[2];
+ ld= sqrt(lv[0]*lv[0]+lv[1]*lv[1]+lv[2]*lv[2]);
+ lv[0]/= ld;
+ lv[1]/= ld;
+ lv[2]/= ld;
+
+ /* ld is re-used further on (texco's) */
+ if(lar->type==LA_AREA) {
+ lampdist= 1.0;
+ }
+ else {
+ if(lar->mode & LA_QUAD) {
+ float t= 1.0;
+ if(lar->ld1>0.0)
+ t= lar->dist/(lar->dist+lar->ld1*ld);
+ if(lar->ld2>0.0)
+ t*= lar->distkw/(lar->distkw+lar->ld2*ld*ld);
+
+ lampdist= t;
+ }
+ else {
+ lampdist= (lar->dist/(lar->dist+ld));
+ }
+
+ if(lar->mode & LA_SPHERE) {
+ float t= lar->dist - ld;
+ if(t<0.0) return;
+
+ t/= lar->dist;
+ lampdist*= (t);
+ }
+ }
+ }
+
+ lacol[0]= lar->r;
+ lacol[1]= lar->g;
+ lacol[2]= lar->b;
+
+ if(lar->type==LA_SPOT) {
+ float t, inpr;
+
+ if(lar->mode & LA_SQUARE) {
+ if(lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0) {
+ float lvrot[3], x;
+
+ /* rotate view to lampspace */
+ VECCOPY(lvrot, lv);
+ MTC_Mat3MulVecfl(lar->imat, lvrot);
+
+ x= MAX2(fabs(lvrot[0]/lvrot[2]) , fabs(lvrot[1]/lvrot[2]));
+ /* 1.0/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */
+
+ inpr= 1.0f/(sqrt(1.0f+x*x));
+ }
+ else inpr= 0.0;
+ }
+ else {
+ inpr= lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2];
+ }
+
+ t= lar->spotsi;
+ if(inpr<t) return;
+ else {
+ t= inpr-t;
+ i= 1.0;
+ if(t<lar->spotbl && lar->spotbl!=0.0) {
+ /* soft area */
+ i= t/lar->spotbl;
+ t= i*i;
+ inpr*= (3.0*t-2.0*t*i);
+ }
+ lampdist*=inpr;
+ }
+
+ if(lar->mode & LA_OSATEX) {
+ shi->osatex= 1; /* signal for multitex() */
+
+ shi->dxlv[0]= lv[0] - (shi->co[0]-lar->co[0]+shi->dxco[0])/ld;
+ shi->dxlv[1]= lv[1] - (shi->co[1]-lar->co[1]+shi->dxco[1])/ld;
+ shi->dxlv[2]= lv[2] - (shi->co[2]-lar->co[2]+shi->dxco[2])/ld;
+
+ shi->dylv[0]= lv[0] - (shi->co[0]-lar->co[0]+shi->dyco[0])/ld;
+ shi->dylv[1]= lv[1] - (shi->co[1]-lar->co[1]+shi->dyco[1])/ld;
+ shi->dylv[2]= lv[2] - (shi->co[2]-lar->co[2]+shi->dyco[2])/ld;
+ }
+
+ }
+
+ if(lar->mode & LA_TEXTURE) do_lamp_tex(lar, lv, shi, lacol);
+
+ /* dot product and reflectivity */
+ /* inp = dotproduct, is = shader result, i = lamp energy (with shadow) */
+
+ /* tangent case; calculate fake face normal, aligned with lampvector */
+ if(vlr->flag & R_TANGENT) {
+ float cross[3];
+ Crossf(cross, lv, vn);
+ Crossf(vnor, cross, vn);
+ vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2];
+ vn= vnor;
+ }
+ else if(ma->mode & MA_TANGENT_V) {
+ float cross[3];
+ Crossf(cross, lv, shi->tang);
+ Crossf(vnor, cross, shi->tang);
+ vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2];
+ vn= vnor;
+ }
+
+ inp= vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2];
+
+ /* phong threshold to prevent backfacing faces having artefacts on ray shadow (terminator problem) */
+ if((ma->mode & MA_RAYBIAS) && (lar->mode & LA_SHAD_RAY) && (vlr->flag & R_SMOOTH)) {
+ float thresh= vlr->ob->smoothresh;
+ if(inp>thresh)
+ phongcorr= (inp-thresh)/(inp*(1.0-thresh));
+ else
+ phongcorr= 0.0;
+ }
+ else if(ma->sbias!=0.0f) {
+ if(inp>ma->sbias)
+ phongcorr= (inp-ma->sbias)/(inp*(1.0-ma->sbias));
+ else
+ phongcorr= 0.0;
+ }
+ else phongcorr= 1.0;
+
+ /* diffuse shaders */
+ if(lar->mode & LA_NO_DIFF) {
+ is= 0.0; // skip shaders
+ }
+ else if(lar->type==LA_HEMI) {
+ is= 0.5*inp + 0.5;
+ }
+ else {
+
+ if(lar->type==LA_AREA) {
+ /* single sided */
+ if(lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0) {
+ inp= area_lamp_energy(shi->co, vn, lar);
+ }
+ else inp= 0.0;
+ }
+
+ /* diffuse shaders (oren nayer gets inp from area light) */
+ if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(inp, vn, lv, view, ma->roughness);
+ else if(ma->diff_shader==MA_DIFF_TOON) is= Toon_Diff(vn, lv, view, ma->param[0], ma->param[1]);
+ else if(ma->diff_shader==MA_DIFF_MINNAERT) is= Minnaert_Diff(inp, vn, view, ma->darkness);
+ else if(ma->diff_shader==MA_DIFF_FRESNEL) is= Fresnel_Diff(vn, lv, view, ma->param[0], ma->param[1]);
+ else is= inp; // Lambert
+ }
+
+ i= is*phongcorr;
+
+ if(i>0.0) {
+ i*= lampdist*shi->refl;
+ }
+ i_noshad= i;
+
+ vn= shi->vn; // bring back original vector, we use special specular shaders for tangent
+ if(ma->mode & MA_TANGENT_V)
+ vn= shi->tang;
+
+ /* init transp shadow */
+ shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 1.0;
+
+ /* shadow and spec, (lampdist==0 outside spot) */
+ if(lampdist> 0.0) {
+
+ if(i>0.0 && (R.r.mode & R_SHADOW)) {
+ if(ma->mode & MA_SHADOW) {
+ if(lar->type==LA_HEMI); // no shadow
+ else {
+ if(lar->shb) {
+ shadfac[3] = testshadowbuf(lar->shb, shi->co, shi->dxco, shi->dyco, inp);
+ }
+ else if(lar->mode & LA_SHAD_RAY) {
+ ray_shadow(shi, lar, shadfac);
+ }
+
+ /* warning, here it skips the loop */
+ if(lar->mode & LA_ONLYSHADOW) {
+
+ shadfac[3]= i*lar->energy*(1.0-shadfac[3]);
+ shr->diff[0] -= shadfac[3]*shi->r;
+ shr->diff[1] -= shadfac[3]*shi->g;
+ shr->diff[2] -= shadfac[3]*shi->b;
+ return;
+ }
+
+ if(passrender==0)
+ if(shadfac[3]==0.0) return;
+
+ i*= shadfac[3];
+ }
+ }
+ }
+
+ /* in case 'no diffuse' we still do most calculus, spec can be in shadow */
+ if(i>0.0 && !(lar->mode & LA_NO_DIFF)) {
+ if(ma->mode & MA_SHADOW_TRA)
+ add_to_diffuse(shr->diff, shi, is, i*shadfac[0]*lacol[0], i*shadfac[1]*lacol[1], i*shadfac[2]*lacol[2]);
+ else
+ add_to_diffuse(shr->diff, shi, is, i*lacol[0], i*lacol[1], i*lacol[2]);
+ }
+ if(passrender && i_noshad>0.0 && !(lar->mode & LA_NO_DIFF)) {
+ /* while passrender we store shadowless diffuse in shr->shad, so we can subtract */
+ if(ma->mode & MA_SHADOW_TRA)
+ add_to_diffuse(shr->shad, shi, is, i_noshad*shadfac[0]*lacol[0], i_noshad*shadfac[1]*lacol[1], i_noshad*shadfac[2]*lacol[2]);
+ else
+ add_to_diffuse(shr->shad, shi, is, i_noshad*lacol[0], i_noshad*lacol[1], i_noshad*lacol[2]);
+ }
+
+ /* specularity */
+ if(shadfac[3]>0.0 && shi->spec!=0.0 && !(lar->mode & LA_NO_SPEC)) {
+
+ if(lar->type==LA_HEMI) {
+ float t;
+ /* hemi uses no spec shaders (yet) */
+
+ lv[0]+= view[0];
+ lv[1]+= view[1];
+ lv[2]+= view[2];
+
+ Normalise(lv);
+
+ t= vn[0]*lv[0]+vn[1]*lv[1]+vn[2]*lv[2];
+
+ if(lar->type==LA_HEMI) {
+ t= 0.5*t+0.5;
+ }
+
+ t= shadfac[3]*shi->spec*spec(t, shi->har);
+
+ shr->spec[0]+= t*(lacol[0] * shi->specr);
+ shr->spec[1]+= t*(lacol[1] * shi->specg);
+ shr->spec[2]+= t*(lacol[2] * shi->specb);
+ }
+ else {
+ /* specular shaders */
+ float specfac, t;
+
+ if(ma->spec_shader==MA_SPEC_PHONG)
+ specfac= Phong_Spec(vn, lv, view, shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
+ else if(ma->spec_shader==MA_SPEC_COOKTORR)
+ specfac= CookTorr_Spec(vn, lv, view, shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
+ else if(ma->spec_shader==MA_SPEC_BLINN)
+ specfac= Blinn_Spec(vn, lv, view, ma->refrac, (float)shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
+ else if(ma->spec_shader==MA_SPEC_WARDISO)
+ specfac= WardIso_Spec( vn, lv, view, ma->rms, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
+ else
+ specfac= Toon_Spec(vn, lv, view, ma->param[2], ma->param[3], (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
+
+ /* area lamp correction */
+ if(lar->type==LA_AREA) specfac*= inp;
+
+ t= shadfac[3]*shi->spec*lampdist*specfac;
+
+ if(ma->mode & MA_RAMP_SPEC) {
+ float spec[3];
+ do_specular_ramp(shi, specfac, t, spec);
+ shr->spec[0]+= t*(lacol[0] * spec[0]);
+ shr->spec[1]+= t*(lacol[1] * spec[1]);
+ shr->spec[2]+= t*(lacol[2] * spec[2]);
+ }
+ else {
+ shr->spec[0]+= t*(lacol[0] * shi->specr);
+ shr->spec[1]+= t*(lacol[1] * shi->specg);
+ shr->spec[2]+= t*(lacol[2] * shi->specb);
+ }
+ }
+ }
+ }
+
+}
+
+
+static void shade_lamp_loop_pass(ShadeInput *shi, ShadeResult *shr, int passflag)
+{
+ Material *ma= shi->mat;
+ VlakRen *vlr= shi->vlr;
+
+ memset(shr, 0, sizeof(ShadeResult));
+
+ /* envmap hack, always reset */
+ shi->refcol[0]= shi->refcol[1]= shi->refcol[2]= shi->refcol[3]= 0.0f;
+
+ /* material color itself */
+ if(passflag & (SCE_PASS_COMBINED|SCE_PASS_RGBA)) {
+ if(ma->mode & (MA_VERTEXCOLP|MA_FACETEXTURE)) {
+ shi->r= shi->vcol[0];
+ shi->g= shi->vcol[1];
+ shi->b= shi->vcol[2];
+ }
+ if(ma->texco)
+ do_material_tex(shi);
+
+ shr->col[0]= shi->r;
+ shr->col[1]= shi->g;
+ shr->col[2]= shi->b;
+ }
+
+ if(ma->mode & MA_SHLESS) {
+ shr->diff[0]= shi->r;
+ shr->diff[1]= shi->g;
+ shr->diff[2]= shi->b;
+ shr->alpha= shi->alpha;
+ return;
+ }
+
+ if( (ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEXCOL ) { // vertexcolor light
+ shr->diff[0]= shi->r*(shi->emit+shi->vcol[0]);
+ shr->diff[1]= shi->g*(shi->emit+shi->vcol[1]);
+ shr->diff[2]= shi->b*(shi->emit+shi->vcol[2]);
+ }
+ else {
+ shr->diff[0]= shi->r*shi->emit;
+ shr->diff[1]= shi->g*shi->emit;
+ shr->diff[2]= shi->b*shi->emit;
+ }
+
+ /* AO pass */
+ if(passflag & (SCE_PASS_COMBINED|SCE_PASS_AO)) {
+ ambient_occlusion(shi, shr);
+ }
+
+ /* lighting pass */
+ if(passflag & (SCE_PASS_COMBINED|SCE_PASS_DIFFUSE|SCE_PASS_SPEC|SCE_PASS_SHADOW)) {
+ GroupObject *go;
+ ListBase *lights;
+ LampRen *lar;
+ float diff[3];
+
+ /* lights */
+ if(ma->group)
+ lights= &ma->group->gobject;
+ else
+ lights= &R.lights;
+
+ for(go=lights->first; go; go= go->next) {
+ lar= go->lampren;
+ if(lar==NULL) continue;
+
+ /* yafray: ignore shading by photonlights, not used in Blender */
+ if (lar->type==LA_YF_PHOTON) continue;
+
+ /* test for lamp layer */
+ if(lar->mode & LA_LAYER) if((lar->lay & vlr->lay)==0) continue;
+
+ /* accumulates in shr->diff and shr->spec and shr->shad */
+ shade_one_light(lar, shi, shr, passflag);
+ }
+
+ /* calculate shadow */
+ VECCOPY(diff, shr->shad);
+ VECSUB(shr->shad, shr->shad, shr->diff);
+ VECCOPY(shr->diff, diff);
+ }
+
+ /* alpha in end, spec can influence it */
+ if(passflag & (SCE_PASS_COMBINED|SCE_PASS_RGBA)) {
+ if(ma->mode & (MA_ZTRA|MA_RAYTRANSP)) {
+ if(ma->fresnel_tra!=0.0)
+ shi->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra);
+
+ if(shi->spectra!=0.0) {
+ float t = MAX3(shr->spec[0], shr->spec[1], shr->spec[2]);
+ t *= shi->spectra;
+ if(t>1.0) t= 1.0;
+ shi->alpha= (1.0-t)*shi->alpha+t;
+ }
+ }
+ shr->col[3]= shi->alpha;
+ }
+ shr->alpha= shi->alpha;
+
+ shr->diff[0]+= shi->ambr + shi->r*shi->amb*shi->rad[0];
+ shr->diff[1]+= shi->ambg + shi->g*shi->amb*shi->rad[1];
+ shr->diff[2]+= shi->ambb + shi->b*shi->amb*shi->rad[2];
+
+ if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(shr->diff, shi);
+ if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(shr->spec, shr->spec+1, shr->spec+2, shi);
+
+ /* refcol is for envmap only */
+ if(shi->refcol[0]!=0.0) {
+ shr->diff[0]= shi->mirr*shi->refcol[1] + (1.0 - shi->mirr*shi->refcol[0])*shr->diff[0];
+ shr->diff[1]= shi->mirg*shi->refcol[2] + (1.0 - shi->mirg*shi->refcol[0])*shr->diff[1];
+ shr->diff[2]= shi->mirb*shi->refcol[3] + (1.0 - shi->mirb*shi->refcol[0])*shr->diff[2];
+ }
+
+ if(passflag & SCE_PASS_COMBINED) {
+ shr->combined[0]= shr->diff[0]+(shr->ao[0])*shr->col[0] + shr->spec[0];
+ shr->combined[1]= shr->diff[1]+(shr->ao[1])*shr->col[1] + shr->spec[1];
+ shr->combined[2]= shr->diff[2]+(shr->ao[2])*shr->col[2] + shr->spec[2];
+ shr->combined[3]= shr->alpha;
+ }
+
+ if(R.r.mode & R_RAYTRACE) {
+
+ if((ma->mode & MA_RAYMIRROR)==0) shi->ray_mirror= 0.0;
+
+ if(shi->ray_mirror!=0.0 || ((shi->mat->mode & MA_RAYTRANSP) && shr->alpha!=1.0)) {
+ float diff[3];
+
+ VECCOPY(diff, shr->diff);
+
+ ray_trace(shi, shr);
+
+ VECSUB(shr->ray, shr->diff, diff);
+ VECCOPY(shr->diff, diff);
+ VECADD(shr->combined, shr->combined, shr->ray);
+ }
+ }
+ else {
+ /* doesnt look 'correct', but is better for preview, plus envmaps dont raytrace this */
+ if(shi->mat->mode & MA_RAYTRANSP) shr->alpha= 1.0;
+ }
+
+}
+
void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
{
LampRen *lar;
@@ -1184,11 +1630,6 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
Material *ma= shi->mat;
VlakRen *vlr= shi->vlr;
ListBase *lights;
- float i, inp, inpr, is, t, lv[3], vnor[3], lacol[3], lampdist, ld = 0;
- float lvrot[3], *vn, *view, shadfac[4], soft, phongcorr; // shadfac = rgba
-
- vn= shi->vn;
- view= shi->view;
memset(shr, 0, sizeof(ShadeResult));
@@ -1202,7 +1643,12 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
/* separate loop */
if(ma->mode & MA_ONLYSHADOW) {
- float ir;
+ float i, inp, inpr, lv[3];
+ float *vn, *view, shadfac[4];
+ float t, ir;
+
+ vn= shi->vn;
+ view= shi->view;
if(R.r.mode & R_SHADOW) {
@@ -1322,20 +1768,21 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
}
if( (ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEXCOL ) { // vertexcolor light
- // add_to_diffuse(shr->diff, shi, 1.0, ma->emit+shi->vcol[0], ma->emit+shi->vcol[1], ma->emit+shi->vcol[2]);
shr->diff[0]= shi->r*(shi->emit+shi->vcol[0]);
shr->diff[1]= shi->g*(shi->emit+shi->vcol[1]);
shr->diff[2]= shi->b*(shi->emit+shi->vcol[2]);
}
else {
- // add_to_diffuse(shr->diff, shi, 1.0, ma->emit, ma->emit, ma->emit);
shr->diff[0]= shi->r*shi->emit;
shr->diff[1]= shi->g*shi->emit;
shr->diff[2]= shi->b*shi->emit;
}
- ambient_occlusion(shi, shr);
-
+ if(R.wrld.mode & WO_AMB_OCC) {
+ ambient_occlusion(shi, shr);
+ VECADD(shr->diff, shr->diff, shr->ao);
+ }
+
for(go=lights->first; go; go= go->next) {
lar= go->lampren;
if(lar==NULL) continue;
@@ -1346,297 +1793,8 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
/* test for lamp layer */
if(lar->mode & LA_LAYER) if((lar->lay & vlr->lay)==0) continue;
- /* lampdist calculation */
- if(lar->type==LA_SUN || lar->type==LA_HEMI) {
- VECCOPY(lv, lar->vec);
- lampdist= 1.0;
- }
- else {
- lv[0]= shi->co[0]-lar->co[0];
- lv[1]= shi->co[1]-lar->co[1];
- lv[2]= shi->co[2]-lar->co[2];
- ld= sqrt(lv[0]*lv[0]+lv[1]*lv[1]+lv[2]*lv[2]);
- lv[0]/= ld;
- lv[1]/= ld;
- lv[2]/= ld;
-
- /* ld is re-used further on (texco's) */
- if(lar->type==LA_AREA) {
- lampdist= 1.0;
- }
- else {
- if(lar->mode & LA_QUAD) {
- t= 1.0;
- if(lar->ld1>0.0)
- t= lar->dist/(lar->dist+lar->ld1*ld);
- if(lar->ld2>0.0)
- t*= lar->distkw/(lar->distkw+lar->ld2*ld*ld);
-
- lampdist= t;
- }
- else {
- lampdist= (lar->dist/(lar->dist+ld));
- }
-
- if(lar->mode & LA_SPHERE) {
- t= lar->dist - ld;
- if(t<0.0) continue;
-
- t/= lar->dist;
- lampdist*= (t);
- }
- }
- }
-
- lacol[0]= lar->r;
- lacol[1]= lar->g;
- lacol[2]= lar->b;
-
- /* init transp shadow */
- shadfac[3]= 1.0;
- if(ma->mode & MA_SHADOW_TRA) shadfac[0]= shadfac[1]= shadfac[2]= 1.0;
-
- if(lar->type==LA_SPOT) {
-
- if(lar->mode & LA_SQUARE) {
- if(lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0) {
- float x;
-
- /* rotate view to lampspace */
- VECCOPY(lvrot, lv);
- MTC_Mat3MulVecfl(lar->imat, lvrot);
-
- x= MAX2(fabs(lvrot[0]/lvrot[2]) , fabs(lvrot[1]/lvrot[2]));
- /* 1.0/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */
-
- inpr= 1.0f/(sqrt(1.0f+x*x));
- }
- else inpr= 0.0;
- }
- else {
- inpr= lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2];
- }
-
- t= lar->spotsi;
- if(inpr<t) continue;
- else {
- t= inpr-t;
- i= 1.0;
- soft= 1.0;
- if(t<lar->spotbl && lar->spotbl!=0.0) {
- /* soft area */
- i= t/lar->spotbl;
- t= i*i;
- soft= (3.0*t-2.0*t*i);
- inpr*= soft;
- }
- lampdist*=inpr;
- }
-
- if(lar->mode & LA_OSATEX) {
- shi->osatex= 1; /* signal for multitex() */
-
- shi->dxlv[0]= lv[0] - (shi->co[0]-lar->co[0]+shi->dxco[0])/ld;
- shi->dxlv[1]= lv[1] - (shi->co[1]-lar->co[1]+shi->dxco[1])/ld;
- shi->dxlv[2]= lv[2] - (shi->co[2]-lar->co[2]+shi->dxco[2])/ld;
-
- shi->dylv[0]= lv[0] - (shi->co[0]-lar->co[0]+shi->dyco[0])/ld;
- shi->dylv[1]= lv[1] - (shi->co[1]-lar->co[1]+shi->dyco[1])/ld;
- shi->dylv[2]= lv[2] - (shi->co[2]-lar->co[2]+shi->dyco[2])/ld;
- }
-
- }
-
- if(lar->mode & LA_TEXTURE) do_lamp_tex(lar, lv, shi, lacol);
-
- /* dot product and reflectivity */
- /* inp = dotproduct, is = shader result, i = lamp energy (with shadow) */
-
- /* tangent case; calculate fake face normal, aligned with lampvector */
- if(vlr->flag & R_TANGENT) {
- float cross[3];
- Crossf(cross, lv, vn);
- Crossf(vnor, cross, vn);
- vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2];
- vn= vnor;
- }
- else if(ma->mode & MA_TANGENT_V) {
- float cross[3];
- Crossf(cross, lv, shi->tang);
- Crossf(vnor, cross, shi->tang);
- vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2];
- vn= vnor;
- }
-
- inp= vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2];
-
- /* phong threshold to prevent backfacing faces having artefacts on ray shadow (terminator problem) */
- if((ma->mode & MA_RAYBIAS) && (lar->mode & LA_SHAD_RAY) && (vlr->flag & R_SMOOTH)) {
- float thresh= vlr->ob->smoothresh;
- if(inp>thresh)
- phongcorr= (inp-thresh)/(inp*(1.0-thresh));
- else
- phongcorr= 0.0;
- }
- else if(ma->sbias!=0.0f) {
- if(inp>ma->sbias)
- phongcorr= (inp-ma->sbias)/(inp*(1.0-ma->sbias));
- else
- phongcorr= 0.0;
- }
- else phongcorr= 1.0;
-
- /* diffuse shaders */
- if(lar->mode & LA_NO_DIFF) {
- is= 0.0; // skip shaders
- }
- else if(lar->type==LA_HEMI) {
- is= 0.5*inp + 0.5;
- }
- else {
-
- if(lar->type==LA_AREA) {
- /* single sided */
- if(lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0) {
- inp= area_lamp_energy(shi->co, vn, lar);
- }
- else inp= 0.0;
- }
-
- /* diffuse shaders (oren nayer gets inp from area light) */
- if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(inp, vn, lv, view, ma->roughness);
- else if(ma->diff_shader==MA_DIFF_TOON) is= Toon_Diff(vn, lv, view, ma->param[0], ma->param[1]);
- else if(ma->diff_shader==MA_DIFF_MINNAERT) is= Minnaert_Diff(inp, vn, view, ma->darkness);
- else if(ma->diff_shader==MA_DIFF_FRESNEL) is= Fresnel_Diff(vn, lv, view, ma->param[0], ma->param[1]);
- else is= inp; // Lambert
- }
-
- i= is*phongcorr;
-
- if(i>0.0) {
- i*= lampdist*shi->refl;
- }
-
- vn= shi->vn; // bring back original vector, we use special specular shaders for tangent
- if(ma->mode & MA_TANGENT_V)
- vn= shi->tang;
-
- /* shadow and spec, (lampdist==0 outside spot) */
- if(lampdist> 0.0) {
-
- if(i>0.0 && (R.r.mode & R_SHADOW)) {
- if(ma->mode & MA_SHADOW) {
- if(lar->type==LA_HEMI); // no shadow
- else {
- if(lar->shb) {
- shadfac[3] = testshadowbuf(lar->shb, shi->co, shi->dxco, shi->dyco, inp);
- }
- else if(lar->mode & LA_SHAD_RAY) {
- ray_shadow(shi, lar, shadfac);
- }
-
- /* warning, here it skips the loop */
- if(lar->mode & LA_ONLYSHADOW) {
-
- shadfac[3]= i*lar->energy*(1.0-shadfac[3]);
- shr->diff[0] -= shadfac[3]*shi->r;
- shr->diff[1] -= shadfac[3]*shi->g;
- shr->diff[2] -= shadfac[3]*shi->b;
-
- continue;
- }
-
- if(shadfac[3]==0.0) continue;
-
- i*= shadfac[3];
- }
- }
- }
-#if 0
- if(R.r.mode & R_RAYTRACE) {
- extern void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float *co);
- float co[3], distfac;
-
- ray_translucent(shi, lar, &distfac, co);
-
- if(distfac<0.01f*G.rt) {
- // printf("distfac %f\n", distfac);
- distfac= 1.0f - distfac/(0.01f*G.rt);
- shr->diff[0]+= distfac;
- shr->diff[1]+= distfac;
- shr->diff[2]+= distfac;
- }
- }
-#endif
-
- /* specularity */
- if(shadfac[3]>0.0 && shi->spec!=0.0 && !(lar->mode & LA_NO_SPEC)) {
-
- if(lar->type==LA_HEMI) {
- /* hemi uses no spec shaders (yet) */
-
- lv[0]+= view[0];
- lv[1]+= view[1];
- lv[2]+= view[2];
-
- Normalise(lv);
-
- t= vn[0]*lv[0]+vn[1]*lv[1]+vn[2]*lv[2];
-
- if(lar->type==LA_HEMI) {
- t= 0.5*t+0.5;
- }
-
- t= shadfac[3]*shi->spec*spec(t, shi->har);
- shr->spec[0]+= t*(lacol[0] * shi->specr);
- shr->spec[1]+= t*(lacol[1] * shi->specg);
- shr->spec[2]+= t*(lacol[2] * shi->specb);
- }
- else {
- /* specular shaders */
- float specfac;
-
- if(ma->spec_shader==MA_SPEC_PHONG)
- specfac= Phong_Spec(vn, lv, view, shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
- else if(ma->spec_shader==MA_SPEC_COOKTORR)
- specfac= CookTorr_Spec(vn, lv, view, shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
- else if(ma->spec_shader==MA_SPEC_BLINN)
- specfac= Blinn_Spec(vn, lv, view, ma->refrac, (float)shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
- else if(ma->spec_shader==MA_SPEC_WARDISO)
- specfac= WardIso_Spec( vn, lv, view, ma->rms, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
- else
- specfac= Toon_Spec(vn, lv, view, ma->param[2], ma->param[3], (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
-
- /* area lamp correction */
- if(lar->type==LA_AREA) specfac*= inp;
-
- t= shadfac[3]*shi->spec*lampdist*specfac;
-
- if(ma->mode & MA_RAMP_SPEC) {
- float spec[3];
- do_specular_ramp(shi, specfac, t, spec);
- shr->spec[0]+= t*(lacol[0] * spec[0]);
- shr->spec[1]+= t*(lacol[1] * spec[1]);
- shr->spec[2]+= t*(lacol[2] * spec[2]);
- }
- else {
- shr->spec[0]+= t*(lacol[0] * shi->specr);
- shr->spec[1]+= t*(lacol[1] * shi->specg);
- shr->spec[2]+= t*(lacol[2] * shi->specb);
- }
- }
- }
- }
-
- /* in case 'no diffuse' we still do most calculus, spec can be in shadow */
- if(i>0.0 && !(lar->mode & LA_NO_DIFF)) {
- if(ma->mode & MA_SHADOW_TRA) {
- add_to_diffuse(shr->diff, shi, is, i*shadfac[0]*lacol[0], i*shadfac[1]*lacol[1], i*shadfac[2]*lacol[2]);
- }
- else {
- add_to_diffuse(shr->diff, shi, is, i*lacol[0], i*lacol[1], i*lacol[2]);
- }
- }
+ /* accumulates in shr->diff and shr->spec, 0= no passrender */
+ shade_one_light(lar, shi, shr, 0);
}
if(ma->mode & (MA_ZTRA|MA_RAYTRANSP)) {
@@ -1644,8 +1802,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
shi->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra);
if(shi->spectra!=0.0) {
-
- t = MAX3(shr->spec[0], shr->spec[1], shr->spec[2]);
+ float t = MAX3(shr->spec[0], shr->spec[1], shr->spec[2]);
t *= shi->spectra;
if(t>1.0) t= 1.0;
shi->alpha= (1.0-t)*shi->alpha+t;
@@ -2125,7 +2282,7 @@ void shade_material_loop(ShadeInput *shi, ShadeResult *shr)
/* note, facenr declared volatile due to over-eager -O2 optimizations
* on cygwin (particularly -frerun-cse-after-loop)
*/
-void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, int mask, ShadeResult *shr, float *rco)
+void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, int mask, ShadeResult *shr, float *rco, int passflag)
{
ShadeInput shi;
VlakRen *vlr=NULL;
@@ -2347,7 +2504,10 @@ void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, i
memcpy(&shi.r, &shi.mat->r, 23*sizeof(float));
shi.har= shi.mat->har;
- shade_material_loop(&shi, shr);
+// if(passflag)
+// shade_lamp_loop_pass(&shi, shr, passflag);
+// else
+ shade_material_loop(&shi, shr);
}
/* after shading and composit layers */
@@ -2359,7 +2519,9 @@ void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, i
if(shr->diff[1]<0.0f) shr->diff[1]= 0.0f;
if(shr->diff[2]<0.0f) shr->diff[2]= 0.0f;
- VECADD(shr->combined, shr->diff, shr->spec);
+// if(passflag==0) {
+ VECADD(shr->combined, shr->diff, shr->spec);
+// }
/* additional passes */
shr->winspeed[0]= shi.winspeed[0]; shr->winspeed[1]= shi.winspeed[1];
@@ -2423,12 +2585,12 @@ void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, i
return vlr;
}
-static void shadepixel_sky(RenderPart *pa, float x, float y, int z, int facenr, int mask, ShadeResult *shr)
+static void shadepixel_sky(RenderPart *pa, float x, float y, int z, int facenr, int mask, ShadeResult *shr, int passflag)
{
VlakRen *vlr;
float collector[4], rco[3];
- vlr= shadepixel(pa, x, y, z, facenr, mask, shr, rco);
+ vlr= shadepixel(pa, x, y, z, facenr, mask, shr, rco, passflag);
if(shr->combined[3] != 1.0) {
/* bail out when raytrace transparency (sky included already) */
@@ -2515,6 +2677,96 @@ static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
/* ********************* MAINLOOPS ******************** */
+/* osa version */
+static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, ShadeResult *shr)
+{
+ RenderPass *rpass;
+
+ for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
+ float *fp, *col= NULL;
+ int pixsize= 3;
+
+ switch(rpass->passtype) {
+ case SCE_PASS_RGBA:
+ col= shr->col;
+ pixsize= 4;
+ break;
+ case SCE_PASS_DIFFUSE:
+ col= shr->diff;
+ break;
+ case SCE_PASS_SPEC:
+ col= shr->spec;
+ break;
+ case SCE_PASS_SHADOW:
+ col= shr->shad;
+ break;
+ case SCE_PASS_AO:
+ col= shr->ao;
+ break;
+ case SCE_PASS_RAY:
+ col= shr->ray;
+ break;
+ case SCE_PASS_NORMAL:
+ col= shr->nor;
+ break;
+ case SCE_PASS_VECTOR:
+ col= shr->winspeed;
+ pixsize= 2;
+ break;
+ }
+ if(col) {
+ fp= rpass->rect + pixsize*offset;
+ add_filt_fmask_pixsize(curmask, col, fp, rectx, pixsize);
+ }
+ }
+}
+
+/* non-osa version */
+static void add_passes(RenderLayer *rl, int offset, ShadeResult *shr)
+{
+ RenderPass *rpass;
+
+ for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
+ float *fp, *col= NULL;
+ int a, pixsize= 3;
+
+ switch(rpass->passtype) {
+ case SCE_PASS_RGBA:
+ col= shr->col;
+ pixsize= 4;
+ break;
+ case SCE_PASS_DIFFUSE:
+ col= shr->diff;
+ break;
+ case SCE_PASS_SPEC:
+ col= shr->spec;
+ break;
+ case SCE_PASS_SHADOW:
+ col= shr->shad;
+ break;
+ case SCE_PASS_AO:
+ col= shr->ao;
+ break;
+ case SCE_PASS_RAY:
+ col= shr->ray;
+ break;
+ case SCE_PASS_NORMAL:
+ col= shr->nor;
+ break;
+ case SCE_PASS_VECTOR:
+ col= shr->winspeed;
+ pixsize= 2;
+ break;
+ }
+ if(col) {
+ fp= rpass->rect + pixsize*offset;
+ for(a=0; a<pixsize; a++)
+ fp[a]= col[a];
+ }
+ }
+}
+
+
static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
{
RenderResult *rr= pa->result;
@@ -2524,7 +2776,7 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
float *fcol= shr.combined, *rf, *rectf= rl->rectf;
long *rd, *rectdaps= pa->rectdaps;
int zbuf, samp, curmask, face, mask, fullmask;
- int b, x, y, full_osa, seed, crop=0, offs=0, od;
+ int b, x, y, full_osa, seed, crop=0, offs=0, od, renderpassflag, addpassflag;
if(R.test_break()) return;
@@ -2533,6 +2785,13 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
fullmask= (1<<R.osa)-1;
+ /* bit clumsy, but with passes we need different shade code */
+ if(rl->passflag & ~(SCE_PASS_Z|SCE_PASS_NORMAL|SCE_PASS_VECTOR|SCE_PASS_COMBINED))
+ renderpassflag= rl->passflag;
+ else
+ renderpassflag= 0;
+ addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
+
/* filtered render, for now we assume only 1 filter size */
if(pa->crop) {
crop= 1;
@@ -2582,7 +2841,7 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
if(curmask & (1<<samp)) {
xs= (float)x + R.jit[samp][0];
ys= (float)y + R.jit[samp][1];
- shadepixel_sky(pa, xs, ys, zbuf, face, (1<<samp), &shr);
+ shadepixel_sky(pa, xs, ys, zbuf, face, (1<<samp), &shr, renderpassflag);
if(R.do_gamma) {
fcol[0]= gammaCorrect(fcol[0]);
@@ -2590,6 +2849,9 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
fcol[2]= gammaCorrect(fcol[2]);
}
add_filt_fmask(1<<samp, fcol, rf, pa->rectx);
+
+ if(addpassflag)
+ add_filt_passes(rl, curmask, pa->rectx, od, &shr);
}
}
}
@@ -2597,7 +2859,7 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
b= R.samples->centmask[curmask];
xs= (float)x+R.samples->centLut[b & 15];
ys= (float)y+R.samples->centLut[b>>4];
- shadepixel_sky(pa, xs, ys, zbuf, face, curmask, &shr);
+ shadepixel_sky(pa, xs, ys, zbuf, face, curmask, &shr, renderpassflag);
if(R.do_gamma) {
fcol[0]= gammaCorrect(fcol[0]);
@@ -2605,6 +2867,9 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
fcol[2]= gammaCorrect(fcol[2]);
}
add_filt_fmask(curmask, fcol, rf, pa->rectx);
+
+ if(addpassflag)
+ add_filt_passes(rl, curmask, pa->rectx, od, &shr);
}
mask |= curmask;
@@ -2612,13 +2877,6 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
if(ps==NULL) break;
else ps= ps->next;
}
-
- /* passes */
- if(rl->passflag & SCE_PASS_VECTOR) {
- float *fp= rl->rectvec+2*od;
- fp[0]= shr.winspeed[0];
- fp[1]= shr.winspeed[1];
- }
}
rectf+= 4*pa->rectx;
@@ -2812,10 +3070,10 @@ void zbufshadeDA_tile(RenderPart *pa)
/* supposed to be fully threadable! */
void zbufshade_tile(RenderPart *pa)
{
- ShadeResult shr;
+ ShadeResult *shr= RE_mallocN(sizeof(ShadeResult), "shaderesult");
RenderResult *rr= pa->result;
RenderLayer *rl;
-
+
set_part_zbuf_clipflag(pa);
/* zbuffer code clears/inits rects */
@@ -2831,22 +3089,26 @@ void zbufshade_tile(RenderPart *pa)
if(!R.test_break()) {
if(rl->layflag & SCE_LAY_SOLID) {
float *fcol= rl->rectf;
- int x, y, *rp= pa->rectp, *rz= pa->rectz, offs=0;
+ int x, y, *rp= pa->rectp, *rz= pa->rectz, offs=0, renderpassflag, addpassflag;
+
+ /* bit clumsy, but with passes we shade differently */
+ if(rl->passflag & ~(SCE_PASS_Z|SCE_PASS_NORMAL|SCE_PASS_VECTOR|SCE_PASS_COMBINED))
+ renderpassflag= rl->passflag;
+ else
+ renderpassflag= 0;
+ addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
/* init scanline updates */
rr->renrect.ymin=rr->renrect.ymax= 0;
for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, rp++, fcol+=4, offs++) {
- shadepixel_sky(pa, (float)x, (float)y, *rz, *rp, 0, &shr);
- QUATCOPY(fcol, shr.combined);
+ shadepixel_sky(pa, (float)x, (float)y, *rz, *rp, 0, shr, renderpassflag);
+ QUATCOPY(fcol, shr->combined);
/* passes */
- if(*rp && (rl->passflag & SCE_PASS_VECTOR)) {
- float *fp= rl->rectvec+2*(offs);
- fp[0]= shr.winspeed[0];
- fp[1]= shr.winspeed[1];
- }
+ if(*rp && addpassflag)
+ add_passes(rl, offs, shr);
}
if(y&1)
if(R.test_break()) break;
@@ -2891,7 +3153,7 @@ void zbufshade_tile(RenderPart *pa)
convert_zbuf_to_distbuf(pa, rl);
}
-
+ RE_freeN(shr);
RE_freeN(pa->rectp); pa->rectp= NULL;
RE_freeN(pa->rectz); pa->rectz= NULL;
}
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 4830db352d7..eb1385cab95 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -2049,7 +2049,7 @@ static void shadetrapixel(RenderPart *pa, float x, float y, int z, int facenr, i
if(vlr->flag & R_FULL_OSA) {
for(a=0; a<R.osa; a++) {
if(mask & (1<<a)) {
- shadepixel(pa, x+R.jit[a][0], y+R.jit[a][1], z, facenr, 1<<a, &shr, rco);
+ shadepixel(pa, x+R.jit[a][0], y+R.jit[a][1], z, facenr, 1<<a, &shr, rco, 0);
accumcol[0]+= shr.combined[0];
accumcol[1]+= shr.combined[1];
accumcol[2]+= shr.combined[2];
@@ -2067,12 +2067,12 @@ static void shadetrapixel(RenderPart *pa, float x, float y, int z, int facenr, i
int b= R.samples->centmask[mask];
x= x+R.samples->centLut[b & 15];
y= y+R.samples->centLut[b>>4];
- shadepixel(pa, x, y, z, facenr, mask, &shr, rco);
+ shadepixel(pa, x, y, z, facenr, mask, &shr, rco, 0);
QUATCOPY(fcol, shr.combined);
}
}
else {
- shadepixel(pa, x, y, z, facenr, mask, &shr, rco);
+ shadepixel(pa, x, y, z, facenr, mask, &shr, rco, 0);
QUATCOPY(fcol, shr.combined);
}
}
@@ -2238,15 +2238,21 @@ void zbuffer_transp_shade(RenderPart *pa, float *pass, unsigned int lay, short l
/* uses part zbuffer values to convert into distances from camera in renderlayer */
void convert_zbuf_to_distbuf(RenderPart *pa, RenderLayer *rl)
{
+ RenderPass *rpass;
float *rectzf, zco;
int a, *rectz, ortho= R.r.mode & R_ORTHO;
if(pa->rectz==NULL) return;
- if(rl->rectz==NULL) {
+ for(rpass= rl->passes.first; rpass; rpass= rpass->next)
+ if(rpass->passtype==SCE_PASS_Z)
+ break;
+
+ if(rpass==NULL) {
printf("called convert zbuf wrong...\n");
return;
}
- rectzf= rl->rectz;
+
+ rectzf= rpass->rect;
rectz= pa->rectz;
for(a=pa->rectx*pa->recty; a>0; a--, rectz++, rectzf++) {