Fix T37675: blender internal viewport render not updating properly with volumes.
This commit is contained in:
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
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue