diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2013-12-18 18:41:28 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2013-12-18 18:46:30 +0400 |
commit | 15927e05e4f13eb4bb23e82c378a4d0de91456b4 (patch) | |
tree | 377f015555b72b30a63f2f0a39e07548f38f8774 /source/blender/render/intern | |
parent | 81064447560cb1481b4094a4a5faa8cee2fe53a7 (diff) |
Fix T37675: blender internal viewport render not updating properly with volumes.
Diffstat (limited to 'source/blender/render/intern')
6 files changed, 72 insertions, 53 deletions
diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h index 9e48299ed9a..891505dd3a8 100644 --- a/source/blender/render/intern/include/renderdatabase.h +++ b/source/blender/render/intern/include/renderdatabase.h @@ -47,6 +47,7 @@ struct StrandBuffer; struct StrandRen; struct ObjectInstanceRen; struct RadFace; +struct Isect; #define RE_QUAD_MASK 0x7FFFFFF #define RE_QUAD_OFFS 0x8000000 @@ -113,6 +114,11 @@ struct ObjectRen *RE_addRenderObject(struct Render *re, struct Object *ob, struc struct ObjectInstanceRen *RE_addRenderInstance(struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, int index, int psysindex, float mat[4][4], int lay); void RE_makeRenderInstances(struct Render *re); +void RE_instance_rotate_ray_start(struct ObjectInstanceRen *obi, struct Isect *is); +void RE_instance_rotate_ray_dir(struct ObjectInstanceRen *obi, struct Isect *is); +void RE_instance_rotate_ray(struct ObjectInstanceRen *obi, struct Isect *is); +void RE_instance_rotate_ray_restore(struct ObjectInstanceRen *obi, struct Isect *is); + float *RE_vertren_get_stress(struct ObjectRen *obr, struct VertRen *ver, int verify); float *RE_vertren_get_rad(struct ObjectRen *obr, struct VertRen *ver, int verify); float *RE_vertren_get_strand(struct ObjectRen *obr, struct VertRen *ver, int verify); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 52030fb2d86..1f3e961c151 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -5268,6 +5268,8 @@ void RE_DataBase_IncrementalView(Render *re, float viewmat[4][4], int restore) copy_m4_m4(re->viewmat, viewmat); invert_m4_m4(re->viewinv, re->viewmat); + init_camera_inside_volumes(re); + env_rotate_scene(re, tmat, !restore); /* SSS points distribution depends on view */ diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 90ae39ee767..17e438599c1 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -499,36 +499,6 @@ static void shade_ray_set_derivative(ShadeInput *shi) } -/* four functions to facilitate envmap rotation for raytrace */ -static void ray_env_rotate_start(Isect *is, float imat[4][4]) -{ - copy_v3_v3(is->origstart, is->start); - mul_m4_v3(imat, is->start); -} - -static void ray_env_rotate_dir(Isect *is, float imat[4][4]) -{ - float end[3]; - - copy_v3_v3(is->origdir, is->dir); - add_v3_v3v3(end, is->origstart, is->dir); - - mul_m4_v3(imat, end); - sub_v3_v3v3(is->dir, end, is->start); -} - -static void ray_env_rotate(Isect *is, float imat[4][4]) -{ - ray_env_rotate_start(is, imat); - ray_env_rotate_dir(is, imat); -} - -static void ray_env_rotate_restore(Isect *is) -{ - copy_v3_v3(is->start, is->origstart); - copy_v3_v3(is->dir, is->origdir); -} - /* main ray shader */ void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr) { @@ -757,15 +727,13 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, con RE_RC_INIT(isec, shi); /* database is in original view, obi->imat transforms current position back to original */ - if (origshi->obi->flag & R_ENV_TRANSFORMED) - ray_env_rotate(&isec, origshi->obi->imat); + RE_instance_rotate_ray(origshi->obi, &isec); if (RE_rayobject_raycast(R.raytree, &isec)) { ShadeResult shr= {{0}}; float d= 1.0f; - if (origshi->obi->flag & R_ENV_TRANSFORMED) - ray_env_rotate_restore(&isec); + RE_instance_rotate_ray_restore(origshi->obi, &isec); /* for as long we don't have proper dx/dy transform for rays we copy over original */ copy_v3_v3(shi.dxco, origshi->dxco); @@ -1667,8 +1635,7 @@ static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int shi.lay= origshi->lay; shi.nodes= origshi->nodes; - if (origshi->obi->flag & R_ENV_TRANSFORMED) - ray_env_rotate_restore(is); + RE_instance_rotate_ray_restore(origshi->obi, is); shade_ray(is, &shi, &shr); if (shi.mat->material_type == MA_TYPE_SURFACE) { @@ -1887,8 +1854,7 @@ static void ray_ao_qmc(ShadeInput *shi, float ao[3], float env[3]) copy_v3_v3(isec.start, shi->co); - if (shi->obi->flag & R_ENV_TRANSFORMED) - ray_env_rotate_start(&isec, shi->obi->imat); + RE_instance_rotate_ray_start(shi->obi, &isec); RE_rayobject_hint_bb(R.raytree, &point_hint, isec.start, isec.start); isec.hint = &point_hint; @@ -1948,8 +1914,7 @@ static void ray_ao_qmc(ShadeInput *shi, float ao[3], float env[3]) isec.dir[2] = -dir[2]; isec.dist = maxdist; - if (shi->obi->flag & R_ENV_TRANSFORMED) - ray_env_rotate_dir(&isec, shi->obi->imat); + RE_instance_rotate_ray_dir(shi->obi, &isec); prev = fac; @@ -2033,8 +1998,7 @@ static void ray_ao_spheresamp(ShadeInput *shi, float ao[3], float env[3]) isec.lay= -1; copy_v3_v3(isec.start, shi->co); - if (shi->obi->flag & R_ENV_TRANSFORMED) - ray_env_rotate_start(&isec, shi->obi->imat); + RE_instance_rotate_ray_start(shi->obi, &isec); RE_rayobject_hint_bb(R.raytree, &point_hint, isec.start, isec.start); isec.hint = &point_hint; @@ -2093,8 +2057,7 @@ static void ray_ao_spheresamp(ShadeInput *shi, float ao[3], float env[3]) isec.dir[2] = -vec[2]; isec.dist = maxdist; - if (shi->obi->flag & R_ENV_TRANSFORMED) - ray_env_rotate_dir(&isec, shi->obi->imat); + RE_instance_rotate_ray_dir(shi->obi, &isec); /* do the trace */ if (RE_rayobject_raycast(R.raytree, &isec)) { @@ -2320,8 +2283,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, const float lampco[3], sub_v3_v3v3(isec->dir, end, start); isec->dist = normalize_v3(isec->dir); - if (shi->obi->flag & R_ENV_TRANSFORMED) - ray_env_rotate(isec, shi->obi->imat); + RE_instance_rotate_ray(shi->obi, isec); /* trace the ray */ if (isec->mode==RE_RAY_SHADOW_TRA) { @@ -2399,8 +2361,7 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, const float lampco[ else if (a==9) mask |= (mask>>9); copy_v3_v3(isec->start, shi->co); - if (shi->obi->flag & R_ENV_TRANSFORMED) - ray_env_rotate_start(isec, shi->obi->imat); + RE_instance_rotate_ray_start(shi->obi, isec); isec->orig.ob = shi->obi; isec->orig.face = shi->vlr; @@ -2428,8 +2389,7 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, const float lampco[ isec->dir[1] = vec[1]+lampco[1]-isec->start[1]; isec->dir[2] = vec[2]+lampco[2]-isec->start[2]; - if (shi->obi->flag & R_ENV_TRANSFORMED) - ray_env_rotate_dir(isec, shi->obi->imat); + RE_instance_rotate_ray_dir(shi->obi, isec); isec->dist = 1.0f; isec->check = RE_CHECK_VLR_RENDER; @@ -2530,8 +2490,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float shadfac[4]) sub_v3_v3v3(isec.dir, lampco, isec.start); isec.dist = normalize_v3(isec.dir); - if (shi->obi->flag & R_ENV_TRANSFORMED) - ray_env_rotate(&isec, shi->obi->imat); + RE_instance_rotate_ray(shi->obi, &isec); if (isec.mode==RE_RAY_SHADOW_TRA) { /* isec.col is like shadfac, so defines amount of light (0.0 is full shadow) */ diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 8169250f74f..9a1ee91d1f0 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -80,6 +80,7 @@ #include "RE_render_ext.h" /* externtex */ +#include "rayintersection.h" #include "rayobject.h" #include "renderpipeline.h" #include "render_types.h" @@ -1419,6 +1420,42 @@ void RE_makeRenderInstances(Render *re) re->instancetable= newlist; } +/* four functions to facilitate envmap rotation for raytrace */ +void RE_instance_rotate_ray_start(ObjectInstanceRen *obi, Isect *is) +{ + if (obi && (obi->flag & R_ENV_TRANSFORMED)) { + copy_v3_v3(is->origstart, is->start); + mul_m4_v3(obi->imat, is->start); + } +} + +void RE_instance_rotate_ray_dir(ObjectInstanceRen *obi, Isect *is) +{ + if (obi && (obi->flag & R_ENV_TRANSFORMED)) { + float end[3]; + + copy_v3_v3(is->origdir, is->dir); + add_v3_v3v3(end, is->origstart, is->dir); + + mul_m4_v3(obi->imat, end); + sub_v3_v3v3(is->dir, end, is->start); + } +} + +void RE_instance_rotate_ray(ObjectInstanceRen *obi, Isect *is) +{ + RE_instance_rotate_ray_start(obi, is); + RE_instance_rotate_ray_dir(obi, is); +} + +void RE_instance_rotate_ray_restore(ObjectInstanceRen *obi, Isect *is) +{ + if (obi && (obi->flag & R_ENV_TRANSFORMED)) { + copy_v3_v3(is->start, is->origstart); + copy_v3_v3(is->dir, is->origdir); + } +} + int clip_render_object(float boundbox[2][3], float bounds[4], float winmat[4][4]) { float mat[4][4], vec[4]; diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c index e5e3aff573d..6cf83d0508f 100644 --- a/source/blender/render/intern/source/volume_precache.c +++ b/source/blender/render/intern/source/volume_precache.c @@ -95,7 +95,7 @@ static int intersect_outside_volume(RayObject *tree, Isect *isect, float *offset } /* Uses ray tracing to check if a point is inside or outside an ObjectInstanceRen */ -static int point_inside_obi(RayObject *tree, ObjectInstanceRen *UNUSED(obi), const float co[3]) +static int point_inside_obi(RayObject *tree, ObjectInstanceRen *obi, const float co[3]) { Isect isect= {{0}}; float dir[3] = {0.0f, 0.0f, 1.0f}; @@ -112,7 +112,9 @@ static int point_inside_obi(RayObject *tree, ObjectInstanceRen *UNUSED(obi), con isect.orig.face= NULL; isect.orig.ob = NULL; + RE_instance_rotate_ray(obi, &isect); final_depth = intersect_outside_volume(tree, &isect, dir, limit, depth); + RE_instance_rotate_ray_restore(obi, &isect); /* even number of intersections: point is outside * odd number: point is inside */ diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index 3915d6bdd4b..e1f616e621a 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -56,6 +56,7 @@ #include "pixelshading.h" #include "rayintersection.h" #include "rayobject.h" +#include "renderdatabase.h" #include "shading.h" #include "shadbuf.h" #include "texture.h" @@ -107,7 +108,11 @@ static float vol_get_shadow(ShadeInput *shi, LampRen *lar, const float co[3]) is.orig.face = NULL; is.last_hit = lar->last_hit[shi->thread]; + RE_instance_rotate_ray(shi->obi, &is); + if (RE_rayobject_raycast(R.raytree, &is)) { + RE_instance_rotate_ray_restore(shi->obi, &is); + visibility = 0.f; } @@ -137,8 +142,12 @@ static int vol_get_bounds(ShadeInput *shi, const float co[3], const float vec[3] isect->orig.face = NULL; isect->orig.ob = NULL; } + + RE_instance_rotate_ray(shi->obi, isect); if (RE_rayobject_raycast(R.raytree, isect)) { + RE_instance_rotate_ray_restore(shi->obi, isect); + hitco[0] = isect->start[0] + isect->dist * isect->dir[0]; hitco[1] = isect->start[1] + isect->dist * isect->dir[1]; hitco[2] = isect->start[2] + isect->dist * isect->dir[2]; @@ -199,7 +208,11 @@ static void vol_trace_behind(ShadeInput *shi, VlakRen *vlr, const float co[3], f isect.lay = -1; /* check to see if there's anything behind the volume, otherwise shade the sky */ + RE_instance_rotate_ray(shi->obi, &isect); + if (RE_rayobject_raycast(R.raytree, &isect)) { + RE_instance_rotate_ray_restore(shi->obi, &isect); + shade_intersection(shi, col_r, &isect); } else { |