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-12-08 12:40:44 +0300
committerTon Roosendaal <ton@blender.org>2006-12-08 12:40:44 +0300
commit902a69a7d3fad91d84bc109a6e6e5fd039a79e4b (patch)
tree113e76f7b85c50a428142086ac82e86eb9e2d9fb /source/blender/render/intern
parent3da771fefcde9efc3797bb08cd3d90d09dbe1f81 (diff)
Numerous fixes in Render code:
- Bug: material emit was ignored (showed in preview render backdrop) - Bug: world exposure was ignored - Bug: lamp halo was ignoring 'render layer light override'. Further reshuffled the way shadows are being pre-calculated, this to enable more advanced (and faster) usage of Material lightgroups. Now shadows are being cached in lamps, using a per-sample counter to check if a recalc is needed. Will also work (later) for Raytracing node shaders. - New: Material LightGroup option "Always", which always shades the lights in the group, independent of visibility layer. (so it allows to move such lights to hidden layer, not influencing anything).
Diffstat (limited to 'source/blender/render/intern')
-rw-r--r--source/blender/render/intern/include/render_types.h10
-rw-r--r--source/blender/render/intern/include/shading.h9
-rw-r--r--source/blender/render/intern/source/convertblender.c52
-rw-r--r--source/blender/render/intern/source/rendercore.c16
-rw-r--r--source/blender/render/intern/source/shadeinput.c67
-rw-r--r--source/blender/render/intern/source/shadeoutput.c14
-rw-r--r--source/blender/render/intern/source/zbuf.c10
7 files changed, 86 insertions, 92 deletions
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 77beb446c86..247f10bf7a0 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -290,8 +290,13 @@ struct MTex;
* properties of a lightsource.
*/
+typedef struct LampShadowSubSample {
+ int samplenr;
+ float shadfac[4]; /* rgba shadow */
+} LampShadowSubSample;
+
typedef struct LampShadowSample {
- float shadfac[16][4]; /* 16 = RE_MAX_OSA, 4 = rgba */
+ LampShadowSubSample s[16]; /* MAX OSA */
} LampShadowSample;
typedef struct LampRen {
@@ -344,8 +349,7 @@ typedef struct LampRen {
float area[8][3], areasize;
/* passes & node shader support: all shadow info for a pixel */
- /* struct is currently 2k long... check on alloc? */
- LampShadowSample shadsamp[BLENDER_MAX_THREADS];
+ LampShadowSample *shadsamp;
/* yafray: photonlight params */
int YF_numphotons, YF_numsearch;
diff --git a/source/blender/render/intern/include/shading.h b/source/blender/render/intern/include/shading.h
index 38ed0f73e70..6c8f20673ed 100644
--- a/source/blender/render/intern/include/shading.h
+++ b/source/blender/render/intern/include/shading.h
@@ -28,6 +28,7 @@ struct ShadeResult;
struct RenderPart;
struct RenderLayer;
struct PixStr;
+struct LampRen;
/* shadeinput.c */
@@ -35,8 +36,12 @@ struct PixStr;
/* needed to calculate shadow and AO for an entire pixel */
typedef struct ShadeSample {
int tot; /* amount of shi in use, can be 1 for not FULL_OSA */
+
+ /* could be malloced once */
ShadeInput shi[16]; /* RE_MAX_OSA */
ShadeResult shr[16]; /* RE_MAX_OSA */
+
+ int samplenr; /* counter, detect shadow-reuse for shaders */
} ShadeSample;
@@ -52,8 +57,10 @@ void shade_input_set_normals(struct ShadeInput *shi);
void shade_input_set_shade_texco(struct ShadeInput *shi);
void shade_input_do_shade(struct ShadeInput *shi, struct ShadeResult *shr);
+void shade_input_initialize(struct ShadeInput *shi, struct RenderPart *pa, struct RenderLayer *rl, int sample);
+
void shade_sample_initialize(struct ShadeSample *ssamp, struct RenderPart *pa, struct RenderLayer *rl);
-void shade_samples_do_shadow(struct ShadeSample *ssamp);
+void shade_samples_do_AO(struct ShadeSample *ssamp);
int shade_samples(struct ShadeSample *ssamp, struct PixStr *ps, int x, int y);
void vlr_set_uv_indices(struct VlakRen *vlr, int *i1, int *i2, int *i3);
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 0fba6916c36..c71bbaef7c8 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -2340,9 +2340,15 @@ static LampRen *add_render_lamp(Render *re, Object *ob)
}
}
}
-
- /* yafray: shadowbuffers and jitter only needed for internal render */
+ /* yafray: shadow flag should not be cleared, only used with internal renderer */
if (re->r.renderer==R_INTERN) {
+ /* to make sure we can check ray shadow easily in the render code */
+ if(lar->mode & LA_SHAD_RAY) {
+ if( (re->r.mode & R_RAYTRACE)==0)
+ lar->mode &= ~LA_SHAD_RAY;
+ }
+
+
if(re->r.mode & R_SHADOW) {
if (la->type==LA_SPOT && (lar->mode & LA_SHAD_BUF) ) {
/* Per lamp, one shadow buffer is made. */
@@ -2353,24 +2359,25 @@ static LampRen *add_render_lamp(Render *re, Object *ob)
else if(la->type==LA_AREA && (lar->mode & LA_SHAD_RAY) ) {
init_jitter_plane(lar);
}
+
+ /* this is the way used all over to check for shadow */
+ if(lar->shb || (lar->mode & LA_SHAD_RAY)) {
+ LampShadowSubSample *lss;
+ int a, b, tot= re->r.threads*re->r.osa;
+
+ lar->shadsamp= MEM_mallocN(re->r.threads*sizeof(LampShadowSample), "lamp shadow sample");
+ lss= lar->shadsamp[0].s;
+ /* shadfacs actually mean light, let's put them to 1 to prevent unitialized accidents */
+ for(a=0; a<tot; a++, lss++) {
+ for(b=0; b<4; b++) {
+ lss->samplenr= -1; /* used to detect whether we store or read */
+ lss->shadfac[b]= 1.0f;
+ }
+ }
+ }
}
}
- /* yafray: shadow flag should not be cleared, only used with internal renderer */
- if (re->r.renderer==R_INTERN) {
- int a, b;
-
- /* to make sure we can check ray shadow easily in the render code */
- if(lar->mode & LA_SHAD_RAY) {
- if( (re->r.mode & R_RAYTRACE)==0)
- lar->mode &= ~LA_SHAD_RAY;
- }
- /* shadfacs actually mean light, let's put them to 1 to prevent unitialized accidents */
- for(c=0; c<re->r.threads; c++)
- for(a=0; a<re->r.osa; a++)
- for(b=0; b<4; b++)
- lar->shadsamp[c].shadfac[a][b]= 1.0f;
- }
return lar;
}
@@ -2928,8 +2935,10 @@ void RE_Database_Free(Render *re)
for(go= re->lights.first; go; go= go->next) {
struct LampRen *lar= go->lampren;
+
freeshadowbuf(lar);
if(lar->jitter) MEM_freeN(lar->jitter);
+ if(lar->shadsamp) MEM_freeN(lar->shadsamp);
MEM_freeN(lar);
}
@@ -3115,7 +3124,8 @@ static void check_non_flat_quads(Render *re)
}
}
-static void add_lightgroup(Render *re, Group *group)
+/* layflag: allows material group to ignore layerflag */
+static void add_lightgroup(Render *re, Group *group, int nolay)
{
GroupObject *go, *gol;
@@ -3131,6 +3141,8 @@ static void add_lightgroup(Render *re, Group *group)
}
if(go->lampren==NULL)
go->lampren= add_render_lamp(re, go->ob);
+ if(nolay)
+ ((LampRen *)go->lampren)->lay= 0xFFFFFFFF;
}
}
}
@@ -3143,7 +3155,7 @@ static void set_material_lightgroups(Render *re)
/* hola! materials not in use...? */
for(ma= G.main->mat.first; ma; ma=ma->id.next) {
if(ma->group)
- add_lightgroup(re, ma->group);
+ add_lightgroup(re, ma->group, ma->mode & MA_GROUP_NOLAY);
}
}
@@ -3153,7 +3165,7 @@ static void set_renderlayer_lightgroups(Render *re, Scene *sce)
for(srl= sce->r.layers.first; srl; srl= srl->next) {
if(srl->light_override)
- add_lightgroup(re, srl->light_override);
+ add_lightgroup(re, srl->light_override, 0);
}
}
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 20718941aad..e8e75b6f7fb 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -287,14 +287,15 @@ static void halo_tile(RenderPart *pa, float *pass, unsigned int lay)
}
}
-static void lamphalo_tile(RenderPart *pa, float *pass, unsigned int lay)
+static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
{
ShadeInput shi;
+ float *pass= rl->rectf;
float fac;
long *rd= pa->rectdaps;
int x, y, *rz= pa->rectz;
- shi.lay= lay;
+ shade_input_initialize(&shi, pa, rl, 0);
for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, pass+=4) {
@@ -321,7 +322,6 @@ static void lamphalo_tile(RenderPart *pa, float *pass, unsigned int lay)
shi.co[2]= 0.0f;
renderspothalo(&shi, pass, fac);
}
-
}
else {
if(R.r.mode & R_ORTHO)
@@ -859,7 +859,7 @@ void zbufshadeDA_tile(RenderPart *pa)
/* lamphalo after solid, before ztra, looks nicest because ztra does own halo */
if(R.flag & R_LAMPHALO)
if(rl->layflag & SCE_LAY_HALO)
- lamphalo_tile(pa, rl->rectf, rl->lay);
+ lamphalo_tile(pa, rl);
/* halo before ztra, because ztra fills in zbuffer now */
if(R.flag & R_HALO)
@@ -1028,7 +1028,7 @@ void zbufshade_tile(RenderPart *pa)
/* lamphalo after solid, before ztra, looks nicest because ztra does own halo */
if(R.flag & R_LAMPHALO)
if(rl->layflag & SCE_LAY_HALO)
- lamphalo_tile(pa, rl->rectf, rl->lay);
+ lamphalo_tile(pa, rl);
/* halo before ztra, because ztra fills in zbuffer now */
if(R.flag & R_HALO)
@@ -1353,6 +1353,9 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
/* no face normal flip */
shi->puno= 0;
+ /* cache for shadow */
+ shi->samplenr++;
+
if(bs->quad)
shade_input_set_triangle_i(shi, vlr, 0, 2, 3);
else
@@ -1377,8 +1380,7 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
shade_input_set_shade_texco(shi);
- if(R.r.mode & R_SHADOW)
- shade_samples_do_shadow(ssamp);
+ shade_samples_do_AO(ssamp);
if(shi->mat->nodetree && shi->mat->use_nodes) {
ntreeShaderExecTree(shi->mat->nodetree, shi, &shr);
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index a15e0d031e8..f706be36523 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -70,8 +70,8 @@ extern struct Render R;
- shade_input_set_uv() <- not for ray or bake
- shade_input_set_normals()
- shade_samples()
- - if shadow or AO
- - shade_samples_do_shadow()
+ - if AO
+ - shade_samples_do_AO()
- if shading happens
- for each sample
- shade_input_set_shade_texco()
@@ -835,7 +835,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
/* initialize per part, not per pixel! */
-static void shade_input_initialize(ShadeInput *shi, RenderPart *pa, RenderLayer *rl, int sample)
+void shade_input_initialize(ShadeInput *shi, RenderPart *pa, RenderLayer *rl, int sample)
{
memset(shi, 0, sizeof(ShadeInput));
@@ -864,59 +864,24 @@ void shade_sample_initialize(ShadeSample *ssamp, RenderPart *pa, RenderLayer *rl
shade_input_initialize(&ssamp->shi[a], pa, rl, a);
memset(&ssamp->shr[a], 0, sizeof(ShadeResult));
}
+
+ ssamp->samplenr= 0; /* counter, detect shadow-reuse for shaders */
}
-/* for all lamps, for all samples, do shadow */
-/* renderdata mode was checked for */
-void shade_samples_do_shadow(ShadeSample *ssamp)
+
+/* Do AO or (future) GI */
+void shade_samples_do_AO(ShadeSample *ssamp)
{
- GroupObject *go;
- LampRen *lar;
ShadeInput *shi;
int sample;
- if(ssamp->shi[0].passflag & (SCE_PASS_COMBINED|SCE_PASS_DIFFUSE|SCE_PASS_SPEC|SCE_PASS_SHADOW)) {
- for(go=R.lights.first; go; go= go->next) {
- lar= go->lampren;
-
- /* if there's shadow */
- if(lar->shb || (lar->mode & LA_SHAD_RAY)) {
-
- for(sample=0, shi= ssamp->shi; sample<ssamp->tot; shi++, sample++) {
- float visifac, lv[3], lampdist, inpr;
-
- /* tests to quickly reject */
- if(lar->mode & LA_LAYER) if((lar->lay & shi->vlr->lay)==0) continue;
- if((lar->lay & shi->lay)==0) continue;
-
- if(!(shi->mode & MA_SHADOW) || (shi->mode & MA_SHLESS))
- continue;
-
- if(!( (shi->combinedflag | shi->passflag) & SCE_PASS_SHADOW))
- continue;
-
- visifac= lamp_get_visibility(lar, shi->co, lv, &lampdist);
- if(visifac==0.0f)
- continue;
-
- inpr= INPR(shi->vn, lv);
-
- /* tangential faces always look at lamp */
- if( (shi->mat->mode & MA_TANGENT_V) || (shi->vlr->flag & R_TANGENT) )
- inpr= 1.0f - inpr*inpr;
- else if(inpr <= 0.0f)
- continue;
-
- /* now we're going (1 = do it real) */
- lamp_get_shadow(lar, shi, inpr, lar->shadsamp[shi->thread].shadfac[sample], 1);
- }
- }
- }
- }
+ if(!(R.r.mode & R_SHADOW))
+ return;
+ if(!(R.r.mode & R_RAYTRACE))
+ return;
- /* do the AO */
if(R.wrld.mode & WO_AMB_OCC)
- if(ssamp->shi[0].passflag & (SCE_PASS_COMBINED|SCE_PASS_DIFFUSE|SCE_PASS_AO))
+ if(ssamp->shi[0].passflag & (SCE_PASS_COMBINED|SCE_PASS_AO))
for(sample=0, shi= ssamp->shi; sample<ssamp->tot; shi++, sample++)
if(!(shi->mode & MA_SHLESS))
if(shi->mode & MA_SHADOW)
@@ -924,6 +889,7 @@ void shade_samples_do_shadow(ShadeSample *ssamp)
}
+
static void shade_samples_fill_with_ps(ShadeSample *ssamp, PixStr *ps, int x, int y)
{
ShadeInput *shi;
@@ -950,6 +916,7 @@ static void shade_samples_fill_with_ps(ShadeSample *ssamp, PixStr *ps, int x, in
shade_input_copy_triangle(shi, shi-1);
shi->mask= (1<<samp);
+ shi->samplenr= ssamp->samplenr++;
shade_input_set_viewco(shi, xs, ys, (float)ps->z);
shade_input_set_uv(shi);
shade_input_set_normals(shi);
@@ -970,6 +937,7 @@ static void shade_samples_fill_with_ps(ShadeSample *ssamp, PixStr *ps, int x, in
ys= (float)y + 0.5f;
}
shi->mask= curmask;
+ shi->samplenr= ssamp->samplenr++;
shade_input_set_viewco(shi, xs, ys, (float)ps->z);
shade_input_set_uv(shi);
shade_input_set_normals(shi);
@@ -994,8 +962,7 @@ int shade_samples(ShadeSample *ssamp, PixStr *ps, int x, int y)
int samp;
/* if shadow or AO? */
- if(R.r.mode & R_SHADOW)
- shade_samples_do_shadow(ssamp);
+ shade_samples_do_AO(ssamp);
/* if shade (all shadepinputs have same passflag) */
if(ssamp->shi[0].passflag & ~(SCE_PASS_Z|SCE_PASS_INDEXOB)) {
diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c
index dd2cad02dc0..d6457313906 100644
--- a/source/blender/render/intern/source/shadeoutput.c
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -59,7 +59,7 @@ static ListBase *get_lights(ShadeInput *shi)
if(shi->light_override)
return &shi->light_override->gobject;
- else if(shi->mat->group)
+ else if(shi->mat && shi->mat->group)
return &shi->mat->group->gobject;
else
return &R.lights;
@@ -1003,8 +1003,9 @@ void ambient_occlusion_to_diffuse(ShadeInput *shi, float *diff)
/* result written in shadfac */
void lamp_get_shadow(LampRen *lar, ShadeInput *shi, float inp, float *shadfac, int do_real)
{
+ LampShadowSubSample *lss= &(lar->shadsamp[shi->thread].s[shi->sample]);
- if(do_real) {
+ if(do_real || lss->samplenr!=shi->samplenr) {
shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 1.0f;
@@ -1017,10 +1018,12 @@ void lamp_get_shadow(LampRen *lar, ShadeInput *shi, float inp, float *shadfac, i
else if(lar->mode & LA_SHAD_RAY) {
ray_shadow(shi, lar, shadfac);
}
+
+ QUATCOPY(lss->shadfac, shadfac);
+ lss->samplenr= shi->samplenr;
}
else {
- float *fp= lar->shadsamp[shi->thread].shadfac[shi->sample];
- QUATCOPY(shadfac, fp);
+ QUATCOPY(shadfac, lss->shadfac);
}
}
@@ -1455,6 +1458,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
shr->diff[1]= shi->g*shi->emit;
shr->diff[2]= shi->b*shi->emit;
}
+ VECCOPY(shr->shad, shr->diff);
/* AO pass */
if(R.wrld.mode & WO_AMB_OCC) {
@@ -1501,7 +1505,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
/* exposure correction */
if(R.wrld.exp!=0.0f || R.wrld.range!=1.0f) {
- wrld_exposure_correct(shr->diff);
+ wrld_exposure_correct(shr->combined); /* has no spec! */
wrld_exposure_correct(shr->spec);
}
}
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 1b30cbf6037..a3b67f8e654 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -2813,9 +2813,6 @@ static int vergzvlak(const void *a1, const void *a2)
return 0;
}
-/**
-* Shade this face at this location in SCS.
- */
static void shade_tra_samples_fill(ShadeSample *ssamp, int x, int y, int z, int facenr, int curmask)
{
@@ -2843,6 +2840,7 @@ static void shade_tra_samples_fill(ShadeSample *ssamp, int x, int y, int z, int
shi++;
}
shi->mask= (1<<samp);
+ shi->samplenr= ssamp->samplenr++;
shade_input_set_viewco(shi, xs, ys, (float)z);
shade_input_set_uv(shi);
shade_input_set_normals(shi);
@@ -2862,6 +2860,7 @@ static void shade_tra_samples_fill(ShadeSample *ssamp, int x, int y, int z, int
ys= (float)y + 0.5f;
}
shi->mask= curmask;
+ shi->samplenr= ssamp->samplenr++;
shade_input_set_viewco(shi, xs, ys, (float)z);
shade_input_set_uv(shi);
shade_input_set_normals(shi);
@@ -2881,9 +2880,8 @@ static int shade_tra_samples(ShadeSample *ssamp, int x, int y, int z, int facenr
ShadeResult *shr= ssamp->shr;
int samp;
- /* if shadow or AO? */
- if(R.r.mode & R_SHADOW)
- shade_samples_do_shadow(ssamp);
+ /* if AO? */
+ shade_samples_do_AO(ssamp);
/* if shade (all shadepinputs have same passflag) */
if(shi->passflag & ~(SCE_PASS_Z|SCE_PASS_INDEXOB)) {