Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2013-05-17 15:13:46 +0400
committerTon Roosendaal <ton@blender.org>2013-05-17 15:13:46 +0400
commit7b2172cb0b4afaada3f59f90f694847cfc61c43d (patch)
tree439fc1413791498022c04b310deebf78c5689902 /source/blender/render
parenta4e9edb6743769bd9f8fd3e24bd11fd1878d510a (diff)
3D Viewport rendering (Blender Internal)
Added incremental re-render on view changes. That means all data preprocessing only needs to be done once on view changes, quite faster that way. Also fixed a bug in raytracing strands with soft shadows, was wrongly changing coordinates in a static array. Note: proper signals for re-renders is still on the todo. Many button options don't signal a re-render yet. Work around: press G+ESC for quick full renders.
Diffstat (limited to 'source/blender/render')
-rw-r--r--source/blender/render/intern/include/envmap.h2
-rw-r--r--source/blender/render/intern/include/rayintersection.h4
-rw-r--r--source/blender/render/intern/include/renderdatabase.h3
-rw-r--r--source/blender/render/intern/source/convertblender.c2
-rw-r--r--source/blender/render/intern/source/envmap.c80
-rw-r--r--source/blender/render/intern/source/rayshade.c210
6 files changed, 142 insertions, 159 deletions
diff --git a/source/blender/render/intern/include/envmap.h b/source/blender/render/intern/include/envmap.h
index 79233a5d625..c813e88c656 100644
--- a/source/blender/render/intern/include/envmap.h
+++ b/source/blender/render/intern/include/envmap.h
@@ -48,7 +48,7 @@ struct ImagePool;
void make_envmaps(struct Render *re);
int envmaptex(struct Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool);
-void env_rotate_scene(struct Render *re, float mat[4][4], int mode);
+void env_rotate_scene(struct Render *re, float mat[4][4], int do_rotate);
#endif /* __ENVMAP_H__ */
diff --git a/source/blender/render/intern/include/rayintersection.h b/source/blender/render/intern/include/rayintersection.h
index 4dceae56a4c..3607e66a237 100644
--- a/source/blender/render/intern/include/rayintersection.h
+++ b/source/blender/render/intern/include/rayintersection.h
@@ -64,6 +64,10 @@ typedef struct Isect {
float dir[3];
float dist;
+ /* for envmap and incremental view update renders */
+ float origstart[3];
+ float origdir[3];
+
/* precomputed values to accelerate bounding box intersection */
int bv_index[6];
float idot_axis[3];
diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h
index 1e81ca20d03..9e48299ed9a 100644
--- a/source/blender/render/intern/include/renderdatabase.h
+++ b/source/blender/render/intern/include/renderdatabase.h
@@ -140,6 +140,9 @@ struct VlakRen *RE_vlakren_copy(struct ObjectRen *obr, struct VlakRen *vlr);
void RE_set_customdata_names(struct ObjectRen *obr, struct CustomData *data);
+void area_lamp_vectors(struct LampRen *lar);
+
+
/* haloren->type: flags */
#define HA_ONLYSKY 1
#define HA_VECT 2
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 976be755532..2be3c118ec8 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -3765,7 +3765,7 @@ static void initshadowbuf(Render *re, LampRen *lar, float mat[4][4])
shb->compressthresh= lar->compressthresh;
}
-static void area_lamp_vectors(LampRen *lar)
+void area_lamp_vectors(LampRen *lar)
{
float xsize= 0.5f*lar->area_size, ysize= 0.5f*lar->area_sizey, multifac;
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index 6423bfa9486..419c3d8ee23 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -45,6 +45,7 @@
#include "DNA_group_types.h"
#include "DNA_image_types.h"
+#include "DNA_lamp_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
@@ -163,6 +164,7 @@ static Render *envmap_render_copy(Render *re, EnvMap *env)
/* view stuff in env render */
viewscale = (env->type == ENV_PLANE) ? env->viewscale : 1.0f;
RE_SetEnvmapCamera(envre, env->object, viewscale, env->clipsta, env->clipend);
+ copy_m4_m4(envre->viewmat_orig, re->viewmat_orig);
/* callbacks */
envre->display_draw = re->display_draw;
@@ -265,23 +267,27 @@ static void env_set_imats(Render *re)
/* ------------------------------------------------------------------------- */
-void env_rotate_scene(Render *re, float mat[4][4], int mode)
+void env_rotate_scene(Render *re, float mat[4][4], int do_rotate)
{
GroupObject *go;
ObjectRen *obr;
ObjectInstanceRen *obi;
LampRen *lar = NULL;
HaloRen *har = NULL;
- float imat[3][3], pmat[4][4], smat[4][4], tmat[4][4], cmat[3][3], tmpmat[4][4];
+ float imat[3][3], mat_inverse[4][4], smat[4][4], tmat[4][4], cmat[3][3], tmpmat[4][4];
int a;
- if (mode == 0) {
+ if (do_rotate == 0) {
invert_m4_m4(tmat, mat);
copy_m3_m4(imat, tmat);
+
+ copy_m4_m4(mat_inverse, mat);
}
else {
copy_m4_m4(tmat, mat);
copy_m3_m4(imat, mat);
+
+ invert_m4_m4(mat_inverse, tmat);
}
for (obi = re->instancetable.first; obi; obi = obi->next) {
@@ -290,7 +296,7 @@ void env_rotate_scene(Render *re, float mat[4][4], int mode)
copy_m4_m4(tmpmat, obi->mat);
mult_m4_m4m4(obi->mat, tmat, tmpmat);
}
- else if (mode == 1)
+ else if (do_rotate == 1)
copy_m4_m4(obi->mat, tmat);
else
unit_m4(obi->mat);
@@ -300,10 +306,12 @@ void env_rotate_scene(Render *re, float mat[4][4], int mode)
transpose_m3(obi->nmat);
/* indicate the renderer has to use transform matrices */
- if (mode == 0)
+ if (do_rotate == 0)
obi->flag &= ~R_ENV_TRANSFORMED;
- else
+ else {
obi->flag |= R_ENV_TRANSFORMED;
+ copy_m4_m4(obi->imat, mat_inverse);
+ }
}
@@ -319,32 +327,50 @@ void env_rotate_scene(Render *re, float mat[4][4], int mode)
for (go = re->lights.first; go; go = go->next) {
lar = go->lampren;
- /* removed here some horrible code of someone in NaN who tried to fix
- * prototypes... just solved by introducing a correct cmat[3][3] instead
- * of using smat. this works, check square spots in reflections (ton) */
- copy_m3_m3(cmat, lar->imat);
- mul_m3_m3m3(lar->imat, cmat, imat);
-
- mul_m3_v3(imat, lar->vec);
- mul_m4_v3(tmat, lar->co);
-
- lar->sh_invcampos[0] = -lar->co[0];
- lar->sh_invcampos[1] = -lar->co[1];
- lar->sh_invcampos[2] = -lar->co[2];
- mul_m3_v3(lar->imat, lar->sh_invcampos);
- lar->sh_invcampos[2] *= lar->sh_zfac;
+ /* copy from add_render_lamp */
+ if (do_rotate == 1)
+ mult_m4_m4m4(tmpmat, re->viewmat, go->ob->obmat);
+ else
+ mult_m4_m4m4(tmpmat, re->viewmat_orig, go->ob->obmat);
+ invert_m4_m4(go->ob->imat, tmpmat);
- if (lar->shb) {
- if (mode == 1) {
- invert_m4_m4(pmat, mat);
- mult_m4_m4m4(smat, lar->shb->viewmat, pmat);
- mult_m4_m4m4(lar->shb->persmat, lar->shb->winmat, smat);
+ copy_m3_m4(lar->mat, tmpmat);
+
+ copy_m3_m4(lar->imat, go->ob->imat);
+
+ lar->vec[0]= -tmpmat[2][0];
+ lar->vec[1]= -tmpmat[2][1];
+ lar->vec[2]= -tmpmat[2][2];
+ normalize_v3(lar->vec);
+ lar->co[0]= tmpmat[3][0];
+ lar->co[1]= tmpmat[3][1];
+ lar->co[2]= tmpmat[3][2];
+
+ if (lar->type == LA_AREA) {
+ area_lamp_vectors(lar);
+ }
+ else if (lar->type == LA_SPOT) {
+ normalize_v3(lar->imat[0]);
+ normalize_v3(lar->imat[1]);
+ normalize_v3(lar->imat[2]);
+
+ lar->sh_invcampos[0] = -lar->co[0];
+ lar->sh_invcampos[1] = -lar->co[1];
+ lar->sh_invcampos[2] = -lar->co[2];
+ mul_m3_v3(lar->imat, lar->sh_invcampos);
+ lar->sh_invcampos[2] *= lar->sh_zfac;
+
+ if (lar->shb) {
+ if (do_rotate == 1) {
+ mult_m4_m4m4(smat, lar->shb->viewmat, mat_inverse);
+ mult_m4_m4m4(lar->shb->persmat, lar->shb->winmat, smat);
+ }
+ else mult_m4_m4m4(lar->shb->persmat, lar->shb->winmat, lar->shb->viewmat);
}
- else mult_m4_m4m4(lar->shb->persmat, lar->shb->winmat, lar->shb->viewmat);
}
}
- if (mode) {
+ if (do_rotate) {
init_render_world(re);
env_set_imats(re);
}
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index 387004527c0..e77920dde26 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -499,7 +499,37 @@ 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)
{
ObjectInstanceRen *obi = (ObjectInstanceRen *)is->hit.ob;
@@ -716,11 +746,18 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, con
isec.orig.ob = obi;
isec.orig.face = vlr;
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);
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);
+
/* for as long we don't have proper dx/dy transform for rays we copy over original */
copy_v3_v3(shi.dxco, origshi->dxco);
copy_v3_v3(shi.dyco, origshi->dyco);
@@ -1621,6 +1658,9 @@ 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);
+
shade_ray(is, &shi, &shr);
if (shi.mat->material_type == MA_TYPE_SURFACE) {
const float d= (traflag & RAY_TRA) ?
@@ -1654,78 +1694,6 @@ 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 */
-static int UNUSED_FUNCTION(ray_trace_shadow_rad)(ShadeInput *ship, ShadeResult *shr)
-{
- static int counter=0, only_one= 0;
- extern float hashvectf[];
- Isect isec;
- ShadeInput shi;
- ShadeResult shr_t;
- float vec[3], accum[3], div= 0.0f;
- int a;
-
- assert(0);
-
- if (only_one) {
- return 0;
- }
- only_one= 1;
-
- accum[0]= accum[1]= accum[2]= 0.0f;
- isec.mode= RE_RAY_MIRROR;
- isec.orig.ob = ship->obi;
- isec.orig.face = ship->vlr;
- isec.hint = 0;
-
- copy_v3_v3(isec.start, ship->co);
-
- RE_RC_INIT(isec, shi);
-
- for (a=0; a<8*8; a++) {
-
- counter+=3;
- counter %= 768;
- copy_v3_v3(vec, hashvectf+counter);
- if (dot_v3v3(ship->vn, vec) > 0.0f) {
- vec[0]-= vec[0];
- vec[1]-= vec[1];
- vec[2]-= vec[2];
- }
-
- copy_v3_v3(isec.dir, vec);
- isec.dist = RE_RAYTRACE_MAXDIST;
-
- if (RE_rayobject_raycast(R.raytree, &isec)) {
- float fac;
-
- /* Warning, This is not that nice, and possibly a bit slow for every ray,
- * however some variables were not initialized properly in, unless using shade_input_initialize(...), we need to do a memset */
- memset(&shi, 0, sizeof(ShadeInput));
- /* end warning! - Campbell */
-
- shade_ray(&isec, &shi, &shr_t);
- /* 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]);
- accum[2]+= fac*(shr_t.diff[2]+shr_t.spec[2]);
- div+= fac;
- }
- else div+= 1.0f;
- }
-
- if (div!=0.0f) {
- shr->diff[0]+= accum[0]/div;
- shr->diff[1]+= accum[1]/div;
- shr->diff[2]+= accum[2]/div;
- }
- shr->alpha= 1.0f;
-
- only_one= 0;
- return 1;
-}
/* aolight: function to create random unit sphere vectors for total random sampling */
static void RandomSpherical(RNG *rng, float v[3])
@@ -1909,6 +1877,10 @@ static void ray_ao_qmc(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_rayobject_hint_bb(R.raytree, &point_hint, isec.start, isec.start);
isec.hint = &point_hint;
@@ -1961,12 +1933,15 @@ static void ray_ao_qmc(ShadeInput *shi, float ao[3], float env[3])
dir[2] = (samp3d[0]*up[2] + samp3d[1]*side[2] + samp3d[2]*nrm[2]);
normalize_v3(dir);
-
+
isec.dir[0] = -dir[0];
isec.dir[1] = -dir[1];
isec.dir[2] = -dir[2];
isec.dist = maxdist;
+ if (shi->obi->flag & R_ENV_TRANSFORMED)
+ ray_env_rotate_dir(&isec, shi->obi->imat);
+
prev = fac;
if (RE_rayobject_raycast(R.raytree, &isec)) {
@@ -2049,6 +2024,9 @@ 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_rayobject_hint_bb(R.raytree, &point_hint, isec.start, isec.start);
isec.hint = &point_hint;
@@ -2106,6 +2084,9 @@ 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);
+
/* do the trace */
if (RE_rayobject_raycast(R.raytree, &isec)) {
if (R.wrld.aomode & WO_AODIST) sh+= expf(-isec.dist*R.wrld.aodistfac);
@@ -2214,7 +2195,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, const float lampco[3],
float colsq[4];
float adapt_thresh = lar->adapt_thresh;
int min_adapt_samples=4, max_samples = lar->ray_totsamp;
- float *co;
+ float start[3];
int do_soft = TRUE, full_osa = FALSE, i;
float min[3], max[3];
@@ -2257,6 +2238,10 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, const float lampco[3],
for (i = 0; i < totjitco; i++) {
minmax_v3v3_v3(min, max, jitco[i]);
}
+ if (shi->obi->flag & R_ENV_TRANSFORMED) {
+ mul_m4_v3(shi->obi->imat, min);
+ mul_m4_v3(shi->obi->imat, max);
+ }
RE_rayobject_hint_bb(R.raytree, &bb_hint, min, max);
isec->hint = &bb_hint;
@@ -2272,7 +2257,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, const float lampco[3],
/* manually jitter the start shading co-ord per sample
* based on the pre-generated OSA texture sampling offsets,
* for anti-aliasing sharp shadow edges. */
- co = jitco[samples % totjitco];
+ copy_v3_v3(start, jitco[samples % totjitco]);
if (do_soft) {
/* sphere shadow source */
@@ -2280,7 +2265,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, const float lampco[3],
float ru[3], rv[3], v[3], s[3];
/* calc tangent plane vectors */
- sub_v3_v3v3(v, co, lampco);
+ sub_v3_v3v3(v, start, lampco);
normalize_v3(v);
ortho_basis_v3v3_v3(ru, rv, v);
@@ -2314,20 +2299,23 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, const float lampco[3],
float jitbias= 0.5f*(len_v3(shi->dxco) + len_v3(shi->dyco));
float v[3];
- sub_v3_v3v3(v, co, end);
+ sub_v3_v3v3(v, start, end);
normalize_v3(v);
- co[0] -= jitbias*v[0];
- co[1] -= jitbias*v[1];
- co[2] -= jitbias*v[2];
+ start[0] -= jitbias*v[0];
+ start[1] -= jitbias*v[1];
+ start[2] -= jitbias*v[2];
}
-
- copy_v3_v3(isec->start, co);
+
+ copy_v3_v3(isec->start, start);
isec->dir[0] = end[0]-isec->start[0];
isec->dir[1] = end[1]-isec->start[1];
isec->dir[2] = end[2]-isec->start[2];
isec->dist = normalize_v3(isec->dir);
+ if (shi->obi->flag & R_ENV_TRANSFORMED)
+ ray_env_rotate(isec, shi->obi->imat);
+
/* trace the ray */
if (isec->mode==RE_RAY_SHADOW_TRA) {
float col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
@@ -2404,6 +2392,9 @@ 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);
+
isec->orig.ob = shi->obi;
isec->orig.face = shi->vlr;
RE_rayobject_hint_bb(R.raytree, &point_hint, isec->start, isec->start);
@@ -2429,6 +2420,10 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, const float lampco[
isec->dir[0] = vec[0]+lampco[0]-isec->start[0];
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);
+
isec->dist = 1.0f;
isec->check = RE_CHECK_VLR_RENDER;
isec->skip = RE_SKIP_VLR_NEIGHBOUR;
@@ -2528,6 +2523,9 @@ 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);
+
if (isec.mode==RE_RAY_SHADOW_TRA) {
/* isec.col is like shadfac, so defines amount of light (0.0 is full shadow) */
float col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
@@ -2550,51 +2548,3 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float shadfac[4])
}
-#if 0
-/* only when face points away from lamp, in direction of lamp, trace ray and find first exit point */
-static void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float co[3])
-{
- Isect isec;
- float lampco[3];
-
- assert(0);
-
- /* setup isec */
- RE_RC_INIT(isec, *shi);
- isec.mode= RE_RAY_SHADOW_TRA;
- isec.hint = 0;
-
- if (lar->mode & LA_LAYER) isec.lay= lar->lay; else isec.lay= -1;
-
- if (lar->type==LA_SUN || lar->type==LA_HEMI) {
- lampco[0]= shi->co[0] - RE_RAYTRACE_MAXDIST*lar->vec[0];
- lampco[1]= shi->co[1] - RE_RAYTRACE_MAXDIST*lar->vec[1];
- lampco[2]= shi->co[2] - RE_RAYTRACE_MAXDIST*lar->vec[2];
- }
- else {
- copy_v3_v3(lampco, lar->co);
- }
-
- isec.orig.ob = shi->obi;
- isec.orig.face = shi->vlr;
-
- /* set up isec.dir */
- copy_v3_v3(isec.start, shi->co);
- copy_v3_v3(isec.end, lampco);
-
- if (RE_rayobject_raycast(R.raytree, &isec)) {
- /* we got a face */
-
- /* render co */
- co[0]= isec.start[0]+isec.dist*(isec.dir[0]);
- co[1]= isec.start[1]+isec.dist*(isec.dir[1]);
- co[2]= isec.start[2]+isec.dist*(isec.dir[2]);
-
- *distfac= len_v3(isec.dir);
- }
- else
- *distfac= 0.0f;
-}
-
-#endif
-