diff options
author | Janne Karhu <jhkarh@gmail.com> | 2011-02-28 18:42:15 +0300 |
---|---|---|
committer | Janne Karhu <jhkarh@gmail.com> | 2011-02-28 18:42:15 +0300 |
commit | 506e8aa43786f80c60979fb53ba38288cfe193ad (patch) | |
tree | 02b541af0d65ffa69e97146b0b016b9cf0d6e9f8 /source/blender/render | |
parent | 13b617c78fb2e81b805d6f84b05a68ad951bc4ce (diff) |
Bug fix: Render and 3d view conflict over ob->imat
* For rendering every object's inverse matrix "ob->imat" needs to
be in render view coordinates, but for drawing in 3d view it needs
to be in global coordinates. Originally (way back in historical
times) ob->imat was only used for rendering, but over the years
other uses came up too. Before 2.5 this wasn't a problem as
rendering was a totally blocking operation, but with the new
"interactive ui while rendering" the problems started. Basically
any update that redrew the 3d view while rendering (like rotating
the scene with mouse) updated the inverse matrix into global
coordinates thus invalidating it for the render, leading to all
kinds of strange discontinuities with textures and volumetrics.
* Problems were very easy to achieve using orco/object coordinates
for pretty much any textures (bump, point density, volume, sky),
for examples see bug reports 24906 and 25229. Render baking normals
in object coordinates was wrong most of the time too.
* Now there is a separate inverse matrix ob->imat_ren that's
calculated at the beginning of rendering and is used in all places
inside render code where it's needed. This way the original ob->imat
can change at will during rendering without causing problems.
Diffstat (limited to 'source/blender/render')
4 files changed, 19 insertions, 37 deletions
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 5ecb62130f7..fbc23cbb457 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -4810,7 +4810,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp ObjectInstanceRen *obi; Scene *sce_iter; float mat[4][4]; - int lay, vectorlay, redoimat= 0; + int lay, vectorlay; /* for duplis we need the Object texture mapping to work as if * untransformed, set_dupli_tex_mat sets the matrix to allow that @@ -4821,7 +4821,8 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp ob= base->object; /* imat objects has to be done here, since displace can have texture using Object map-input */ mul_m4_m4m4(mat, ob->obmat, re->viewmat); - invert_m4_m4(ob->imat, mat); + invert_m4_m4(ob->imat_ren, mat); + copy_m4_m4(ob->imat, ob->imat_ren); /* each object should only be rendered once */ ob->flag &= ~OB_DONE; ob->transflag &= ~OB_RENDER_DUPLI; @@ -4855,8 +4856,6 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp DupliObject *dob; ListBase *lb; - redoimat= 1; - /* create list of duplis generated by this object, particle * system need to have render settings set for dupli particles */ dupli_render_particle_set(re, ob, timeoffset, 0, 1); @@ -4968,15 +4967,6 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp for(group= re->main->group.first; group; group=group->id.next) add_group_render_dupli_obs(re, group, nolamps, onlyselected, actob, timeoffset, renderlay, 0); - /* imat objects has to be done again, since groups can mess it up */ - if(redoimat) { - for(SETLOOPER(re->scene, sce_iter, base)) { - ob= base->object; - mul_m4_m4m4(mat, ob->obmat, re->viewmat); - invert_m4_m4(ob->imat, mat); - } - } - if(!re->test_break(re->tbh)) RE_makeRenderInstances(re); } diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 497fa6b0fcd..acc69680487 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -1830,8 +1830,8 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, idv = (dv < 1e-5f) ? bf : (bf/dv); if ((mtex->texco == TEXCO_ORCO) && shi->obr && shi->obr->ob) { - mul_mat3_m4_v3(shi->obr->ob->imat, tu); - mul_mat3_m4_v3(shi->obr->ob->imat, tv); + mul_mat3_m4_v3(shi->obr->ob->imat_ren, tu); + mul_mat3_m4_v3(shi->obr->ob->imat_ren, tv); normalize_v3(tu); normalize_v3(tv); } @@ -1840,8 +1840,8 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, mul_mat3_m4_v3(R.viewinv, tv); } else if (mtex->texco == TEXCO_OBJECT && mtex->object) { - mul_mat3_m4_v3(mtex->object->imat, tu); - mul_mat3_m4_v3(mtex->object->imat, tv); + mul_mat3_m4_v3(mtex->object->imat_ren, tu); + mul_mat3_m4_v3(mtex->object->imat_ren, tv); normalize_v3(tu); normalize_v3(tv); } @@ -2177,12 +2177,12 @@ void do_material_tex(ShadeInput *shi) if(mtex->texflag & MTEX_OB_DUPLI_ORIG) if(shi->obi && shi->obi->duplitexmat) mul_m4_v3(shi->obi->duplitexmat, tempvec); - mul_m4_v3(ob->imat, tempvec); + mul_m4_v3(ob->imat_ren, tempvec); if(shi->osatex) { VECCOPY(dxt, shi->dxco); VECCOPY(dyt, shi->dyco); - mul_mat3_m4_v3(ob->imat, dxt); - mul_mat3_m4_v3(ob->imat, dyt); + mul_mat3_m4_v3(ob->imat_ren, dxt); + mul_mat3_m4_v3(ob->imat_ren, dyt); } } else { @@ -2653,7 +2653,7 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa if(shi->obi && shi->obi->duplitexmat) mul_m4_v3(shi->obi->duplitexmat, co); } - mul_m4_v3(ob->imat, co); + mul_m4_v3(ob->imat_ren, co); } } /* not really orco, but 'local' */ @@ -2665,7 +2665,7 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa else { Object *ob= shi->obi->ob; VECCOPY(co, xyz); - mul_m4_v3(ob->imat, co); + mul_m4_v3(ob->imat_ren, co); } } else if(mtex->texco==TEXCO_GLOB) { @@ -3016,7 +3016,7 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f case TEXCO_OBJECT: if(mtex->object) { VECCOPY(tempvec, lo); - mul_m4_v3(mtex->object->imat, tempvec); + mul_m4_v3(mtex->object->imat_ren, tempvec); co= tempvec; } break; @@ -3165,12 +3165,12 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int ef dx= dxt; dy= dyt; VECCOPY(tempvec, shi->co); - mul_m4_v3(ob->imat, tempvec); + mul_m4_v3(ob->imat_ren, tempvec); if(shi->osatex) { VECCOPY(dxt, shi->dxco); VECCOPY(dyt, shi->dyco); - mul_mat3_m4_v3(ob->imat, dxt); - mul_mat3_m4_v3(ob->imat, dyt); + mul_mat3_m4_v3(ob->imat_ren, dxt); + mul_mat3_m4_v3(ob->imat_ren, dyt); } } else { diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index bd904c2337f..b30e4241c06 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -2179,7 +2179,7 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int quad, int mul_m3_v3(imat, nor); } else if(R.r.bake_normal_space == R_BAKE_SPACE_OBJECT) - mul_mat3_m4_v3(ob->imat, nor); /* ob->imat includes viewinv! */ + mul_mat3_m4_v3(ob->imat_ren, nor); /* ob->imat_ren includes viewinv! */ else if(R.r.bake_normal_space == R_BAKE_SPACE_WORLD) mul_mat3_m4_v3(R.viewinv, nor); diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 99fe20a729b..74c99d1a92f 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -1129,16 +1129,8 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater ; } else if(mtex->texco & TEXCO_OBJECT) { - if(mtex->object){ - float imat[4][4]; - /* imat should really be cached somewhere before this */ - invert_m4_m4(imat,mtex->object->obmat); - mul_m4_v3(imat,texvec); - } - /* texvec[0]+= imatbase->ivec[0]; */ - /* texvec[1]+= imatbase->ivec[1]; */ - /* texvec[2]+= imatbase->ivec[2]; */ - /* mul_m3_v3(imatbase->imat, texvec); */ + if(mtex->object) + mul_m4_v3(mtex->object->imat_ren,texvec); } else if(mtex->texco & TEXCO_GLOB){ VECCOPY(texvec,vec); |