- Recursive environment map render
Multiple environments now can be rendered in one pass. Previously the other objects with environment maps didn't show up in a reflection. Like this: http://www.blender.org/bf/dep.jpg By default, Blender renders now this result: http://www.blender.org/bf/dep0.jpg For a further 'recursive ray-tracing effect' you can give each EnvMap texture a higher "Depth" value. Here is a result with depth set at '2': http://www.blender.org/bf/dep2.jpg Related new options: - in (F10) DisplayButtons, environment map rendering can be turned on and off. - in EnvMap texture buttons you can free all environment maps - Environment map sizes are also reduced with the (F10) 'percentage' option. Tech note: with this commit the VlakRen struct has on *ob pointer!
This commit is contained in:
@@ -629,10 +629,6 @@ void init_render_texture(Tex *tex)
|
||||
tex->extend= TEX_CLIP;
|
||||
|
||||
if(tex->env) {
|
||||
/* temporal solution: layer 21 is to indicate an anvmap object */
|
||||
tex->env->notlay |= (1<<20);
|
||||
if(tex->env->object) tex->env->object->lay |= (1<<20);
|
||||
|
||||
if(R.flag & R_RENDERING) {
|
||||
if(tex->env->stype==ENV_ANIM) RE_free_envmapdata(tex->env);
|
||||
}
|
||||
|
||||
@@ -3703,6 +3703,7 @@ static void do_versions(Main *main)
|
||||
for (sce= main->scene.first; sce; sce= sce->id.next) {
|
||||
sce->audio.mixrate = 44100;
|
||||
sce->audio.flag |= AUDIO_SCRUB;
|
||||
sce->r.mode |= R_ENVMAP;
|
||||
}
|
||||
// init new shader vars
|
||||
for (ma= main->mat.first; ma; ma= ma->id.next) {
|
||||
|
||||
@@ -166,7 +166,7 @@ typedef struct RenderData {
|
||||
* 1: do shadows
|
||||
* 2: do gamma correction
|
||||
* 3: ortho (not used?)
|
||||
* 4: trace (not used?)
|
||||
* 4: do envmap
|
||||
* 5: edge shading
|
||||
* 6: field rendering
|
||||
* 7: Disables time difference in field calculations
|
||||
@@ -268,7 +268,7 @@ typedef struct Scene {
|
||||
#define R_SHADOW 0x0002
|
||||
#define R_GAMMA 0x0004
|
||||
#define R_ORTHO 0x0008
|
||||
#define R_TRACE 0x0010
|
||||
#define R_ENVMAP 0x0010
|
||||
#define R_EDGE 0x0020
|
||||
#define R_FIELDS 0x0040
|
||||
#define R_FIELDSTILL 0x0080
|
||||
|
||||
@@ -113,8 +113,10 @@ typedef struct EnvMap {
|
||||
short type, stype;
|
||||
float clipsta, clipend;
|
||||
unsigned int notlay;
|
||||
int cuberes;
|
||||
short cuberes, depth;
|
||||
short ok, lastframe;
|
||||
short recalc, lastsize;
|
||||
int pad1;
|
||||
} EnvMap;
|
||||
|
||||
typedef struct Tex {
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_world_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
/* Definitely weird: this equals 1<<21... so wtf?*/
|
||||
#define MAXVERT (2<<20)
|
||||
@@ -190,6 +191,7 @@ typedef struct VlakRen
|
||||
char flag, ec;
|
||||
unsigned int lay;
|
||||
RadFace *radface;
|
||||
Object *ob;
|
||||
} VlakRen;
|
||||
|
||||
|
||||
|
||||
@@ -203,13 +203,16 @@ void envmap_renderdata(EnvMap *env)
|
||||
{
|
||||
static RE_Render envR;
|
||||
static Object *camera;
|
||||
int cuberes;
|
||||
|
||||
if(env) {
|
||||
envR= R;
|
||||
camera= G.scene->camera;
|
||||
|
||||
env->cuberes &= 0xFFFC;
|
||||
R.rectx= R.r.xsch= R.recty= R.r.ysch= env->cuberes;
|
||||
cuberes = (env->cuberes * R.r.size) / 100;
|
||||
cuberes &= 0xFFFC;
|
||||
env->lastsize= R.r.size;
|
||||
R.rectx= R.r.xsch= R.recty= R.r.ysch= cuberes;
|
||||
R.afmx= R.afmy= R.r.xsch/2;
|
||||
R.xstart= R.ystart= -R.afmx;
|
||||
R.xend= R.yend= R.xstart+R.rectx-1;
|
||||
@@ -381,6 +384,18 @@ void env_layerflags(unsigned int notlay)
|
||||
}
|
||||
}
|
||||
|
||||
void env_hideobject(Object *ob)
|
||||
{
|
||||
VlakRen *vlr = NULL;
|
||||
int a;
|
||||
|
||||
for(a=0; a<R.totvlak; a++) {
|
||||
if((a & 255)==0) vlr= R.blovl[a>>8];
|
||||
else vlr++;
|
||||
if(vlr->ob == ob) vlr->flag &= ~R_VISIBLE;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void env_set_imats()
|
||||
@@ -443,6 +458,7 @@ void render_envmap(EnvMap *env)
|
||||
init_render_world();
|
||||
setzbufvlaggen(RE_projectverto);
|
||||
env_layerflags(env->notlay);
|
||||
env_hideobject(env->object);
|
||||
env_set_imats();
|
||||
|
||||
if(RE_local_test_break()==0) {
|
||||
@@ -492,29 +508,53 @@ void render_envmap(EnvMap *env)
|
||||
void make_envmaps()
|
||||
{
|
||||
Tex *tex;
|
||||
int do_init= 0;
|
||||
int do_init= 0, depth= 0;
|
||||
|
||||
tex= G.main->tex.first;
|
||||
while(tex) {
|
||||
if(tex->id.us && tex->type==TEX_ENVMAP) {
|
||||
if(tex->env && tex->env->object) {
|
||||
if(tex->env->object->lay & G.scene->lay) {
|
||||
if(tex->env->stype!=ENV_LOAD) {
|
||||
|
||||
if(tex->env->ok==0) {
|
||||
do_init= 1;
|
||||
render_envmap(tex->env);
|
||||
}
|
||||
else if((R.r.mode & R_OSA) && tex->env->ok==ENV_NORMAL) {
|
||||
do_init= 1;
|
||||
RE_free_envmapdata(tex->env);
|
||||
render_envmap(tex->env);
|
||||
if (!(R.r.mode & R_ENVMAP)) return;
|
||||
|
||||
|
||||
/* 5 = hardcoded max recursion level */
|
||||
while(depth<5) {
|
||||
tex= G.main->tex.first;
|
||||
while(tex) {
|
||||
if(tex->id.us && tex->type==TEX_ENVMAP) {
|
||||
if(tex->env && tex->env->object) {
|
||||
if(tex->env->object->lay & G.scene->lay) {
|
||||
if(tex->env->stype!=ENV_LOAD) {
|
||||
|
||||
/* decide if to render an envmap (again) */
|
||||
if(tex->env->depth >= depth) {
|
||||
|
||||
/* set 'recalc' to make sure it does an entire loop of recalcs */
|
||||
|
||||
if(tex->env->ok) {
|
||||
/* free when OSA, and old one isn't OSA */
|
||||
if((R.r.mode & R_OSA) && tex->env->ok==ENV_NORMAL)
|
||||
RE_free_envmapdata(tex->env);
|
||||
/* free when size larger */
|
||||
else if(tex->env->lastsize < R.r.size)
|
||||
RE_free_envmapdata(tex->env);
|
||||
/* free when env is in recalcmode */
|
||||
else if(tex->env->recalc)
|
||||
RE_free_envmapdata(tex->env);
|
||||
}
|
||||
|
||||
if(tex->env->ok==0 && depth==0) tex->env->recalc= 1;
|
||||
|
||||
if(tex->env->ok==0) {
|
||||
do_init= 1;
|
||||
render_envmap(tex->env);
|
||||
|
||||
if(depth==tex->env->depth) tex->env->recalc= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tex= tex->id.next;
|
||||
}
|
||||
tex= tex->id.next;
|
||||
depth++;
|
||||
}
|
||||
|
||||
if(do_init) {
|
||||
|
||||
@@ -1194,6 +1194,7 @@ static void init_render_displist_mesh(Object *ob)
|
||||
flen= CalcNormFloat4(v1->co, v3->co, v4->co, v2->co, n1);
|
||||
if(flen!=0.0) {
|
||||
vlr= RE_findOrAddVlak(R.totvlak++);
|
||||
vlr->ob= ob;
|
||||
vlr->v1= v1;
|
||||
vlr->v2= v3;
|
||||
vlr->v3= v4;
|
||||
@@ -1272,6 +1273,7 @@ static void init_render_displist_mesh(Object *ob)
|
||||
|
||||
if(flen!=0.0) {
|
||||
vlr= RE_findOrAddVlak(R.totvlak++);
|
||||
vlr->ob= ob;
|
||||
vlr->v1= v1;
|
||||
vlr->v2= v2;
|
||||
vlr->v3= v3;
|
||||
@@ -1445,6 +1447,7 @@ static void init_render_mball(Object *ob)
|
||||
for(a=0; a<dl->parts; a++, index+=4) {
|
||||
|
||||
vlr= RE_findOrAddVlak(R.totvlak++);
|
||||
vlr->ob= ob;
|
||||
vlr->v1= RE_findOrAddVert(startvert+index[0]);
|
||||
vlr->v2= RE_findOrAddVert(startvert+index[1]);
|
||||
vlr->v3= RE_findOrAddVert(startvert+index[2]);
|
||||
@@ -1648,6 +1651,7 @@ static void init_render_mesh(Object *ob)
|
||||
if(mface->v3) {
|
||||
|
||||
vlr= RE_findOrAddVlak(R.totvlak++);
|
||||
vlr->ob= ob;
|
||||
vlr->v1= RE_findOrAddVert(vertofs+mface->v1);
|
||||
vlr->v2= RE_findOrAddVert(vertofs+mface->v2);
|
||||
vlr->v3= RE_findOrAddVert(vertofs+mface->v3);
|
||||
@@ -1727,6 +1731,7 @@ static void init_render_mesh(Object *ob)
|
||||
}
|
||||
else if(mface->v2 && (ma->mode & MA_WIRE)) {
|
||||
vlr= RE_findOrAddVlak(R.totvlak++);
|
||||
vlr->ob= ob;
|
||||
vlr->v1= RE_findOrAddVert(vertofs+mface->v1);
|
||||
vlr->v2= RE_findOrAddVert(vertofs+mface->v2);
|
||||
vlr->v3= vlr->v2;
|
||||
@@ -2119,6 +2124,7 @@ static void init_render_surf(Object *ob)
|
||||
|
||||
// if(flen!=0.0) {
|
||||
vlr= RE_findOrAddVlak(R.totvlak++);
|
||||
vlr->ob= ob;
|
||||
vlr->v1= v1; vlr->v2= v2; vlr->v3= v3; vlr->v4= v4;
|
||||
VECCOPY(vlr->n, n1);
|
||||
vlr->len= flen;
|
||||
@@ -2255,6 +2261,7 @@ static void init_render_surf(Object *ob)
|
||||
flen= CalcNormFloat4(v1->co, v3->co, v4->co, v2->co, n1);
|
||||
if(flen!=0.0) {
|
||||
vlr= RE_findOrAddVlak(R.totvlak++);
|
||||
vlr->ob= ob;
|
||||
vlr->v1= v1;
|
||||
vlr->v2= v3;
|
||||
vlr->v3= v4;
|
||||
@@ -2492,6 +2499,7 @@ static void init_render_curve(Object *ob)
|
||||
for(; b<bl->nr; b++) {
|
||||
|
||||
vlr= RE_findOrAddVlak(R.totvlak++);
|
||||
vlr->ob= ob;
|
||||
vlr->v1= RE_findOrAddVert(p2);
|
||||
vlr->v2= RE_findOrAddVert(p1);
|
||||
vlr->v3= RE_findOrAddVert(p3);
|
||||
|
||||
@@ -272,6 +272,8 @@ char texstr[15][8]= {"None" , "Clouds" , "Wood",
|
||||
#define B_PACKIMA 1355
|
||||
#define B_TEXSETFRAMES 1356
|
||||
|
||||
#define B_ENV_FREE_ALL 1357
|
||||
|
||||
/* *********************** */
|
||||
#define B_ANIMBUTS 1500
|
||||
|
||||
@@ -3560,6 +3562,19 @@ void do_texbuts(unsigned short event)
|
||||
BIF_preview_changed(G.buts);
|
||||
}
|
||||
break;
|
||||
case B_ENV_FREE_ALL:
|
||||
tex= G.main->tex.first;
|
||||
while(tex) {
|
||||
if(tex->id.us && tex->type==TEX_ENVMAP) {
|
||||
if(tex->env) {
|
||||
if(tex->env->stype!=ENV_LOAD) RE_free_envmapdata(tex->env);
|
||||
}
|
||||
}
|
||||
tex= tex->id.next;
|
||||
}
|
||||
allqueue(REDRAWBUTSTEX, 0);
|
||||
BIF_preview_changed(G.buts);
|
||||
break;
|
||||
case B_ENV_SAVE:
|
||||
if(tex->env && tex->env->ok) {
|
||||
sa= closest_bigger_area();
|
||||
@@ -3917,8 +3932,10 @@ void texbuts(void)
|
||||
}
|
||||
else if(tex->type==TEX_ENVMAP) {
|
||||
|
||||
if(tex->env==0) tex->env= RE_add_envmap();
|
||||
|
||||
if(tex->env==0) {
|
||||
tex->env= RE_add_envmap();
|
||||
tex->env->object= OBACT;
|
||||
}
|
||||
if(tex->env) {
|
||||
env= tex->env;
|
||||
|
||||
@@ -3957,15 +3974,17 @@ void texbuts(void)
|
||||
uiDefBut(block, BUT, B_ENV_FREE, "Free Data", 350,137,107,24, 0, 0, 0, 0, 0, "Release all images associated with environment map");
|
||||
uiBlockSetCol(block, BUTGREY);
|
||||
uiDefBut(block, BUT, B_ENV_SAVE, "Save EnvMap", 461,137,115,24, 0, 0, 0, 0, 0, "Save environment map");
|
||||
uiBlockSetCol(block, BUTSALMON);
|
||||
uiDefBut(block, BUT, B_ENV_FREE_ALL, "Free all EnvMaps", 600,137,160,24, 0, 0, 0, 0, 0, "Frees all rendered environment maps");
|
||||
}
|
||||
uiBlockSetCol(block, BUTGREY);
|
||||
uiDefIDPoinBut(block, test_obpoin_but, B_ENV_OB, "Ob:", 350,95,206,24, &(env->object), "Object name");
|
||||
uiBlockSetCol(block, BUTGREY);
|
||||
uiDefButF(block, NUM, REDRAWVIEW3D, "ClipSta", 350,68,122,24, &env->clipsta, 0.01, 50.0, 100, 0, "Set start value for clipping");
|
||||
uiDefButF(block, NUM, 0, "ClipEnd", 475,68,142,24, &env->clipend, 0.1, 5000.0, 1000, 0, "Set end value for clipping");
|
||||
if(env->stype!=ENV_LOAD) uiDefButI(block, NUM, B_ENV_FREE, "CubeRes", 620,68,140,24, &env->cuberes, 50, 1000.0, 0, 0, "Set the resolution in pixels");
|
||||
|
||||
uiDefButF(block, NUM, B_MATPRV, "Filter :", 558,95,201,24, &tex->filtersize, 0.1, 25.0, 0, 0, "Adjust sharpness or blurriness of the reflection"),
|
||||
uiDefIDPoinBut(block, test_obpoin_but, B_ENV_OB, "Ob:", 350,95,166,24, &(env->object), "Object name");
|
||||
uiDefButF(block, NUM, B_MATPRV, "Filter :", 518,95,121,24, &tex->filtersize, 0.1, 25.0, 0, 0, "Adjust sharpness or blurriness of the reflection"),
|
||||
uiDefButS(block, NUM, B_ENV_FREE, "Depth:", 639,95,120,24, &env->depth, 0, 5.0, 0, 0, "Number of times a map gets rendered again, for recursive mirror effect"),
|
||||
|
||||
uiDefButF(block, NUM, REDRAWVIEW3D, "ClipSta", 350,68,122,24, &env->clipsta, 0.01, 50.0, 100, 0, "Set start value for clipping");
|
||||
uiDefButF(block, NUM, 0, "ClipEnd", 475,68,142,24, &env->clipend, 0.1, 5000.0, 1000, 0, "Set end value for clipping");
|
||||
if(env->stype!=ENV_LOAD) uiDefButS(block, NUM, B_ENV_FREE, "CubeRes", 620,68,140,24, &env->cuberes, 50, 2048.0, 0, 0, "Set the resolution in pixels");
|
||||
|
||||
uiDefBut(block, LABEL, 0, "Don't render layer:", 772,100,140,22, 0, 0.0, 0.0, 0, 0, "");
|
||||
xco= 772;
|
||||
@@ -6628,9 +6647,10 @@ void renderbuts(void)
|
||||
uiDefBut(block, BUT,B_DORENDER,"RENDER", 369,142,192,47, 0, 0, 0, 0, 0, "Start the rendering");
|
||||
|
||||
uiBlockSetCol(block, BUTGREY);
|
||||
uiDefButS(block, TOG|BIT|1,0,"Shadows", 565,167,122,22, &G.scene->r.mode, 0, 0, 0, 0, "Enable shadow calculation");
|
||||
uiDefButS(block, TOG|BIT|10,0,"Pano",565,142,61,22, &G.scene->r.mode, 0, 0, 0, 0, "Enable panorama rendering (output width is multiplied by Xparts)");
|
||||
uiDefButS(block, TOG|BIT|8,0,"Radio",626,142,61,22, &G.scene->r.mode, 0, 0, 0, 0, "Enable radiosity rendering");
|
||||
uiDefButS(block, TOG|BIT|1,0,"Shadow", 565,167,61,22, &G.scene->r.mode, 0, 0, 0, 0, "Enable shadow calculation");
|
||||
uiDefButS(block, TOG|BIT|4,0,"EnvMap", 626,167,61,22, &G.scene->r.mode, 0, 0, 0, 0, "Enable shadow calculation");
|
||||
uiDefButS(block, TOG|BIT|10,0,"Pano", 565,142,61,22, &G.scene->r.mode, 0, 0, 0, 0, "Enable panorama rendering (output width is multiplied by Xparts)");
|
||||
uiDefButS(block, TOG|BIT|8,0,"Radio", 626,142,61,22, &G.scene->r.mode, 0, 0, 0, 0, "Enable radiosity rendering");
|
||||
|
||||
uiDefButS(block, ROW,B_DIFF,"100%", 565,114,121,20,&G.scene->r.size,1.0,100.0, 0, 0, "Set render size to defined size");
|
||||
uiDefButS(block, ROW,B_DIFF,"75%", 565,90,36,20,&G.scene->r.size,1.0,75.0, 0, 0, "Set render size to 3/4 of defined size");
|
||||
|
||||
Reference in New Issue
Block a user