Fix T37675: blender internal viewport render not updating properly with volumes.

This commit is contained in:
Brecht Van Lommel 2013-12-18 15:41:28 +01:00
parent 8106444756
commit 15927e05e4
Notes: blender-bot 2023-02-14 11:32:10 +01:00
Referenced by issue #37675, BI viewport render gives incorrect result with volumes
6 changed files with 72 additions and 53 deletions

View File

@ -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);

View File

@ -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 */

View File

@ -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) */

View File

@ -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];

View File

@ -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 */

View File

@ -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 {