diff options
Diffstat (limited to 'source/blender/render/intern')
21 files changed, 425 insertions, 377 deletions
diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index dea8c1bdb6f..bef7ae6196b 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -60,7 +60,7 @@ int RE_rayobject_raycast(RayObject *r, struct Isect *i); RayObject* RE_rayobject_octree_create(int ocres, int size); RayObject* RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob); -RayObject* RE_rayobject_empty_create(); +RayObject* RE_rayobject_empty_create(void); RayObject* RE_rayobject_blibvh_create(int size); /* BLI_kdopbvh.c */ RayObject* RE_rayobject_vbvh_create(int size); /* raytrace/rayobject_vbvh.c */ diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index cf16211b6d1..13ca40bfd20 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -60,6 +60,7 @@ struct RenderBuckets; struct ObjectInstanceRen; struct RayObject; struct RayFace; +struct ReportList; struct Main; #define TABLEINITSIZE 1024 @@ -214,7 +215,7 @@ struct Render ListBase instancetable; int totinstance; - struct Image *backbuf, *bakebuf; + struct Image *bakebuf; struct GHash *orco_hash; @@ -252,10 +253,9 @@ struct Render int (*test_break)(void *handle); void *tbh; - void (*error)(void *handle, const char *str); - void *erh; - RenderStats i; + + struct ReportList *reports; }; /* ------------------------------------------------------------------------- */ diff --git a/source/blender/render/intern/include/shading.h b/source/blender/render/intern/include/shading.h index 865cb056a61..07d24ea6d66 100644 --- a/source/blender/render/intern/include/shading.h +++ b/source/blender/render/intern/include/shading.h @@ -37,7 +37,7 @@ struct LampRen; struct VlakRen; struct StrandSegment; struct StrandPoint; -struct ObjectInstanceRen obi; +struct ObjectInstanceRen; struct Isect; /* shadeinput.c */ diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 74ce7957dd7..b385b507707 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -341,7 +341,7 @@ u | | F1 | F2 | /* ------------------------------------------------------------------------- */ -static void split_v_renderfaces(ObjectRen *obr, int startvlak, int startvert, int usize, int vsize, int uIndex, int UNUSED(cyclu), int cyclv) +static void split_v_renderfaces(ObjectRen *obr, int startvlak, int UNUSED(startvert), int UNUSED(usize), int vsize, int uIndex, int UNUSED(cyclu), int cyclv) { int vLen = vsize-1+(!!cyclv); int v; @@ -393,7 +393,7 @@ static void calc_edge_stress_add(float *accum, VertRen *v1, VertRen *v2) acc[1]+= 1.0f; } -static void calc_edge_stress(Render *re, ObjectRen *obr, Mesh *me) +static void calc_edge_stress(Render *UNUSED(re), ObjectRen *obr, Mesh *me) { float loc[3], size[3], *accum, *acc, *accumoffs, *stress; int a; @@ -590,7 +590,7 @@ static void SetTSpace(const SMikkTSpaceContext * pContext, const float fvTangent } } -static void calc_vertexnormals(Render *re, ObjectRen *obr, int do_tangent, int do_nmap_tangent) +static void calc_vertexnormals(Render *UNUSED(re), ObjectRen *obr, int do_tangent, int do_nmap_tangent) { MemArena *arena= NULL; VertexTangent **vtangents= NULL; @@ -759,7 +759,7 @@ static void as_addvert(ASvert *asv, VertRen *v1, VlakRen *vlr) } } -static int as_testvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh) +static int as_testvertex(VlakRen *vlr, VertRen *UNUSED(ver), ASvert *asv, float thresh) { /* return 1: vertex needs a copy */ ASface *asf; @@ -782,7 +782,7 @@ static int as_testvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh) return 0; } -static VertRen *as_findvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh) +static VertRen *as_findvertex(VlakRen *vlr, VertRen *UNUSED(ver), ASvert *asv, float thresh) { /* return when new vertex already was made */ ASface *asf; @@ -810,7 +810,7 @@ static VertRen *as_findvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thr /* note; autosmooth happens in object space still, after applying autosmooth we rotate */ /* note2; actually, when original mesh and displist are equal sized, face normals are from original mesh */ -static void autosmooth(Render *re, ObjectRen *obr, float mat[][4], int degr) +static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[][4], int degr) { ASvert *asv, *asverts; ASface *asf; @@ -1680,8 +1680,6 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem bb.anim = part->bb_anim; bb.lock = part->draw & PART_DRAW_BB_LOCK; bb.ob = (part->bb_ob ? part->bb_ob : RE_GetCamera(re)); - bb.offset[0] = part->bb_offset[0]; - bb.offset[1] = part->bb_offset[1]; bb.split_offset = part->bb_split_offset; bb.totnum = totpart+totchild; bb.uv_split = part->bb_uv_split; @@ -1800,10 +1798,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem pa_size = pa->size; - BLI_srandom(psys->seed+a); - - r_tilt = 2.0f*(BLI_frand() - 0.5f); - r_length = BLI_frand(); + r_tilt = 2.0f*(PSYS_FRAND(a) - 0.5f); + r_length = PSYS_FRAND(a+1); if(path_nbr) { cache = psys->pathcache[a]; @@ -2015,7 +2011,20 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if(part->ren_as == PART_DRAW_BB) { bb.random = random; - bb.size = pa_size; + bb.offset[0] = part->bb_offset[0]; + bb.offset[1] = part->bb_offset[1]; + bb.size[0] = part->bb_size[0] * pa_size; + if (part->bb_align==PART_BB_VEL) { + float pa_vel = len_v3(state.vel); + float head = part->bb_vel_head*pa_vel; + float tail = part->bb_vel_tail*pa_vel; + bb.size[1] = part->bb_size[1]*pa_size + head + tail; + /* use offset to adjust the particle center. this is relative to size, so need to divide! */ + if (bb.size[1] > 0.0f) + bb.offset[1] += (head-tail) / bb.size[1]; + } + else + bb.size[1] = part->bb_size[1] * pa_size; bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt); bb.time = ct; bb.num = a; @@ -2036,11 +2045,24 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem mul_m4_v3(psys->parent->obmat, state.co); if(use_duplimat) - mul_m4_v4(duplimat, state.co); + mul_m4_v3(duplimat, state.co); if(part->ren_as == PART_DRAW_BB) { bb.random = random; - bb.size = pa_size; + bb.offset[0] = part->bb_offset[0]; + bb.offset[1] = part->bb_offset[1]; + bb.size[0] = part->bb_size[0] * pa_size; + if (part->bb_align==PART_BB_VEL) { + float pa_vel = len_v3(state.vel); + float head = part->bb_vel_head*pa_vel; + float tail = part->bb_vel_tail*pa_vel; + bb.size[1] = part->bb_size[1]*pa_size + head + tail; + /* use offset to adjust the particle center. this is relative to size, so need to divide! */ + if (bb.size[1] > 0.0f) + bb.offset[1] += (head-tail) / bb.size[1]; + } + else + bb.size[1] = part->bb_size[1] * pa_size; bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt); bb.time = pa_time; bb.num = a; @@ -2100,7 +2122,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem /* Halo's */ /* ------------------------------------------------------------------------- */ -static void make_render_halos(Render *re, ObjectRen *obr, Mesh *me, int totvert, MVert *mvert, Material *ma, float *orco) +static void make_render_halos(Render *re, ObjectRen *obr, Mesh *UNUSED(me), int totvert, MVert *mvert, Material *ma, float *orco) { Object *ob= obr->ob; HaloRen *har; @@ -2908,8 +2930,10 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) vlr->v3= RE_findOrAddVert(obr, startvert+index[2]); vlr->v4= NULL; - normal_tri_v3(tmp, vlr->v3->co, vlr->v2->co, vlr->v1->co); - add_v3_v3(n, tmp); + if(area_tri_v3(vlr->v3->co, vlr->v2->co, vlr->v1->co)>FLT_EPSILON) { + normal_tri_v3(tmp, vlr->v3->co, vlr->v2->co, vlr->v1->co); + add_v3_v3(n, tmp); + } vlr->mat= matar[ dl->col ]; vlr->flag= 0; @@ -3351,7 +3375,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) /* test for 100% transparant */ ok= 1; - if(ma->alpha==0.0f && ma->spectra==0.0f && ma->filter==0.0f && (ma->mode & MA_TRANSP)) { + if(ma->alpha==0.0f && ma->spectra==0.0f && ma->filter==0.0f && (ma->mode & MA_TRANSP) && (ma->mode & MA_RAYMIRROR)==0) { ok= 0; /* texture on transparency? */ for(a=0; a<MAX_MTEX; a++) { @@ -4665,7 +4689,6 @@ void RE_Database_Free(Render *re) re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0; re->i.convertdone= 0; - re->backbuf= NULL; re->bakebuf= NULL; if(re->scene) @@ -4700,7 +4723,7 @@ static int allow_render_object(Render *re, Object *ob, int nolamps, int onlysele return 1; } -static int allow_render_dupli_instance(Render *re, DupliObject *dob, Object *obd) +static int allow_render_dupli_instance(Render *UNUSED(re), DupliObject *dob, Object *obd) { ParticleSystem *psys; Material *ma; @@ -5387,7 +5410,7 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float * float imat[4][4]; FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(fsob, eModifierType_Fluidsim); FluidsimSettings *fss; - float *velarray = NULL; + FluidVertexVelocity *velarray = NULL; /* only one step needed */ if(step) return 1; @@ -5401,14 +5424,14 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float * invert_m4_m4(imat, mat); /* set first vertex OK */ - if(!fss->meshSurfNormals) return 0; + if(!fss->meshVelocities) return 0; - if( obr->totvert != GET_INT_FROM_POINTER(fss->meshSurface) ) { + if( obr->totvert != fss->totvert) { //fprintf(stderr, "load_fluidsimspeedvectors - modified fluidsim mesh, not using speed vectors (%d,%d)...\n", obr->totvert, fsob->fluidsimSettings->meshSurface->totvert); // DEBUG return 0; } - velarray = (float *)fss->meshSurfNormals; + velarray = fss->meshVelocities; if(obi->flag & R_TRANSFORMED) mul_m4_m4m4(winmat, obi->mat, re->winmat); @@ -5420,7 +5443,7 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float * so that also small drops/little water volumes return a velocity != 0. But I had no luck in fixing that function - DG */ for(a=0; a<obr->totvert; a++) { - for(j=0;j<3;j++) avgvel[j] += velarray[3*a + j]; + for(j=0;j<3;j++) avgvel[j] += velarray[a].vel[j]; } for(j=0;j<3;j++) avgvel[j] /= (float)(obr->totvert); @@ -5435,7 +5458,7 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float * // get fluid velocity fsvec[3] = 0.; //fsvec[0] = fsvec[1] = fsvec[2] = fsvec[3] = 0.; fsvec[2] = 2.; // NT fixed test - for(j=0;j<3;j++) fsvec[j] = velarray[3*a + j]; + for(j=0;j<3;j++) fsvec[j] = velarray[a].vel[j]; /* (bad) HACK insert average velocity if none is there (see previous comment) */ if((fsvec[0] == 0.0) && (fsvec[1] == 0.0) && (fsvec[2] == 0.0)) @@ -5657,13 +5680,14 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned RE_BAKE_DISPLACEMENT:for baking, no lamps, only selected objects RE_BAKE_SHADOW: for baking, only shadows, but all objects */ -void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay, int type, Object *actob) +void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay, const int type, Object *actob) { Object *camera; float mat[4][4]; float amb[3]; - int onlyselected, nolamps; - + const short onlyselected= !ELEM4(type, RE_BAKE_LIGHT, RE_BAKE_ALL, RE_BAKE_SHADOW, RE_BAKE_AO); + const short nolamps= ELEM3(type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_DISPLACEMENT); + re->main= bmain; re->scene= scene; re->lay= lay; @@ -5713,7 +5737,15 @@ void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay, unit_m4(mat); RE_SetView(re, mat); } - + copy_m3_m4(re->imat, re->viewinv); + + /* TODO: deep shadow maps + baking + strands */ + /* strands use the window matrix and view size, there is to correct + * window matrix but at least avoids malloc and crash loop [#27807] */ + unit_m4(re->winmat); + re->winx= re->winy= 256; + /* done setting dummy values */ + init_render_world(re); /* do first, because of ambient. also requires re->osa set correct */ if(re->r.mode & R_RAYTRACE) { init_render_qmcsampler(re); @@ -5732,9 +5764,6 @@ void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay, set_node_shader_lamp_loop(shade_material_loop); /* MAKE RENDER DATA */ - nolamps= !ELEM3(type, RE_BAKE_LIGHT, RE_BAKE_ALL, RE_BAKE_SHADOW); - onlyselected= ELEM3(type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_DISPLACEMENT); - database_init_objects(re, lay, nolamps, onlyselected, actob, 0); set_material_lightgroups(re); @@ -5749,6 +5778,14 @@ void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay, if(re->r.mode & R_RAYTRACE) makeraytree(re); + /* point density texture */ + if(!re->test_break(re->tbh)) + make_pointdensities(re); + + /* voxel data texture */ + if(!re->test_break(re->tbh)) + make_voxeldata(re); + /* occlusion */ if((re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) && !re->test_break(re->tbh)) if(re->wrld.ao_gather_method == WO_AOGATHER_APPROX) diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 1e40ab886ae..e2ab21ef877 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -149,7 +149,6 @@ static Render *envmap_render_copy(Render *re, EnvMap *env) envre->r.layers.first= envre->r.layers.last= NULL; envre->r.filtertype= 0; envre->r.xparts= envre->r.yparts= 2; - envre->r.bufflag= 0; envre->r.size= 100; envre->r.yasp= envre->r.xasp= 1; diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 7d2c7b35247..6d264951204 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -76,6 +76,8 @@ extern struct Render R; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float maxy, TexResult *texres, const short imaprepeat, const short imapextend); + /* *********** IMAGEWRAPPING ****************** */ @@ -113,6 +115,7 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, TexResult *texre { float fx, fy, val1, val2, val3; int x, y, retval; + int xi, yi; /* original values */ texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0f; @@ -164,8 +167,8 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, TexResult *texre } } - x = (int)floorf(fx*ibuf->x); - y = (int)floorf(fy*ibuf->y); + x= xi= (int)floorf(fx*ibuf->x); + y= yi= (int)floorf(fy*ibuf->y); if(tex->extend == TEX_CLIPCUBE) { if(x<0 || y<0 || x>=ibuf->x || y>=ibuf->y || texvec[2]<-1.0f || texvec[2]>1.0f) { @@ -201,7 +204,23 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, TexResult *texre ibuf->rect+= (ibuf->x*ibuf->y); } - ibuf_get_color(&texres->tr, ibuf, x, y); + /* interpolate */ + if (tex->imaflag & TEX_INTERPOL) { + float filterx, filtery; + filterx = (0.5f * tex->filtersize) / ibuf->x; + filtery = (0.5f * tex->filtersize) / ibuf->y; + + /* important that this value is wrapped [#27782] + * this applies the modifications made by the checks above, + * back to the floating point values */ + fx -= (float)(xi - x) / (float)ibuf->x; + fy -= (float)(yi - y) / (float)ibuf->y; + + boxsample(ibuf, fx-filterx, fy-filtery, fx+filterx, fy+filtery, texres, (tex->extend==TEX_REPEAT), (tex->extend==TEX_EXTEND)); + } + else { /* no filtering */ + ibuf_get_color(&texres->tr, ibuf, x, y); + } if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) { ibuf->rect-= (ibuf->x*ibuf->y); @@ -513,15 +532,17 @@ static void boxsampleclip(struct ImBuf *ibuf, rctf *rf, TexResult *texres) } } -static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float maxy, TexResult *texres, int imaprepeat, int imapextend) +static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float maxy, TexResult *texres, const short imaprepeat, const short imapextend) { /* Sample box, performs clip. minx etc are in range 0.0 - 1.0 . - * Enlarge with antialiased edges of pixels. - * If variable 'imaprepeat' has been set, the - * clipped-away parts are sampled as well. - */ + * Enlarge with antialiased edges of pixels. + * If variable 'imaprepeat' has been set, the + * clipped-away parts are sampled as well. + */ /* note: actually minx etc isnt in the proper range... this due to filter size and offset vectors for bump */ /* note: talpha must be initialized */ + /* note: even when 'imaprepeat' is set, this can only repeate once in any direction. + * the point which min/max is derived from is assumed to be wrapped */ TexResult texr; rctf *rf, stack[8]; float opp, tot, alphaclip= 1.0; diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 436f0ecd997..b9006b390ab 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -64,6 +64,7 @@ #include "BLI_blenlib.h" #include "BLI_rand.h" #include "BLI_threads.h" +#include "BLI_callbacks.h" #include "BLI_utildefines.h" #include "PIL_time.h" @@ -127,7 +128,7 @@ Render R; /* ********* alloc and free ******** */ -static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, ReportList *reports, const char *name_override); +static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, const char *name_override); static volatile int g_break= 0; static int thread_break(void *UNUSED(arg)) @@ -140,7 +141,6 @@ static void result_nothing(void *UNUSED(arg), RenderResult *UNUSED(rr)) {} static void result_rcti_nothing(void *UNUSED(arg), RenderResult *UNUSED(rr), volatile struct rcti *UNUSED(rect)) {} static void stats_nothing(void *UNUSED(arg), RenderStats *UNUSED(rs)) {} static void float_nothing(void *UNUSED(arg), float UNUSED(val)) {} -static void print_error(void *UNUSED(arg), const char *str) {printf("ERROR: %s\n", str);} static int default_break(void *UNUSED(arg)) {return G.afbreek == 1;} static void stats_background(void *UNUSED(arg), RenderStats *rs) @@ -383,6 +383,10 @@ static const char *get_pass_name(int passtype, int channel) if(channel==-1) return "IndexOB"; return "IndexOB.X"; } + if(passtype == SCE_PASS_INDEXMA) { + if(channel==-1) return "IndexMA"; + return "IndexMA.X"; + } if(passtype == SCE_PASS_MIST) { if(channel==-1) return "Mist"; return "Mist.Z"; @@ -448,6 +452,9 @@ static int passtype_from_name(char *str) if(strcmp(str, "IndexOB")==0) return SCE_PASS_INDEXOB; + if(strcmp(str, "IndexMA")==0) + return SCE_PASS_INDEXMA; + if(strcmp(str, "Mist")==0) return SCE_PASS_MIST; @@ -631,7 +638,9 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int render_layer_add_pass(rr, rl, 3, SCE_PASS_REFRACT); if(srl->passflag & SCE_PASS_INDEXOB) render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXOB); - if(srl->passflag & SCE_PASS_MIST) + if(srl->passflag & SCE_PASS_INDEXMA) + render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXMA); + if(srl->passflag & SCE_PASS_MIST) render_layer_add_pass(rr, rl, 1, SCE_PASS_MIST); if(rl->passflag & SCE_PASS_RAYHITS) render_layer_add_pass(rr, rl, 4, SCE_PASS_RAYHITS); @@ -1189,13 +1198,12 @@ void RE_InitRenderCB(Render *re) re->display_draw= result_rcti_nothing; re->progress= float_nothing; re->test_break= default_break; - re->error= print_error; if(G.background) re->stats_draw= stats_background; else re->stats_draw= stats_nothing; /* clear callback handles */ - re->dih= re->dch= re->ddh= re->sdh= re->prh= re->tbh= re->erh= NULL; + re->dih= re->dch= re->ddh= re->sdh= re->prh= re->tbh= NULL; } /* only call this while you know it will remove the link too */ @@ -1250,7 +1258,7 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer * if(re->rectx < 2 || re->recty < 2 || (BKE_imtype_is_movie(rd->imtype) && (re->rectx < 16 || re->recty < 16) )) { - re->error(re->erh, "Image too small"); + BKE_report(re->reports, RPT_ERROR, "Image too small"); re->ok= 0; return; } @@ -1416,11 +1424,6 @@ void RE_test_break_cb(Render *re, void *handle, int (*f)(void *handle)) re->test_break= f; re->tbh= handle; } -void RE_error_cb(Render *re, void *handle, void (*f)(void *handle, const char *str)) -{ - re->error= f; - re->erh= handle; -} /* ********* add object data (later) ******** */ @@ -2065,36 +2068,6 @@ static void do_render_fields_3d(Render *re) re->display_draw(re->ddh, re->result, NULL); } -static void load_backbuffer(Render *re) -{ - if(re->r.alphamode == R_ADDSKY) { - ImBuf *ibuf; - char name[256]; - - BLI_strncpy(name, re->r.backbuf, sizeof(name)); - BLI_path_abs(name, re->main->name); - BLI_path_frame(name, re->r.cfra, 0); - - if(re->backbuf) { - re->backbuf->id.us--; - if(re->backbuf->id.us<1) - BKE_image_signal(re->backbuf, NULL, IMA_SIGNAL_RELOAD); - } - - re->backbuf= BKE_add_image_file(name); - ibuf= BKE_image_get_ibuf(re->backbuf, NULL); - if(ibuf==NULL) { - // error() doesnt work with render window open - //error("No backbuf there!"); - printf("Error: No backbuf %s\n", name); - } - else { - if (re->r.mode & R_FIELDS) - image_de_interlace(re->backbuf, re->r.mode & R_ODDFIELD); - } - } -} - /* main render routine, no compositing */ static void do_render_fields_blur_3d(Render *re) { @@ -2105,10 +2078,6 @@ static void do_render_fields_blur_3d(Render *re) G.afbreek= 1; return; } - - /* backbuffer initialize */ - if(re->r.bufflag & 1) - load_backbuffer(re); /* now use renderdata and camera to set viewplane */ RE_SetCamera(re, camera); @@ -2203,6 +2172,24 @@ static void render_scene(Render *re, Scene *sce, int cfra) do_render_fields_blur_3d(resc); } +/* helper call to detect if this scene needs a render, or if there's a any render layer to render */ +static int composite_needs_render(Scene *sce, int this_scene) +{ + bNodeTree *ntree= sce->nodetree; + bNode *node; + + if(ntree==NULL) return 1; + if(sce->use_nodes==0) return 1; + if((sce->r.scemode & R_DOCOMP)==0) return 1; + + for(node= ntree->nodes.first; node; node= node->next) { + if(node->type==CMP_NODE_R_LAYERS) + if(this_scene==0 || node->id==NULL || node->id==&sce->id) + return 1; + } + return 0; +} + static void tag_scenes_for_render(Render *re) { bNode *node; @@ -2211,7 +2198,8 @@ static void tag_scenes_for_render(Render *re) for(sce= re->main->scene.first; sce; sce= sce->id.next) sce->id.flag &= ~LIB_DOIT; - re->scene->id.flag |= LIB_DOIT; + if(RE_GetCamera(re) && composite_needs_render(re->scene, 1)) + re->scene->id.flag |= LIB_DOIT; if(re->scene->nodetree==NULL) return; @@ -2248,6 +2236,8 @@ static void ntree_render_scenes(Render *re) render_scene(re, scene, cfra); restore_scene= (scene != re->scene); node->id->flag &= ~LIB_DOIT; + + NodeTagChanged(re->scene->nodetree, node); } } } @@ -2258,24 +2248,6 @@ static void ntree_render_scenes(Render *re) set_scene_bg(re->main, re->scene); } -/* helper call to detect if theres a composite with render-result node */ -static int composite_needs_render(Scene *sce) -{ - bNodeTree *ntree= sce->nodetree; - bNode *node; - - if(ntree==NULL) return 1; - if(sce->use_nodes==0) return 1; - if((sce->r.scemode & R_DOCOMP)==0) return 1; - - for(node= ntree->nodes.first; node; node= node->next) { - if(node->type==CMP_NODE_R_LAYERS) - if(node->id==NULL || node->id==&sce->id) - return 1; - } - return 0; -} - /* bad call... need to think over proper method still */ static void render_composit_stats(void *UNUSED(arg), char *str) { @@ -2291,6 +2263,16 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree) float *rectf, filt[3][3]; int sample; + /* interaction callbacks */ + if(ntree) { + ntree->stats_draw= render_composit_stats; + ntree->test_break= re->test_break; + ntree->progress= re->progress; + ntree->sdh= re->sdh; + ntree->tbh= re->tbh; + ntree->prh= re->prh; + } + /* filtmask needs it */ R= *re; @@ -2298,25 +2280,27 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree) rectf= MEM_mapallocN(re->rectx*re->recty*sizeof(float)*4, "fullsample rgba"); for(sample=0; sample<re->r.osa; sample++) { + Render *re1; RenderResult rres; int x, y, mask; - /* set all involved renders on the samplebuffers (first was done by render itself) */ + /* enable full sample print */ + R.i.curfsa= sample+1; + + /* set all involved renders on the samplebuffers (first was done by render itself, but needs tagged) */ /* also function below assumes this */ - if(sample) { - Render *re1; - tag_scenes_for_render(re); - for(re1= RenderGlobal.renderlist.first; re1; re1= re1->next) { - if(re1->scene->id.flag & LIB_DOIT) { - if(re1->r.scemode & R_FULL_SAMPLE) { + tag_scenes_for_render(re); + for(re1= RenderGlobal.renderlist.first; re1; re1= re1->next) { + if(re1->scene->id.flag & LIB_DOIT) { + if(re1->r.scemode & R_FULL_SAMPLE) { + if(sample) read_render_result(re1, sample); - ntreeCompositTagRender(re1->scene); /* ensure node gets exec to put buffers on stack */ - } + ntreeCompositTagRender(re1->scene); /* ensure node gets exec to put buffers on stack */ } } } - + /* composite */ if(ntree) { ntreeCompositTagRender(re->scene); @@ -2359,6 +2343,17 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree) break; } + /* clear interaction callbacks */ + if(ntree) { + ntree->stats_draw= NULL; + ntree->test_break= NULL; + ntree->progress= NULL; + ntree->tbh= ntree->sdh= ntree->prh= NULL; + } + + /* disable full sample print */ + R.i.curfsa= 0; + BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); if(re->result->rectf) MEM_freeN(re->result->rectf); @@ -2398,8 +2393,10 @@ void RE_MergeFullSample(Render *re, Main *bmain, Scene *sce, bNodeTree *ntree) } /* own render result should be read/allocated */ - if(re->scene->id.flag & LIB_DOIT) + if(re->scene->id.flag & LIB_DOIT) { RE_ReadRenderResult(re->scene, re->scene); + re->scene->id.flag &= ~LIB_DOIT; + } /* and now we can draw (result is there) */ re->display_init(re->dih, re->result); @@ -2417,12 +2414,21 @@ static void do_render_composite_fields_blur_3d(Render *re) /* INIT seeding, compositor can use random texture */ BLI_srandom(re->r.cfra); - if(composite_needs_render(re->scene)) { + if(composite_needs_render(re->scene, 1)) { /* save memory... free all cached images */ ntreeFreeCache(ntree); do_render_fields_blur_3d(re); - } else { + } + else { + /* ensure new result gets added, like for regular renders */ + BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); + + RE_FreeRenderResult(re->result); + re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM); + + BLI_rw_mutex_unlock(&re->resultmutex); + /* scene render process already updates animsys */ update_newframe = 1; } @@ -2706,14 +2712,14 @@ static int check_valid_camera(Scene *scene, Object *camera_override) return 1; } -int RE_is_rendering_allowed(Scene *scene, Object *camera_override, void *erh, void (*error)(void *handle, const char *str)) +int RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *reports) { SceneRenderLayer *srl; if(scene->r.mode & R_BORDER) { if(scene->r.border.xmax <= scene->r.border.xmin || scene->r.border.ymax <= scene->r.border.ymin) { - error(erh, "No border area selected."); + BKE_report(reports, RPT_ERROR, "No border area selected."); return 0; } } @@ -2724,13 +2730,13 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, void *erh, vo scene_unique_exr_name(scene, str, 0); if (BLI_is_writable(str)==0) { - error(erh, "Can not save render buffers, check the temp default path"); + BKE_report(reports, RPT_ERROR, "Can not save render buffers, check the temp default path"); return 0; } /* no fullsample and edge */ if((scene->r.scemode & R_FULL_SAMPLE) && (scene->r.mode & R_EDGE)) { - error(erh, "Full Sample doesn't support Edge Enhance"); + BKE_report(reports, RPT_ERROR, "Full Sample doesn't support Edge Enhance"); return 0; } @@ -2744,7 +2750,7 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, void *erh, vo bNode *node; if(ntree==NULL) { - error(erh, "No Nodetree in Scene"); + BKE_report(reports, RPT_ERROR, "No Nodetree in Scene"); return 0; } @@ -2753,13 +2759,13 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, void *erh, vo break; if(node==NULL) { - error(erh, "No Render Output Node in Scene"); + BKE_report(reports, RPT_ERROR, "No Render Output Node in Scene"); return 0; } if(scene->r.scemode & R_FULL_SAMPLE) { - if(composite_needs_render(scene)==0) { - error(erh, "Full Sample AA not supported without 3d rendering"); + if(composite_needs_render(scene, 0)==0) { + BKE_report(reports, RPT_ERROR, "Full Sample AA not supported without 3d rendering"); return 0; } } @@ -2768,7 +2774,7 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, void *erh, vo /* check valid camera, without camera render is OK (compo, seq) */ if(!check_valid_camera(scene, camera_override)) { - error(erh, "No camera"); + BKE_report(reports, RPT_ERROR, "No camera"); return 0; } @@ -2778,7 +2784,7 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, void *erh, vo /* forbidden combinations */ if(scene->r.mode & R_PANORAMA) { if(scene->r.mode & R_ORTHO) { - error(erh, "No Ortho render possible for Panorama"); + BKE_report(reports, RPT_ERROR, "No Ortho render possible for Panorama"); return 0; } } @@ -2794,13 +2800,13 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, void *erh, vo if(!(srl->layflag & SCE_LAY_DISABLE)) break; if(srl==NULL) { - error(erh, "All RenderLayers are disabled"); + BKE_report(reports, RPT_ERROR, "All RenderLayers are disabled"); return 0; } /* renderer */ if(!ELEM(scene->r.renderer, R_INTERN, R_YAFRAY)) { - error(erh, "Unknown render engine set"); + BKE_report(reports, RPT_ERROR, "Unknown render engine set"); return 0; } @@ -2902,6 +2908,11 @@ static int render_initialize_from_main(Render *re, Main *bmain, Scene *scene, Sc return 1; } +void RE_SetReports(Render *re, ReportList *reports) +{ + re->reports= reports; +} + /* general Blender frame render call */ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *srl, Object *camera_override, unsigned int lay, int frame, const short write_still) { @@ -2912,6 +2923,9 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr if(render_initialize_from_main(re, bmain, scene, srl, camera_override, lay, 0, 0)) { MEM_reset_peak_memory(); + + BLI_exec_cb(re->main, (ID *)scene, BLI_CB_EVT_RENDER_PRE); + do_render_all_options(re); if(write_still && !G.afbreek) { @@ -2924,16 +2938,18 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr BKE_makepicstring(name, scene->r.pic, scene->r.cfra, scene->r.imtype, scene->r.scemode & R_EXTENSION, FALSE); /* reports only used for Movie */ - do_write_image_or_movie(re, scene, NULL, NULL, name); + do_write_image_or_movie(re, scene, NULL, name); } } + + BLI_exec_cb(re->main, (ID *)scene, BLI_CB_EVT_RENDER_POST); /* keep after file save */ } /* UGLY WARNING */ G.rendering= 0; } -static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, ReportList *reports, const char *name_override) +static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, const char *name_override) { char name[FILE_MAX]; RenderResult rres; @@ -2951,7 +2967,7 @@ static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, R dofree = 1; } RE_ResultGet32(re, (unsigned int *)rres.rect32); - ok= mh->append_movie(&re->r, scene->r.cfra, rres.rect32, rres.rectx, rres.recty, reports); + ok= mh->append_movie(&re->r, scene->r.cfra, rres.rect32, rres.rectx, rres.recty, re->reports); if(dofree) { MEM_freeN(rres.rect32); } @@ -2992,6 +3008,15 @@ static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, R } } + /* color -> greyscale */ + /* editing directly would alter the render view */ + if(scene->r.planes == 8) { + ImBuf *ibuf_bw= IMB_dupImBuf(ibuf); + IMB_color_to_bw(ibuf_bw); + IMB_freeImBuf(ibuf); + ibuf= ibuf_bw; + } + ok= BKE_write_ibuf_stamp(scene, camera, ibuf, name, scene->r.imtype, scene->r.subimtype, scene->r.quality); if(ok==0) { @@ -3024,7 +3049,7 @@ static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, R } /* saves images to disk */ -void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_override, unsigned int lay, int sfra, int efra, int tfra, ReportList *reports) +void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_override, unsigned int lay, int sfra, int efra, int tfra) { bMovieHandle *mh= BKE_get_movie_handle(scene->r.imtype); int cfrao= scene->r.cfra; @@ -3037,24 +3062,31 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */ /* is also set by caller renderwin.c */ G.rendering= 1; - + if(BKE_imtype_is_movie(scene->r.imtype)) - if(!mh->start_movie(scene, &re->r, re->rectx, re->recty, reports)) + if(!mh->start_movie(scene, &re->r, re->rectx, re->recty, re->reports)) G.afbreek= 1; if (mh->get_next_frame) { while (!(G.afbreek == 1)) { - int nf = mh->get_next_frame(&re->r, reports); + int nf = mh->get_next_frame(&re->r, re->reports); if (nf >= 0 && nf >= scene->r.sfra && nf <= scene->r.efra) { scene->r.cfra = re->r.cfra = nf; - + + BLI_exec_cb(re->main, (ID *)scene, BLI_CB_EVT_RENDER_PRE); + do_render_all_options(re); if(re->test_break(re->tbh) == 0) { - if(!do_write_image_or_movie(re, scene, mh, reports, NULL)) + if(!do_write_image_or_movie(re, scene, mh, NULL)) G.afbreek= 1; } - } else { + + if(G.afbreek == 0) { + BLI_exec_cb(re->main, (ID *)scene, BLI_CB_EVT_RENDER_POST); /* keep after file save */ + } + } + else { if(re->test_break(re->tbh)) G.afbreek= 1; } @@ -3101,12 +3133,16 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri } re->r.cfra= scene->r.cfra; /* weak.... */ + + /* run callbacs before rendering, before the scene is updated */ + BLI_exec_cb(re->main, (ID *)scene, BLI_CB_EVT_RENDER_PRE); + do_render_all_options(re); if(re->test_break(re->tbh) == 0) { if(!G.afbreek) - if(!do_write_image_or_movie(re, scene, mh, reports, NULL)) + if(!do_write_image_or_movie(re, scene, mh, NULL)) G.afbreek= 1; } else @@ -3122,6 +3158,10 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri break; } + + if(G.afbreek==0) { + BLI_exec_cb(re->main, (ID *)scene, BLI_CB_EVT_RENDER_POST); /* keep after file save */ + } } } @@ -3310,6 +3350,11 @@ void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char re->i.statstr= NULL; } +void RE_engine_report(RenderEngine *engine, int type, const char *msg) +{ + BKE_report(engine->re->reports, type, msg); +} + /* loads in image into a result, size must match * x/y offsets are only used on a partial copy when dimensions dont match */ void RE_layer_load_from_file(RenderLayer *layer, ReportList *reports, const char *filename, int x, int y) diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c index 2d42938f6ac..56a1c870904 100644 --- a/source/blender/render/intern/source/pixelshading.c +++ b/source/blender/render/intern/source/pixelshading.c @@ -502,21 +502,6 @@ int shadeHaloFloat(HaloRen *har, float *col, int zz, /* ------------------------------------------------------------------------- */ -static void fillBackgroundImage(float *collector, float fx, float fy) -{ - collector[0] = 0.0; - collector[1] = 0.0; - collector[2] = 0.0; - collector[3] = 0.0; - - if(R.backbuf) { - float dx= 1.0f/(float)R.winx; - float dy= 1.0f/(float)R.winy; - - image_sample(R.backbuf, fx*dx, fy*dy, dx, dy, collector); - } -} - /* Only view vector is important here. Result goes to colf[3] */ void shadeSkyView(float *colf, float *rco, float *view, float *dxyview, short thread) { @@ -626,18 +611,14 @@ void shadeSkyPixel(float *collector, float fx, float fy, short thread) float fac; - /* 1. Do a backbuffer image: */ - if(R.r.bufflag & 1) { - fillBackgroundImage(collector, fx, fy); - } - else if((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) { - /* 2. solid color */ + if((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) { + /* 1. solid color */ VECCOPY(collector, &R.wrld.horr); collector[3] = 0.0f; } else { - /* 3. */ + /* 2. */ /* This one true because of the context of this routine */ if(R.wrld.skytype & WO_SKYPAPER) { diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index d3d3e4d261c..b45528b96d9 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -362,10 +362,18 @@ static void accum_density(void *userdata, int index, float squared_dist) density = pdr->squared_radius; else if (pdr->falloff_type == TEX_PD_FALLOFF_ROOT) density = sqrt(dist); - else if (pdr->falloff_type == TEX_PD_FALLOFF_PARTICLE_AGE) - density = dist*MIN2(pdr->point_data[pdr->offset + index], 1.0f); - else if (pdr->falloff_type == TEX_PD_FALLOFF_PARTICLE_VEL) - density = dist*len_v3(pdr->point_data + index*3)*pdr->velscale; + else if (pdr->falloff_type == TEX_PD_FALLOFF_PARTICLE_AGE) { + if (pdr->point_data_used & POINT_DATA_LIFE) + density = dist*MIN2(pdr->point_data[pdr->offset + index], 1.0f); + else + density = dist; + } + else if (pdr->falloff_type == TEX_PD_FALLOFF_PARTICLE_VEL) { + if (pdr->point_data_used & POINT_DATA_VEL) + density = dist*len_v3(pdr->point_data + index*3)*pdr->velscale; + else + density = dist; + } if (pdr->density_curve && dist != 0.0f) { density = curvemapping_evaluateF(pdr->density_curve, 0, density/dist)*dist; diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index b57fe5a8c3b..34d3adcf15b 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -96,7 +96,7 @@ static void RE_rayobject_config_control(RayObject *r, Render *re) } } -RayObject* RE_rayobject_create(Render *re, int type, int size) +static RayObject* RE_rayobject_create(Render *re, int type, int size) { RayObject * res = NULL; @@ -1231,7 +1231,7 @@ static QMCSampler *get_thread_qmcsampler(Render *re, int thread, int type, int t return qsa; } -static void release_thread_qmcsampler(Render *re, int thread, QMCSampler *qsa) +static void release_thread_qmcsampler(Render *UNUSED(re), int UNUSED(thread), QMCSampler *qsa) { qsa->used= 0; } @@ -1679,7 +1679,7 @@ static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int /* not used, test function for ambient occlusion (yaf: pathlight) */ /* main problem; has to be called within shading loop, giving unwanted recursion */ -int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr) +static int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr) { static int counter=0, only_one= 0; extern float hashvectf[]; @@ -1729,7 +1729,7 @@ int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr) /* end warning! - Campbell */ shade_ray(&isec, &shi, &shr_t); - fac= isec.dist*isec.dist; + /* fac= isec.dist*isec.dist; */ fac= 1.0f; accum[0]+= fac*(shr_t.diff[0]+shr_t.spec[0]); accum[1]+= fac*(shr_t.diff[1]+shr_t.spec[1]); diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 5f5dab94ba3..5aad055a8f6 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -2118,7 +2118,8 @@ void do_material_tex(ShadeInput *shi) float fact, facm, factt, facmm, stencilTin=1.0; float texvec[3], dxt[3], dyt[3], tempvec[3], norvec[3], warpvec[3]={0.0f, 0.0f, 0.0f}, Tnor=1.0; int tex_nr, rgbnor= 0, warpdone=0; - int use_compat_bump, use_ntap_bump; + int use_compat_bump = 0, use_ntap_bump = 0; + int found_nmapping = 0; int iFirstTimeNMap=1; compatible_bump_init(&compat_bump); @@ -2192,6 +2193,7 @@ void do_material_tex(ShadeInput *shi) } } else if(mtex->texco==TEXCO_REFL) { + calc_R_ref(shi); co= shi->ref; dx= shi->dxref; dy= shi->dyref; } else if(mtex->texco==TEXCO_NORM) { @@ -2428,6 +2430,9 @@ void do_material_tex(ShadeInput *shi) /* we need to code blending modes for normals too once.. now 1 exception hardcoded */ if ((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP)) { + + found_nmapping = 1; + /* qdn: for normalmaps, to invert the normalmap vector, it is better to negate x & y instead of subtracting the vector as was done before */ if (norfac < 0.0f) { @@ -2509,9 +2514,6 @@ void do_material_tex(ShadeInput *shi) shi->orn[0]= -shi->vn[0]; shi->orn[1]= -shi->vn[1]; shi->orn[2]= -shi->vn[2]; - - /* reflection vector */ - calc_R_ref(shi); } } @@ -2622,6 +2624,12 @@ void do_material_tex(ShadeInput *shi) } } } + if ((use_compat_bump || use_ntap_bump || found_nmapping) && (shi->mat->mode & MA_TANGENT_V)!=0) { + const float fnegdot = -dot_v3v3(shi->vn, shi->tang); + // apply Gram-Schmidt projection + madd_v3_v3fl(shi->tang, shi->vn, fnegdot); + normalize_v3(shi->tang); + } } diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 7a34fc0af50..a7e19c8db4f 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -515,6 +515,14 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, *fp= (float)shi->obr->ob->index; } break; + case SCE_PASS_INDEXMA: + /* no filter */ + if(shi->vlr) { + fp= rpass->rect + offset; + if(*fp==0.0f) + *fp= (float)shi->mat->index; + } + break; case SCE_PASS_MIST: /* */ col= &shr->mist; @@ -619,6 +627,12 @@ static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult *fp= (float)shi->obr->ob->index; } break; + case SCE_PASS_INDEXMA: + if(shi->vlr) { + fp= rpass->rect + offset; + *fp= (float)shi->mat->index; + } + break; case SCE_PASS_MIST: fp= rpass->rect + offset; *fp= shr->mist; @@ -1956,40 +1970,6 @@ void add_halo_flare(Render *re) R.r.mode= mode; } -/* ************************* used for shaded view ************************ */ - -/* if *re, then initialize, otherwise execute */ -void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr) -{ - static VlakRen vlr; - static ObjectRen obr; - static ObjectInstanceRen obi; - - /* init */ - if(re) { - R= *re; - - /* fake render face */ - memset(&vlr, 0, sizeof(VlakRen)); - memset(&obr, 0, sizeof(ObjectRen)); - memset(&obi, 0, sizeof(ObjectInstanceRen)); - obr.lay= -1; - obi.obr= &obr; - - return; - } - shi->vlr= &vlr; - shi->obr= &obr; - shi->obi= &obi; - - if(shi->mat->nodetree && shi->mat->use_nodes) - ntreeShaderExecTree(shi->mat->nodetree, shi, shr); - else { - shade_input_init_material(shi); - shade_material_loop(shi, shr); - } -} - /* ************************* bake ************************ */ @@ -2018,75 +1998,7 @@ typedef struct BakeShade { short *do_update; } BakeShade; -/* bake uses a char mask to know what has been baked */ -#define BAKE_MASK_NULL 0 -#define BAKE_MASK_MARGIN 1 -#define BAKE_MASK_BAKED 2 -static void bake_mask_filter_extend( char *mask, int width, int height ) -{ - char *row1, *row2, *row3; - int rowlen, x, y; - char *temprect; - - rowlen= width; - - /* make a copy, to prevent flooding */ - temprect= MEM_dupallocN(mask); - - for(y=1; y<=height; y++) { - /* setup rows */ - row1= (char *)(temprect + (y-2)*rowlen); - row2= row1 + rowlen; - row3= row2 + rowlen; - if(y==1) - row1= row2; - else if(y==height) - row3= row2; - - for(x=0; x<rowlen; x++) { - if (mask[((y-1)*rowlen)+x]==0) { - if (*row1 || *row2 || *row3 || *(row1+1) || *(row3+1) ) { - mask[((y-1)*rowlen)+x] = BAKE_MASK_MARGIN; - } else if((x!=rowlen-1) && (*(row1+2) || *(row2+2) || *(row3+2)) ) { - mask[((y-1)*rowlen)+x] = BAKE_MASK_MARGIN; - } - } - - if(x!=0) { - row1++; row2++; row3++; - } - } - } - MEM_freeN(temprect); -} - -static void bake_mask_clear( ImBuf *ibuf, char *mask, char val ) -{ - int x,y; - if (ibuf->rect_float) { - for(x=0; x<ibuf->x; x++) { - for(y=0; y<ibuf->y; y++) { - if (mask[ibuf->x*y + x] == val) { - float *col= ibuf->rect_float + 4*(ibuf->x*y + x); - col[0] = col[1] = col[2] = col[3] = 0.0f; - } - } - } - - } else { - /* char buffer */ - for(x=0; x<ibuf->x; x++) { - for(y=0; y<ibuf->y; y++) { - if (mask[ibuf->x*y + x] == val) { - char *col= (char *)(ibuf->rect + ibuf->x*y + x); - col[0] = col[1] = col[2] = col[3] = 0; - } - } - } - } -} - -static void bake_set_shade_input(ObjectInstanceRen *obi, VlakRen *vlr, ShadeInput *shi, int quad, int isect, int x, int y, float u, float v) +static void bake_set_shade_input(ObjectInstanceRen *obi, VlakRen *vlr, ShadeInput *shi, int quad, int UNUSED(isect), int x, int y, float u, float v) { if(quad) shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3); @@ -2117,7 +2029,7 @@ static void bake_set_shade_input(ObjectInstanceRen *obi, VlakRen *vlr, ShadeInpu shi->view[2]= shi->vn[2]; } -static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int quad, int x, int y, float u, float v, float *tvn, float *ttang) +static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(quad), int x, int y, float UNUSED(u), float UNUSED(v), float *tvn, float *ttang) { BakeShade *bs= handle; ShadeSample *ssamp= &bs->ssamp; @@ -2143,7 +2055,9 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int quad, int shade_input_set_shade_texco(shi); - if(!ELEM3(bs->type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_SHADOW)) + /* only do AO for a full bake (and obviously AO bakes) + AO for light bakes is a leftover and might not be needed */ + if( ELEM3(bs->type, RE_BAKE_ALL, RE_BAKE_AO, RE_BAKE_LIGHT)) shade_samples_do_AO(ssamp); if(shi->mat->nodetree && shi->mat->use_nodes) { @@ -2206,6 +2120,42 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int quad, int VECCOPY(shr.combined, shr.shad); shr.alpha = shi->alpha; } + else if(bs->type==RE_BAKE_SPEC_COLOR) { + shr.combined[0]= shi->specr; + shr.combined[1]= shi->specg; + shr.combined[2]= shi->specb; + shr.alpha = 1.0f; + } + else if(bs->type==RE_BAKE_SPEC_INTENSITY) { + shr.combined[0]= + shr.combined[1]= + shr.combined[2]= shi->spec; + shr.alpha = 1.0f; + } + else if(bs->type==RE_BAKE_MIRROR_COLOR) { + shr.combined[0]= shi->mirr; + shr.combined[1]= shi->mirg; + shr.combined[2]= shi->mirb; + shr.alpha = 1.0f; + } + else if(bs->type==RE_BAKE_MIRROR_INTENSITY) { + shr.combined[0]= + shr.combined[1]= + shr.combined[2]= shi->ray_mirror; + shr.alpha = 1.0f; + } + else if(bs->type==RE_BAKE_ALPHA) { + shr.combined[0]= + shr.combined[1]= + shr.combined[2]= shi->alpha; + shr.alpha = 1.0f; + } + else if(bs->type==RE_BAKE_EMIT) { + shr.combined[0]= + shr.combined[1]= + shr.combined[2]= shi->emit; + shr.alpha = 1.0f; + } } if(bs->rect_float) { @@ -2243,11 +2193,11 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int quad, int } if (bs->rect_mask) { - bs->rect_mask[bs->rectx*y + x] = BAKE_MASK_BAKED; + bs->rect_mask[bs->rectx*y + x] = FILTER_MASK_USED; } } -static void bake_displacement(void *handle, ShadeInput *shi, float dist, int x, int y) +static void bake_displacement(void *handle, ShadeInput *UNUSED(shi), float dist, int x, int y) { BakeShade *bs= handle; float disp; @@ -2270,7 +2220,7 @@ static void bake_displacement(void *handle, ShadeInput *shi, float dist, int x, col[3]= 255; } if (bs->rect_mask) { - bs->rect_mask[bs->rectx*y + x] = BAKE_MASK_BAKED; + bs->rect_mask[bs->rectx*y + x] = FILTER_MASK_USED; } } @@ -2494,7 +2444,8 @@ static int get_next_bake_face(BakeShade *bs) if(tface && tface->tpage) { Image *ima= tface->tpage; ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); - float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f}; + const float vec_alpha[4]= {0.0f, 0.0f, 0.0f, 0.0f}; + const float vec_solid[4]= {0.0f, 0.0f, 0.0f, 1.0f}; if(ibuf==NULL) continue; @@ -2514,7 +2465,7 @@ static int get_next_bake_face(BakeShade *bs) imb_freerectImBuf(ibuf); /* clear image */ if(R.r.bake_flag & R_BAKE_CLEAR) - IMB_rectfill(ibuf, vec); + IMB_rectfill(ibuf, (ibuf->depth == 32) ? vec_alpha : vec_solid); /* might be read by UI to set active image for display */ R.bakebuf= ima; @@ -2619,6 +2570,28 @@ static void *do_bake_thread(void *bs_v) return NULL; } +void RE_bake_ibuf_filter(ImBuf *ibuf, char *mask, const int filter) +{ + /* must check before filtering */ + const short is_new_alpha= (ibuf->depth != 32) && BKE_alphatest_ibuf(ibuf); + + /* Margin */ + if(filter) { + IMB_filter_extend(ibuf, mask, filter); + } + + /* if the bake results in new alpha then change the image setting */ + if(is_new_alpha) { + ibuf->depth= 32; + } + else { + if(filter && ibuf->depth != 32) { + /* clear alpha added by filtering */ + IMB_rectfill_alpha(ibuf, 1.0f); + } + } +} + /* using object selection tags, the faces with UV maps get baked */ /* render should have been setup */ /* returns 0 if nothing was handled */ @@ -2705,36 +2678,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up if(!ibuf) continue; - if(re->r.bake_filter) { - if (usemask) { - /* extend the mask +2 pixels from the image, - * this is so colors dont blend in from outside */ - char *temprect; - - for(a=0; a<re->r.bake_filter; a++) - bake_mask_filter_extend((char *)ibuf->userdata, ibuf->x, ibuf->y); - - temprect = MEM_dupallocN(ibuf->userdata); - - /* expand twice to clear this many pixels, so they blend back in */ - bake_mask_filter_extend(temprect, ibuf->x, ibuf->y); - bake_mask_filter_extend(temprect, ibuf->x, ibuf->y); - - /* clear all pixels in the margin*/ - bake_mask_clear(ibuf, temprect, BAKE_MASK_MARGIN); - MEM_freeN(temprect); - } - - for(a=0; a<re->r.bake_filter; a++) { - /*the mask, ibuf->userdata - can be null, in this case only zero alpha is used */ - IMB_filter_extend(ibuf, (char *)ibuf->userdata); - } - - if (ibuf->userdata) { - MEM_freeN(ibuf->userdata); - ibuf->userdata= NULL; - } - } + RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, re->r.bake_filter); ibuf->userflags |= IB_BITMAPDIRTY; if (ibuf->rect_float) IMB_rect_from_float(ibuf); diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 74c99d1a92f..456162d2d30 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -446,7 +446,7 @@ VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr) return vlr1; } -void RE_vlakren_get_normal(Render *re, ObjectInstanceRen *obi, VlakRen *vlr, float *nor) +void RE_vlakren_get_normal(Render *UNUSED(re), ObjectInstanceRen *obi, VlakRen *vlr, float *nor) { float (*nmat)[3]= obi->nmat; @@ -782,7 +782,7 @@ void free_renderdata_vlaknodes(VlakTableNode *vlaknodes) MEM_freeN(vlaknodes); } -void free_renderdata_strandnodes(StrandTableNode *strandnodes) +static void free_renderdata_strandnodes(StrandTableNode *strandnodes) { int a; @@ -1238,7 +1238,7 @@ static int panotestclip(Render *re, int do_pano, float *v) - shadow buffering (shadbuf.c) */ -void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, float xoffs, int do_buckets) +void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, float xoffs, int UNUSED(do_buckets)) { ObjectRen *obr; HaloRen *har = NULL; diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index e575776ec79..eab66aaf2ec 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -303,7 +303,7 @@ void shade_input_set_triangle_i(ShadeInput *shi, ObjectInstanceRen *obi, VlakRen */ /* copy data from face to ShadeInput, scanline case */ -void shade_input_set_triangle(ShadeInput *shi, volatile int obi, volatile int facenr, int normal_flip) +void shade_input_set_triangle(ShadeInput *shi, volatile int obi, volatile int facenr, int UNUSED(normal_flip)) { if(facenr>0) { shi->obi= &R.objectinstance[obi]; @@ -543,11 +543,6 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert shi->orn[2]= -shi->vn[2]; } - if(texco & TEXCO_REFL) { - /* mirror reflection color textures (and envmap) */ - calc_R_ref(shi); /* wrong location for normal maps! XXXXXXXXXXXXXX */ - } - if(texco & TEXCO_STRESS) { /* not supported */ } @@ -633,14 +628,14 @@ void shade_input_calc_viewco(ShadeInput *shi, float x, float y, float z, float * dxco[0]= fx; dxco[1]= 0.0f; if(shi->facenor[2]!=0.0f) - dxco[2]= (shi->facenor[0]*fx)/shi->facenor[2]; + dxco[2]= -(shi->facenor[0]*fx)/shi->facenor[2]; else dxco[2]= 0.0f; dyco[0]= 0.0f; dyco[1]= fy; if(shi->facenor[2]!=0.0f) - dyco[2]= (shi->facenor[1]*fy)/shi->facenor[2]; + dyco[2]= -(shi->facenor[1]*fy)/shi->facenor[2]; else dyco[2]= 0.0f; @@ -776,7 +771,8 @@ void shade_input_set_uv(ShadeInput *shi) t00= v3[axis1]-v1[axis1]; t01= v3[axis2]-v1[axis2]; t10= v3[axis1]-v2[axis1]; t11= v3[axis2]-v2[axis2]; - detsh= 1.0f/(t00*t11-t10*t01); + detsh= (t00*t11-t10*t01); + detsh= (detsh != 0.0f)? 1.0f/detsh: 0.0f; t00*= detsh; t01*=detsh; t10*=detsh; t11*=detsh; @@ -1205,11 +1201,6 @@ void shade_input_set_shade_texco(ShadeInput *shi) shi->orn[2]= -shi->vn[2]; } - if(texco & TEXCO_REFL) { - /* mirror reflection color textures (and envmap) */ - calc_R_ref(shi); /* wrong location for normal maps! XXXXXXXXXXXXXX */ - } - if(texco & TEXCO_STRESS) { float *s1, *s2, *s3; @@ -1282,8 +1273,9 @@ void shade_input_set_shade_texco(ShadeInput *shi) s11= ho3[1]/ho3[3] - ho2[1]/ho2[3]; detsh= s00*s11-s10*s01; - s00/= detsh; s01/=detsh; - s10/=detsh; s11/=detsh; + detsh= (detsh != 0.0f)? 1.0f/detsh: 0.0f; + s00*= detsh; s01*=detsh; + s10*=detsh; s11*=detsh; /* recalc u and v again */ hox= x/Zmulx -1.0f; @@ -1465,7 +1457,7 @@ int shade_samples(ShadeSample *ssamp, PixStr *ps, int x, int y) shade_samples_do_AO(ssamp); /* if shade (all shadepinputs have same passflag) */ - if(ssamp->shi[0].passflag & ~(SCE_PASS_Z|SCE_PASS_INDEXOB)) { + if(ssamp->shi[0].passflag & ~(SCE_PASS_Z|SCE_PASS_INDEXOB|SCE_PASS_INDEXMA)) { for(samp=0; samp<ssamp->tot; samp++, shi++, shr++) { shade_input_set_shade_texco(shi); diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 5a5de938e43..7f921d21041 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -705,7 +705,7 @@ static float WardIso_Spec( float *n, float *l, float *v, float rms, int tangent) } /* cartoon render diffuse */ -static float Toon_Diff( float *n, float *l, float *v, float size, float smooth ) +static float Toon_Diff( float *n, float *l, float *UNUSED(v), float size, float smooth ) { float rslt, ang; @@ -806,7 +806,7 @@ static float Minnaert_Diff(float nl, float *n, float *v, float darkness) return i; } -static float Fresnel_Diff(float *vn, float *lv, float *view, float fac_i, float fac) +static float Fresnel_Diff(float *vn, float *lv, float *UNUSED(view), float fac_i, float fac) { return fresnel_fac(lv, vn, fac_i, fac); } diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index 12e85af7575..72cb35e7827 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -210,7 +210,7 @@ static void interpolate_vec4(float *v1, float *v2, float t, float negt, float *v v[3]= negt*v1[3] + t*v2[3]; } -void interpolate_shade_result(ShadeResult *shr1, ShadeResult *shr2, float t, ShadeResult *shr, int addpassflag) +static void interpolate_shade_result(ShadeResult *shr1, ShadeResult *shr2, float t, ShadeResult *shr, int addpassflag) { float negt= 1.0f - t; @@ -252,7 +252,7 @@ void interpolate_shade_result(ShadeResult *shr1, ShadeResult *shr2, float t, Sha } } -void strand_apply_shaderesult_alpha(ShadeResult *shr, float alpha) +static void strand_apply_shaderesult_alpha(ShadeResult *shr, float alpha) { if(alpha < 1.0f) { shr->combined[0] *= alpha; @@ -594,7 +594,7 @@ static void do_strand_fillac(void *handle, int x, int y, float u, float v, float } /* width is calculated in hoco space, to ensure strands are visible */ -static int strand_test_clip(float winmat[][4], ZSpan *zspan, float *bounds, float *co, float *zcomp, float widthx, float widthy) +static int strand_test_clip(float winmat[][4], ZSpan *UNUSED(zspan), float *bounds, float *co, float *zcomp, float widthx, float widthy) { float hoco[4]; int clipflag= 0; @@ -615,7 +615,7 @@ static int strand_test_clip(float winmat[][4], ZSpan *zspan, float *bounds, floa return clipflag; } -static void do_scanconvert_strand(Render *re, StrandPart *spart, ZSpan *zspan, float t, float dt, float *co1, float *co2, float *co3, float *co4, int sample) +static void do_scanconvert_strand(Render *UNUSED(re), StrandPart *spart, ZSpan *zspan, float t, float dt, float *co1, float *co2, float *co3, float *co4, int sample) { float jco1[3], jco2[3], jco3[3], jco4[3], jx, jy; @@ -778,7 +778,7 @@ void render_strand_segment(Render *re, float winmat[][4], StrandPart *spart, ZSp } /* render call to fill in strands */ -int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[][4], int winx, int winy, int sample, float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache) +int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int UNUSED(negzmask), float winmat[][4], int winx, int winy, int UNUSED(sample), float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache) { ObjectRen *obr; ObjectInstanceRen *obi; diff --git a/source/blender/render/intern/source/sunsky.c b/source/blender/render/intern/source/sunsky.c index 919c06d81f7..5877fa42292 100644 --- a/source/blender/render/intern/source/sunsky.c +++ b/source/blender/render/intern/source/sunsky.c @@ -113,7 +113,7 @@ static void DirectionToThetaPhi(float *toSun, float *theta, float *phi) * PerezFunction: * compute perez function value based on input paramters * */ -float PerezFunction(struct SunSky *sunsky, const float *lam, float theta, float gamma, float lvz) +static float PerezFunction(struct SunSky *sunsky, const float *lam, float theta, float gamma, float lvz) { float den, num; @@ -313,7 +313,7 @@ void GetSkyXYZRadiancef(struct SunSky* sunsky, const float varg[3], float color_ * turbidity: is atmosphere turbidity * fTau: contains computed attenuated sun light * */ -void ComputeAttenuatedSunlight(float theta, int turbidity, float fTau[3]) +static void ComputeAttenuatedSunlight(float theta, int turbidity, float fTau[3]) { float fBeta ; float fTauR, fTauA; @@ -460,7 +460,7 @@ void AtmospherePixleShader( struct SunSky* sunSky, float view[3], float s, float vec3opv(sunSky->atm_BetaRM, sunSky->atm_BetaRay, +, sunSky->atm_BetaMie); //e^(-(beta_1 + beta_2) * s) = E1 - vec3opf(E1, sunSky->atm_BetaRM, *, -s/log(2)); + vec3opf(E1, sunSky->atm_BetaRM, *, -s/M_LN2); E1[0] = exp(E1[0]); E1[1] = exp(E1[1]); E1[2] = exp(E1[2]); diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c index fc3280db771..faa915b7f6c 100644 --- a/source/blender/render/intern/source/volume_precache.c +++ b/source/blender/render/intern/source/volume_precache.c @@ -74,7 +74,7 @@ extern struct Render R; /* Recursive test for intersections, from a point inside the mesh, to outside * Number of intersections (depth) determine if a point is inside or outside the mesh */ -int intersect_outside_volume(RayObject *tree, Isect *isect, float *offset, int limit, int depth) +static int intersect_outside_volume(RayObject *tree, Isect *isect, float *offset, int limit, int depth) { if (limit == 0) return depth; @@ -96,7 +96,7 @@ int intersect_outside_volume(RayObject *tree, Isect *isect, float *offset, int l } /* Uses ray tracing to check if a point is inside or outside an ObjectInstanceRen */ -int point_inside_obi(RayObject *tree, ObjectInstanceRen *UNUSED(obi), float *co) +static int point_inside_obi(RayObject *tree, ObjectInstanceRen *UNUSED(obi), float *co) { Isect isect= {{0}}; float dir[3] = {0.0f,0.0f,1.0f}; @@ -350,7 +350,7 @@ static void ms_diffuse(float *x0, float *x, float diff, int *n) //n is the unpad } } -void multiple_scattering_diffusion(Render *re, VolumePrecache *vp, Material *ma) +static void multiple_scattering_diffusion(Render *re, VolumePrecache *vp, Material *ma) { const float diff = ma->vol.ms_diff * 0.001f; /* compensate for scaling for a nicer UI range */ const int simframes = (int)(ma->vol.ms_spread * (float)MAX3(vp->res[0], vp->res[1], vp->res[2])); @@ -523,7 +523,6 @@ static void *vol_precache_part(void *data) continue; } - /* this view coordinate is very wrong! */ copy_v3_v3(shi->view, cco); normalize_v3(shi->view); vol_get_scattering(shi, scatter_col, cco); @@ -538,7 +537,7 @@ static void *vol_precache_part(void *data) pa->done = 1; - return 0; + return NULL; } @@ -676,7 +675,7 @@ static int precache_resolution(Render *re, VolumePrecache *vp, ObjectInstanceRen * in camera space, aligned with the ObjectRen's bounding box. * Resolution is defined by the user. */ -void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *obi, Material *ma) +static void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *obi, Material *ma) { VolumePrecache *vp; VolPrecachePart *nextpa, *pa; @@ -709,9 +708,8 @@ void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *obi, Mat vp->data_r = MEM_callocN(sizeof(float)*vp->res[0]*vp->res[1]*vp->res[2], "volume light cache data red channel"); vp->data_g = MEM_callocN(sizeof(float)*vp->res[0]*vp->res[1]*vp->res[2], "volume light cache data green channel"); vp->data_b = MEM_callocN(sizeof(float)*vp->res[0]*vp->res[1]*vp->res[2], "volume light cache data blue channel"); - if (vp->data_r==0 || vp->data_g==0 || vp->data_b==0) { + if (vp->data_r==NULL || vp->data_g==NULL || vp->data_b==NULL) { MEM_freeN(vp); - vp = NULL; return; } diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index dde9dbb8485..359002d05ae 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -305,7 +305,7 @@ float vol_get_density(struct ShadeInput *shi, float *co) /* Color of light that gets scattered out by the volume */ /* Uses same physically based scattering parameter as in transmission calculations, * along with artificial reflection scale/reflection color tint */ -void vol_get_reflection_color(ShadeInput *shi, float *ref_col, float *co) +static void vol_get_reflection_color(ShadeInput *shi, float *ref_col, float *co) { float scatter = shi->mat->vol.scattering; float reflection= shi->mat->vol.reflection; @@ -325,7 +325,7 @@ void vol_get_reflection_color(ShadeInput *shi, float *ref_col, float *co) /* compute emission component, amount of radiance to add per segment * can be textured with 'emit' */ -void vol_get_emission(ShadeInput *shi, float *emission_col, float *co) +static void vol_get_emission(ShadeInput *shi, float *emission_col, float *co) { float emission = shi->mat->vol.emission; VECCOPY(emission_col, shi->mat->vol.emission_col); @@ -343,7 +343,7 @@ void vol_get_emission(ShadeInput *shi, float *emission_col, float *co) * This can possibly use a specific scattering color, * and absorption multiplier factor too, but these parameters are left out for simplicity. * It's easy enough to get a good wide range of results with just these two parameters. */ -void vol_get_sigma_t(ShadeInput *shi, float *sigma_t, float *co) +static void vol_get_sigma_t(ShadeInput *shi, float *sigma_t, float *co) { /* technically absorption, but named transmission color * since it describes the effect of the coloring *after* absorption */ @@ -361,7 +361,7 @@ void vol_get_sigma_t(ShadeInput *shi, float *sigma_t, float *co) /* phase function - determines in which directions the light * is scattered in the volume relative to incoming direction * and view direction */ -float vol_get_phasefunc(ShadeInput *UNUSED(shi), float g, float *w, float *wp) +static float vol_get_phasefunc(ShadeInput *UNUSED(shi), float g, float *w, float *wp) { const float normalize = 0.25f; // = 1.f/4.f = M_PI/(4.f*M_PI) @@ -408,7 +408,7 @@ float vol_get_phasefunc(ShadeInput *UNUSED(shi), float g, float *w, float *wp) } /* Compute transmittance = e^(-attenuation) */ -void vol_get_transmittance_seg(ShadeInput *shi, float *tr, float stepsize, float *co, float density) +static void vol_get_transmittance_seg(ShadeInput *shi, float *tr, float stepsize, float *co, float density) { /* input density = density at co */ float tau[3] = {0.f, 0.f, 0.f}; @@ -464,7 +464,7 @@ static void vol_get_transmittance(ShadeInput *shi, float *tr, float *co, float * tr[2] = expf(-tau[2]); } -void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *lacol) +static void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *lacol) { float visifac, lv[3], lampdist; float tr[3]={1.0,1.0,1.0}; @@ -534,6 +534,7 @@ void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float * if (luminance(lacol) < 0.001f) return; + normalize_v3(lv); p = vol_get_phasefunc(shi, shi->mat->vol.asymmetry, shi->view, lv); /* physically based scattering with non-physically based RGB gain */ @@ -605,7 +606,7 @@ static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float for (; t0 < t1; pt0 = t0, t0 += stepsize) { const float density = vol_get_density(shi, p); - if (density > 0.01f) { + if (density > 0.00001f) { float scatter_col[3] = {0.f, 0.f, 0.f}, emit_col[3]; const float stepd = (t0 - pt0) * density; diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c index b8cb5c21337..232f7fdeede 100644 --- a/source/blender/render/intern/source/voxeldata.c +++ b/source/blender/render/intern/source/voxeldata.c @@ -220,6 +220,7 @@ static int read_voxeldata_header(FILE *fp, struct VoxelData *vd) static void init_frame_smoke(VoxelData *vd, float cfra) { +#ifdef WITH_SMOKE Object *ob; ModifierData *md; @@ -300,7 +301,13 @@ static void init_frame_smoke(VoxelData *vd, float cfra) } vd->ok = 1; - return; + +#else // WITH_SMOKE + (void)vd; + (void)cfra; + + vd->dataset= NULL; +#endif } static void cache_voxeldata(struct Render *re, Tex *tex) diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 174b1378f67..13d9ead79e8 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -715,7 +715,7 @@ static void zbufline(ZSpan *zspan, int obi, int zvlnr, float *vec1, float *vec2) } } -static void zbufline_onlyZ(ZSpan *zspan, int obi, int zvlnr, float *vec1, float *vec2) +static void zbufline_onlyZ(ZSpan *zspan, int UNUSED(obi), int UNUSED(zvlnr), float *vec1, float *vec2) { int *rectz, *rectz1= NULL; int start, end, x, y, oldx, oldy, ofs; @@ -1287,7 +1287,7 @@ static void zbuffillGL4(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v2, */ /* now: filling two Z values, the closest and 2nd closest */ -static void zbuffillGL_onlyZ(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v2, float *v3, float *v4) +static void zbuffillGL_onlyZ(ZSpan *zspan, int UNUSED(obi), int UNUSED(zvlnr), float *v1, float *v2, float *v3, float *v4) { double zxd, zyd, zy0, zverg; float x0,y0,z0; @@ -3236,7 +3236,7 @@ static void copyto_abufz(RenderPart *pa, int *arectz, int *rectmask, int sample) * Do accumulation z buffering. */ -static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[][4], int winx, int winy, int samples, float (*jit)[2], float clipcrop, int shadow) +static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[][4], int winx, int winy, int samples, float (*jit)[2], float UNUSED(clipcrop), int shadow) { ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE]; ZSpan zspans[16], *zspan; /* MAX_OSA */ @@ -3497,7 +3497,7 @@ static void add_transp_obindex(RenderLayer *rl, int offset, Object *ob) RenderPass *rpass; for(rpass= rl->passes.first; rpass; rpass= rpass->next) { - if(rpass->passtype == SCE_PASS_INDEXOB) { + if(rpass->passtype == SCE_PASS_INDEXOB||rpass->passtype == SCE_PASS_INDEXMA) { float *fp= rpass->rect + offset; *fp= (float)ob->index; break; @@ -3692,7 +3692,7 @@ static int vergzvlak(const void *a1, const void *a2) return 0; } -static void shade_strand_samples(StrandShadeCache *cache, ShadeSample *ssamp, int x, int y, ZTranspRow *row, int addpassflag) +static void shade_strand_samples(StrandShadeCache *cache, ShadeSample *ssamp, int UNUSED(x), int UNUSED(y), ZTranspRow *row, int addpassflag) { StrandSegment sseg; StrandVert *svert; @@ -3820,7 +3820,7 @@ static int shade_tra_samples(ShadeSample *ssamp, StrandShadeCache *cache, int x, shade_samples_do_AO(ssamp); /* if shade (all shadepinputs have same passflag) */ - if(shi->passflag & ~(SCE_PASS_Z|SCE_PASS_INDEXOB)) { + if(shi->passflag & ~(SCE_PASS_Z|SCE_PASS_INDEXOB|SCE_PASS_INDEXMA)) { for(samp=0; samp<ssamp->tot; samp++, shi++, shr++) { shade_input_set_shade_texco(shi); shade_input_do_shade(shi, shr); @@ -3941,7 +3941,7 @@ static void reset_sky_speedvectors(RenderPart *pa, RenderLayer *rl, float *rectf /* main render call to do the z-transparent layer */ /* returns a mask, only if a) transp rendered and b) solid was rendered */ -unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pass, ListBase *psmlist) +unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pass, ListBase *UNUSED(psmlist)) { RenderResult *rr= pa->result; ShadeSample ssamp; @@ -4115,7 +4115,14 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas add_transp_obindex(rlpp[a], od, obr->ob); } } - + if(addpassflag & SCE_PASS_INDEXMA) { + ObjectRen *obr= R.objectinstance[zrow[totface-1].obi].obr; + if(obr->ob) { + for(a= 0; a<totfullsample; a++) + add_transp_obindex(rlpp[a], od, obr->ob); + } + } + /* for each mask-sample we alpha-under colors. then in end it's added using filter */ memset(samp_shr, 0, sizeof(ShadeResult)*osa); for(a=0; a<osa; a++) { |