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:
authorJoseph Eagar <joeedh@gmail.com>2010-01-06 01:33:41 +0300
committerJoseph Eagar <joeedh@gmail.com>2010-01-06 01:33:41 +0300
commit67ff197cb1b0e79a95bf6546b5fe1a481b79fce1 (patch)
tree9f78d5cda71d200cab6475eb9c2747f7181adf3a /source/blender/render
parent473f235a6eee6c02cf41a1e173f53406b62440aa (diff)
parentffe13aeb232ac6bad3a98997b4a352f434293193 (diff)
Merge with trunk/2.5 at r25563
Most likely will not compile for others, I'd appreciate any build errors and missing files reports (I can never seem to get everything committed and all the build systems working without help). Porting over the sculpt/multires tools was a breeze, thanks goes to brecht for a design that didn't exclude ngons and was easy to port. Note that I've not tested externally-backed multires file support yet. Also, I still need to write version patch code for some cases. Some notes: * Like trunk, topological changes don't update multires right, so e.g. subdivide will duplicate multires data on the new faces, instead of subdividing it. * If you set the debug value (ctrl-alt-d) to 1 it'll turn on my experiments in speeding up sculpting on higher-res multires meshes (but note it makes partial redraw not completely accurate). * There's a bug where you have to go through editmode to get out of sculpt mode, not sure if I inherited or created this myself.
Diffstat (limited to 'source/blender/render')
-rw-r--r--source/blender/render/SConscript45
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h7
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h2
-rw-r--r--source/blender/render/intern/include/render_types.h3
-rw-r--r--source/blender/render/intern/raytrace/reorganize.h8
-rw-r--r--source/blender/render/intern/source/convertblender.c36
-rw-r--r--source/blender/render/intern/source/occlusion.c255
-rw-r--r--source/blender/render/intern/source/pipeline.c65
-rw-r--r--source/blender/render/intern/source/pixelshading.c17
-rw-r--r--source/blender/render/intern/source/shadeinput.c38
-rw-r--r--source/blender/render/intern/source/shadeoutput.c1
-rw-r--r--source/blender/render/intern/source/sss.c11
-rw-r--r--source/blender/render/intern/source/strand.c6
-rw-r--r--source/blender/render/intern/source/texture.c55
-rw-r--r--source/blender/render/intern/source/zbuf.c8
15 files changed, 352 insertions, 205 deletions
diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript
index 795e7247597..d9a074c1470 100644
--- a/source/blender/render/SConscript
+++ b/source/blender/render/SConscript
@@ -1,19 +1,6 @@
#!/usr/bin/python
Import ('env')
-if env['OURPLATFORM'] in ('win32-vc', 'win64-vc', 'win32-mingw'):
- # FIXME: need to set the appropriate flags for msvc, otherwise we get warnings
- cflags = []
- cxxflags = []
-
-if env['OURPLATFORM'] == 'darwin':
- if env['MACOSX_ARCHITECTURE'] in ('i386', 'x86_64'):
- cflags = env['CFLAGS'] + ['-mfpmath=sse']
- cxxflags = env['CXXFLAGS'] + ['-mfpmath=sse']
- else:
- cflags = env['CFLAGS']
- cxxflags = env['CXXFLAGS']
-
sources = env.Glob('intern/source/*.c')
raysources = env.Glob('intern/raytrace/*.cpp')
@@ -21,8 +8,32 @@ incs = 'intern/include #/intern/guardedalloc ../blenlib ../makesdna ../makesrna'
incs += ' extern/include ../blenkernel ../radiosity/extern/include ../imbuf'
incs += ' ../include ../blenloader ../../../intern/smoke/extern'
+cflags = env['CCFLAGS']
+cxxflags = env['CXXFLAGS']
+
defs = []
+if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
+ if env['WITH_BF_RAYOPTIMIZATION']:
+ cflags = env['CCFLAGS'] + env['BF_RAYOPTIMIZATION_SSE_FLAGS']
+ cxxflags = env['CCFLAGS'] + env['BF_RAYOPTIMIZATION_SSE_FLAGS']
+
+if env['OURPLATFORM'] == 'win32-mingw':
+ if env['WITH_BF_RAYOPTIMIZATION']:
+ cflags = env['CCFLAGS'] + env['BF_RAYOPTIMIZATION_SSE_FLAGS']
+ cxxflags = env['CXXFLAGS'] + env['BF_RAYOPTIMIZATION_SSE_FLAGS']
+
+if env['OURPLATFORM'] == 'darwin':
+ if env['MACOSX_ARCHITECTURE'] in ('i386', 'x86_64') and env['WITH_BF_RAYOPTIMIZATION']:
+ cflags = env['CFLAGS'] + env['BF_RAYOPTIMIZATION_SSE_FLAGS']
+ cxxflags = env['CXXFLAGS'] + env['BF_RAYOPTIMIZATION_SSE_FLAGS']
+
+if env['OURPLATFORM'] == 'linux2':
+ if env['WITH_BF_RAYOPTIMIZATION']:
+ cflags = env['CCFLAGS'] + env['BF_RAYOPTIMIZATION_SSE_FLAGS']
+ cxxflags = env['CXXFLAGS'] + env['BF_RAYOPTIMIZATION_SSE_FLAGS']
+ incs += ' ../../../extern/binreloc/include'
+
if env['WITH_BF_QUICKTIME']:
defs.append('WITH_QUICKTIME')
incs += ' ../quicktime ' + env['BF_QUICKTIME_INC']
@@ -30,13 +41,11 @@ if env['WITH_BF_QUICKTIME']:
if env['WITH_BF_OPENEXR']:
defs.append('WITH_OPENEXR')
-if env['OURPLATFORM'] == 'linux2':
- cflags = ['-O2','-msse2','-mfpmath=sse', '-pthread']
- cxxflags = ['-O2','-msse2','-mfpmath=sse', '-pthread']
- incs += ' ../../../extern/binreloc/include'
-
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
incs += ' ' + env['BF_PTHREADS_INC']
+if env['WITH_BF_RAYOPTIMIZATION']:
+ defs.append('__SSE__')
+
env.BlenderLib ( libname = 'bf_render', sources = sources, includes = Split(incs), defines=defs, libtype='core', priority=145, compileflags=cflags )
env.BlenderLib ( libname = 'bf_render_raytrace', sources = raysources, includes = Split(incs), defines=defs, libtype='core', priority=145, compileflags=cflags, cxx_compileflags=cxxflags )
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 56a81ac6b43..76e3e002513 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -44,6 +44,7 @@ struct RenderData;
struct RenderEngine;
struct RenderEngineType;
struct RenderResult;
+struct ReportList;
struct Scene;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
@@ -200,7 +201,7 @@ void RE_TileProcessor(struct Render *re, int firsttile, int threaded);
/* only RE_NewRender() needed, main Blender render calls */
void RE_BlenderFrame(struct Render *re, struct Scene *scene, int frame);
-void RE_BlenderAnim(struct Render *re, struct Scene *scene, int sfra, int efra, int tfra);
+void RE_BlenderAnim(struct Render *re, struct Scene *scene, int sfra, int efra, int tfra, struct ReportList *reports);
void RE_ReadRenderResult(struct Scene *scene, struct Scene *scenode);
void RE_WriteRenderResult(RenderResult *rr, char *filename, int compress);
@@ -253,8 +254,8 @@ typedef struct RenderEngineType {
struct RenderEngineType *next, *prev;
/* type info */
- char idname[32];
- char name[32];
+ char idname[64]; // best keep the same size as BKE_ST_MAXNAME
+ char name[64];
int flag;
void (*render)(struct RenderEngine *engine, struct Scene *scene);
diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h
index b36163f57c0..2615be1440a 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -153,7 +153,7 @@ typedef struct ShadeInput
float dxstrand, dystrand;
/* AO is a pre-process now */
- float ao[3];
+ float ao[3], indirect[3];
int xs, ys; /* pixel to be rendered */
int mask; /* subsample mask */
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 48bf34d0696..d41851db5ff 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -398,7 +398,8 @@ typedef struct StrandSurface {
int (*face)[4];
float (*co)[3];
/* for occlusion caching */
- float (*col)[3];
+ float (*ao)[3];
+ float (*indirect)[3];
/* for speedvectors */
float (*prevco)[3], (*nextco)[3];
int totvert, totface;
diff --git a/source/blender/render/intern/raytrace/reorganize.h b/source/blender/render/intern/raytrace/reorganize.h
index f0335b769d5..841b046e073 100644
--- a/source/blender/render/intern/raytrace/reorganize.h
+++ b/source/blender/render/intern/raytrace/reorganize.h
@@ -32,9 +32,17 @@
#include <vector>
#include <queue>
+#ifdef _WIN32
+#define INFINITY FLT_MAX // in mingw math.h: (1.0F/0.0F). This generates compile error, though.
+#endif
+
extern int tot_pushup;
extern int tot_pushdown;
+#if !defined(INFINITY) && defined(HUGE_VAL)
+#define INFINITY HUGE_VAL
+#endif
+
template<class Node>
bool node_fits_inside(Node *a, Node *b)
{
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 3b08544e2a5..58b6d2bc3c7 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -1707,11 +1707,9 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
totface= psmd->dm->getNumTessFaces(psmd->dm);
origindex= psmd->dm->getTessFaceDataArray(psmd->dm, CD_ORIGINDEX);
- if(origindex) {
- for(a=0; a<totface; a++)
- strandbuf->totbound= MAX2(strandbuf->totbound, origindex[a]);
- strandbuf->totbound++;
- }
+ for(a=0; a<totface; a++)
+ strandbuf->totbound= MAX2(strandbuf->totbound, (origindex)? origindex[a]: a);
+
strandbuf->totbound++;
strandbuf->bound= MEM_callocN(sizeof(StrandBound)*strandbuf->totbound, "StrandBound");
sbound= strandbuf->bound;
@@ -1852,8 +1850,10 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
dosimplify = psys_render_simplify_params(psys, cpa, simplify);
if(strandbuf) {
- if(origindex[cpa->num]+1 > sbound - strandbuf->bound) {
- sbound= strandbuf->bound + origindex[cpa->num]+1;
+ int orignum= (origindex)? origindex[cpa->num]: cpa->num;
+
+ if(orignum > sbound - strandbuf->bound) {
+ sbound= strandbuf->bound + orignum;
sbound->start= sbound->end= obr->totstrand;
}
}
@@ -4492,7 +4492,7 @@ void RE_Database_Free(Render *re)
}
}
-static int allow_render_object(Object *ob, int nolamps, int onlyselected, Object *actob)
+static int allow_render_object(Render *re, Object *ob, int nolamps, int onlyselected, Object *actob)
{
/* override not showing object when duplis are used with particles */
if(ob->transflag & OB_DUPLIPARTS)
@@ -4500,6 +4500,10 @@ static int allow_render_object(Object *ob, int nolamps, int onlyselected, Object
else if((ob->transflag & OB_DUPLI) && !(ob->transflag & OB_DUPLIFRAMES))
return 0;
+ /* don't add non-basic meta objects, ends up having renderobjects with no geometry */
+ if (ob->type == OB_MBALL && ob!=find_basis_mball(re->scene, ob))
+ return 0;
+
if(nolamps && (ob->type==OB_LAMP))
return 0;
@@ -4605,7 +4609,7 @@ static void add_group_render_dupli_obs(Render *re, Group *group, int nolamps, in
if(ob->flag & OB_DONE) {
if(ob->transflag & OB_RENDER_DUPLI) {
- if(allow_render_object(ob, nolamps, onlyselected, actob)) {
+ if(allow_render_object(re, ob, nolamps, onlyselected, actob)) {
init_render_object(re, ob, NULL, 0, timeoffset, vectorlay);
ob->transflag &= ~OB_RENDER_DUPLI;
@@ -4659,7 +4663,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
/* OB_RENDER_DUPLI means instances for it were already created, now
* it still needs to create the ObjectRen containing the data */
if(ob->transflag & OB_RENDER_DUPLI) {
- if(allow_render_object(ob, nolamps, onlyselected, actob)) {
+ if(allow_render_object(re, ob, nolamps, onlyselected, actob)) {
init_render_object(re, ob, NULL, 0, timeoffset, vectorlay);
ob->transflag &= ~OB_RENDER_DUPLI;
}
@@ -4693,7 +4697,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
if(obd->type==OB_MBALL)
continue;
- if(!allow_render_object(obd, nolamps, onlyselected, actob))
+ if(!allow_render_object(re, obd, nolamps, onlyselected, actob))
continue;
if(allow_render_dupli_instance(re, dob, obd)) {
@@ -4763,10 +4767,10 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
}
free_object_duplilist(lb);
- if(allow_render_object(ob, nolamps, onlyselected, actob))
+ if(allow_render_object(re, ob, nolamps, onlyselected, actob))
init_render_object(re, ob, NULL, 0, timeoffset, vectorlay);
}
- else if(allow_render_object(ob, nolamps, onlyselected, actob))
+ else if(allow_render_object(re, ob, nolamps, onlyselected, actob))
init_render_object(re, ob, NULL, 0, timeoffset, vectorlay);
}
@@ -4844,8 +4848,7 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
/* still bad... doing all */
init_render_textures(re);
- if (re->r.color_mgt_flag & R_COLOR_MANAGEMENT) color_manage_linearize(amb, &re->wrld.ambr);
- else VECCOPY(amb, &re->wrld.ambr);
+ VECCOPY(amb, &re->wrld.ambr);
init_render_materials(re->r.mode, amb);
set_node_shader_lamp_loop(shade_material_loop);
@@ -5534,8 +5537,7 @@ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob)
/* still bad... doing all */
init_render_textures(re);
- if (re->r.color_mgt_flag & R_COLOR_MANAGEMENT) color_manage_linearize(amb, &re->wrld.ambr);
- else VECCOPY(amb, &re->wrld.ambr);
+ VECCOPY(amb, &re->wrld.ambr);
init_render_materials(re->r.mode, amb);
set_node_shader_lamp_loop(shade_material_loop);
diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c
index f62668b84c0..40fcc2b399a 100644
--- a/source/blender/render/intern/source/occlusion.c
+++ b/source/blender/render/intern/source/occlusion.c
@@ -64,7 +64,7 @@
#define CACHE_STEP 3
typedef struct OcclusionCacheSample {
- float co[3], n[3], col[3], intensity, dist2;
+ float co[3], n[3], ao[3], indirect[3], intensity, dist2;
int x, y, filled;
} OcclusionCacheSample;
@@ -81,7 +81,7 @@ typedef struct OccFace {
typedef struct OccNode {
float co[3], area;
float sh[9], dco;
- float occlusion;
+ float occlusion, rad[3];
int childflag;
union {
//OccFace face;
@@ -97,6 +97,7 @@ typedef struct OcclusionTree {
OccFace *face; /* instance and face indices */
float *occlusion; /* occlusion for faces */
+ float (*rad)[3]; /* radiance for faces */
OccNode *root;
@@ -110,6 +111,7 @@ typedef struct OcclusionTree {
int dothreadedbuild;
int totbuildthread;
+ int doindirect;
OcclusionCache *cache;
} OcclusionTree;
@@ -117,7 +119,8 @@ typedef struct OcclusionTree {
typedef struct OcclusionThread {
Render *re;
StrandSurface *mesh;
- float (*facecol)[3];
+ float (*faceao)[3];
+ float (*faceindirect)[3];
int begin, end;
int thread;
} OcclusionThread;
@@ -132,7 +135,6 @@ typedef struct OcclusionBuildThread {
extern Render R; // meh
-#if 0
static void occ_shade(ShadeSample *ssamp, ObjectInstanceRen *obi, VlakRen *vlr, float *rad)
{
ShadeInput *shi= ssamp->shi;
@@ -160,7 +162,7 @@ static void occ_shade(ShadeSample *ssamp, ObjectInstanceRen *obi, VlakRen *vlr,
shi->co[0]= l*v3[0]+u*v1[0]+v*v2[0];
shi->co[1]= l*v3[1]+u*v1[1]+v*v2[1];
shi->co[2]= l*v3[2]+u*v1[2]+v*v2[2];
-
+
shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
/* set up view vector */
@@ -179,6 +181,8 @@ static void occ_shade(ShadeSample *ssamp, ObjectInstanceRen *obi, VlakRen *vlr,
if(shi->flippednor)
shade_input_flip_normals(shi);
+ madd_v3_v3fl(shi->co, shi->vn, 0.0001f); /* ugly.. */
+
/* not a pretty solution, but fixes common cases */
if(shi->obr->ob && shi->obr->ob->transflag & OB_NEG_SCALE) {
negate_v3(shi->vn);
@@ -215,12 +219,11 @@ static void occ_build_shade(Render *re, OcclusionTree *tree)
for(a=0; a<tree->totface; a++) {
obi= &R.objectinstance[tree->face[a].obi];
- vlr= RE_findOrAddVlak(obi->obr, tree->face[a].vlr);
+ vlr= RE_findOrAddVlak(obi->obr, tree->face[a].facenr);
occ_shade(&ssamp, obi, vlr, tree->rad[a]);
}
}
-#endif
/* ------------------------- Spherical Harmonics --------------------------- */
@@ -352,17 +355,19 @@ static void occ_face(const OccFace *face, float *co, float *normal, float *area)
static void occ_sum_occlusion(OcclusionTree *tree, OccNode *node)
{
OccNode *child;
- float occ, area, totarea;
- int a, b;
+ float occ, area, totarea, rad[3];
+ int a, b, indirect= tree->doindirect;
occ= 0.0f;
totarea= 0.0f;
+ if(indirect) zero_v3(rad);
for(b=0; b<TOTCHILD; b++) {
if(node->childflag & (1<<b)) {
a= node->child[b].face;
occ_face(&tree->face[a], 0, 0, &area);
occ += area*tree->occlusion[a];
+ if(indirect) madd_v3_v3fl(rad, tree->rad[a], area);
totarea += area;
}
else if(node->child[b].node) {
@@ -370,14 +375,18 @@ static void occ_sum_occlusion(OcclusionTree *tree, OccNode *node)
occ_sum_occlusion(tree, child);
occ += child->area*child->occlusion;
+ if(indirect) madd_v3_v3fl(rad, child->rad, child->area);
totarea += child->area;
}
}
- if(totarea != 0.0f)
+ if(totarea != 0.0f) {
occ /= totarea;
+ if(indirect) mul_v3_fl(rad, 1.0f/totarea);
+ }
node->occlusion= occ;
+ if(indirect) copy_v3_v3(node->rad, rad);
}
static int occ_find_bbox_axis(OcclusionTree *tree, int begin, int end, float *min, float *max)
@@ -644,6 +653,7 @@ static OcclusionTree *occ_tree_build(Render *re)
/* parameters */
tree->error= get_render_aosss_error(&re->r, re->wrld.ao_approx_error);
tree->distfac= (re->wrld.aomode & WO_AODIST)? re->wrld.aodistfac: 0.0f;
+ tree->doindirect= (re->wrld.ao_indirect_energy > 0.0f && re->wrld.ao_indirect_bounces > 0);
/* allocation */
tree->arena= BLI_memarena_new(0x8000 * sizeof(OccNode));
@@ -656,6 +666,9 @@ static OcclusionTree *occ_tree_build(Render *re)
tree->co= MEM_callocN(sizeof(float)*3*totface, "OcclusionCo");
tree->occlusion= MEM_callocN(sizeof(float)*totface, "OcclusionOcclusion");
+ if(tree->doindirect)
+ tree->rad= MEM_callocN(sizeof(float)*3*totface, "OcclusionRad");
+
/* make array of face pointers */
for(b=0, c=0, obi=re->instancetable.first; obi; obi=obi->next, c++) {
obr= obi->obr;
@@ -682,12 +695,10 @@ static OcclusionTree *occ_tree_build(Render *re)
tree->maxdepth= 1;
occ_build_recursive(tree, tree->root, 0, totface, 1);
-#if 0
if(tree->doindirect) {
occ_build_shade(re, tree);
occ_sum_occlusion(tree, tree->root);
}
-#endif
MEM_freeN(tree->co);
tree->co= NULL;
@@ -710,8 +721,9 @@ static void occ_free_tree(OcclusionTree *tree)
if(tree->stack[a])
MEM_freeN(tree->stack[a]);
if(tree->occlusion) MEM_freeN(tree->occlusion);
- if(tree->face) MEM_freeN(tree->face);
if(tree->cache) MEM_freeN(tree->cache);
+ if(tree->face) MEM_freeN(tree->face);
+ if(tree->rad) MEM_freeN(tree->rad);
MEM_freeN(tree);
}
}
@@ -1171,13 +1183,13 @@ static float occ_form_factor(OccFace *face, float *p, float *n)
return contrib;
}
-static void occ_lookup(OcclusionTree *tree, int thread, OccFace *exclude, float *pp, float *pn, float *occ, float *bentn)
+static void occ_lookup(OcclusionTree *tree, int thread, OccFace *exclude, float *pp, float *pn, float *occ, float rad[3], float bentn[3])
{
OccNode *node, **stack;
OccFace *face;
- float resultocc, v[3], p[3], n[3], co[3], invd2;
+ float resultocc, resultrad[3], v[3], p[3], n[3], co[3], invd2;
float distfac, fac, error, d2, weight, emitarea;
- int b, totstack;
+ int b, f, totstack;
/* init variables */
VECCOPY(p, pp);
@@ -1185,12 +1197,13 @@ static void occ_lookup(OcclusionTree *tree, int thread, OccFace *exclude, float
VECADDFAC(p, p, n, 1e-4f);
if(bentn)
- VECCOPY(bentn, n);
+ copy_v3_v3(bentn, n);
error= tree->error;
distfac= tree->distfac;
resultocc= 0.0f;
+ zero_v3(resultrad);
/* init stack */
stack= tree->stack[thread];
@@ -1217,6 +1230,10 @@ static void occ_lookup(OcclusionTree *tree, int thread, OccFace *exclude, float
/* accumulate occlusion from spherical harmonics */
invd2 = 1.0f/sqrtf(d2);
weight= occ_solid_angle(node, v, d2, invd2, n);
+
+ if(rad)
+ madd_v3_v3fl(resultrad, node->rad, weight*fac);
+
weight *= node->occlusion;
if(bentn) {
@@ -1231,7 +1248,8 @@ static void occ_lookup(OcclusionTree *tree, int thread, OccFace *exclude, float
/* traverse into children */
for(b=0; b<TOTCHILD; b++) {
if(node->childflag & (1<<b)) {
- face= tree->face+node->child[b].face;
+ f= node->child[b].face;
+ face= &tree->face[f];
/* accumulate occlusion with face form factor */
if(!exclude || !(face->obi == exclude->obi && face->facenr == exclude->facenr)) {
@@ -1248,7 +1266,11 @@ static void occ_lookup(OcclusionTree *tree, int thread, OccFace *exclude, float
fac= 1.0f;
weight= occ_form_factor(face, p, n);
- weight *= tree->occlusion[node->child[b].face];
+
+ if(rad)
+ madd_v3_v3fl(resultrad, tree->rad[f], weight*fac);
+
+ weight *= tree->occlusion[f];
if(bentn) {
invd2= 1.0f/sqrtf(d2);
@@ -1269,9 +1291,57 @@ static void occ_lookup(OcclusionTree *tree, int thread, OccFace *exclude, float
}
if(occ) *occ= resultocc;
+ if(rad) copy_v3_v3(rad, resultrad);
+ /*if(rad && exclude) {
+ int a;
+ for(a=0; a<tree->totface; a++)
+ if((tree->face[a].obi == exclude->obi && tree->face[a].facenr == exclude->facenr))
+ copy_v3_v3(rad, tree->rad[a]);
+ }*/
if(bentn) normalize_v3(bentn);
}
+static void occ_compute_bounces(Render *re, OcclusionTree *tree, int totbounce)
+{
+ float (*rad)[3], (*sum)[3], (*tmp)[3], co[3], n[3], occ;
+ int bounce, i;
+
+ rad= MEM_callocN(sizeof(float)*3*tree->totface, "OcclusionBounceRad");
+ sum= MEM_dupallocN(tree->rad);
+
+ for(bounce=1; bounce<totbounce; bounce++) {
+ for(i=0; i<tree->totface; i++) {
+ occ_face(&tree->face[i], co, n, NULL);
+ madd_v3_v3fl(co, n, 1e-8f);
+
+ occ_lookup(tree, 0, &tree->face[i], co, n, &occ, rad[i], NULL);
+ rad[i][0]= MAX2(rad[i][0], 0.0f);
+ rad[i][1]= MAX2(rad[i][1], 0.0f);
+ rad[i][2]= MAX2(rad[i][2], 0.0f);
+ add_v3_v3(sum[i], rad[i]);
+
+ if(re->test_break(re->tbh))
+ break;
+ }
+
+ if(re->test_break(re->tbh))
+ break;
+
+ tmp= tree->rad;
+ tree->rad= rad;
+ rad= tmp;
+
+ occ_sum_occlusion(tree, tree->root);
+ }
+
+ MEM_freeN(rad);
+ MEM_freeN(tree->rad);
+ tree->rad= sum;
+
+ if(!re->test_break(re->tbh))
+ occ_sum_occlusion(tree, tree->root);
+}
+
static void occ_compute_passes(Render *re, OcclusionTree *tree, int totpass)
{
float *occ, co[3], n[3];
@@ -1285,7 +1355,7 @@ static void occ_compute_passes(Render *re, OcclusionTree *tree, int totpass)
negate_v3(n);
VECADDFAC(co, co, n, 1e-8f);
- occ_lookup(tree, 0, &tree->face[i], co, n, &occ[i], NULL);
+ occ_lookup(tree, 0, &tree->face[i], co, n, &occ[i], NULL, NULL);
if(re->test_break(re->tbh))
break;
}
@@ -1305,9 +1375,9 @@ static void occ_compute_passes(Render *re, OcclusionTree *tree, int totpass)
MEM_freeN(occ);
}
-static void sample_occ_tree(Render *re, OcclusionTree *tree, OccFace *exclude, float *co, float *n, int thread, int onlyshadow, float *skycol)
+static void sample_occ_tree(Render *re, OcclusionTree *tree, OccFace *exclude, float *co, float *n, int thread, int onlyshadow, float *ao, float *indirect)
{
- float nn[3], bn[3], fac, occ, occlusion, correction;
+ float nn[3], bn[3], fac, occ, occlusion, correction, rad[3];
int aocolor;
aocolor= re->wrld.aocolor;
@@ -1317,7 +1387,7 @@ static void sample_occ_tree(Render *re, OcclusionTree *tree, OccFace *exclude, f
VECCOPY(nn, n);
negate_v3(nn);
- occ_lookup(tree, thread, exclude, co, nn, &occ, (aocolor)? bn: NULL);
+ occ_lookup(tree, thread, exclude, co, nn, &occ, (tree->doindirect)? rad: NULL, (aocolor)? bn: NULL);
correction= re->wrld.ao_approx_correction;
@@ -1330,9 +1400,9 @@ static void sample_occ_tree(Render *re, OcclusionTree *tree, OccFace *exclude, f
/* sky shading using bent normal */
if(ELEM(aocolor, WO_AOSKYCOL, WO_AOSKYTEX)) {
fac= 0.5*(1.0f+bn[0]*re->grvec[0]+ bn[1]*re->grvec[1]+ bn[2]*re->grvec[2]);
- skycol[0]= (1.0f-fac)*re->wrld.horr + fac*re->wrld.zenr;
- skycol[1]= (1.0f-fac)*re->wrld.horg + fac*re->wrld.zeng;
- skycol[2]= (1.0f-fac)*re->wrld.horb + fac*re->wrld.zenb;
+ ao[0]= (1.0f-fac)*re->wrld.horr + fac*re->wrld.zenr;
+ ao[1]= (1.0f-fac)*re->wrld.horg + fac*re->wrld.zeng;
+ ao[2]= (1.0f-fac)*re->wrld.horb + fac*re->wrld.zenb;
}
#if 0
else { /* WO_AOSKYTEX */
@@ -1343,17 +1413,20 @@ static void sample_occ_tree(Render *re, OcclusionTree *tree, OccFace *exclude, f
dxyview[0]= 1.0f;
dxyview[1]= 1.0f;
dxyview[2]= 0.0f;
- shadeSkyView(skycol, co, bn, dxyview);
+ shadeSkyView(ao, co, bn, dxyview);
}
#endif
- mul_v3_fl(skycol, occlusion);
+ mul_v3_fl(ao, occlusion);
}
else {
- skycol[0]= occlusion;
- skycol[1]= occlusion;
- skycol[2]= occlusion;
+ ao[0]= occlusion;
+ ao[1]= occlusion;
+ ao[2]= occlusion;
}
+
+ if(tree->doindirect) copy_v3_v3(indirect, rad);
+ else zero_v3(indirect);
}
/* ---------------------------- Caching ------------------------------- */
@@ -1374,7 +1447,7 @@ static OcclusionCacheSample *find_occ_sample(OcclusionCache *cache, int x, int y
return &cache->sample[y*cache->w + x];
}
-static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int y, int thread, float *col)
+static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int y, int thread, float *ao, float *indirect)
{
OcclusionCache *cache;
OcclusionCacheSample *samples[4], *sample;
@@ -1394,7 +1467,8 @@ static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int
VECSUB(d, sample->co, co);
dist2= INPR(d, d);
if(dist2 < 0.5f*sample->dist2 && INPR(sample->n, n) > 0.98f) {
- VECCOPY(col, sample->col);
+ VECCOPY(ao, sample->ao);
+ VECCOPY(indirect, sample->indirect);
return 1;
}
}
@@ -1420,7 +1494,8 @@ static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int
return 0;
/* compute weighted interpolation between samples */
- col[0]= col[1]= col[2]= 0.0f;
+ zero_v3(ao);
+ zero_v3(indirect);
totw= 0.0f;
x1= samples[0]->x;
@@ -1446,16 +1521,14 @@ static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int
w= wb[i]*wn[i]*wz[i];
totw += w;
- col[0] += w*samples[i]->col[0];
- col[1] += w*samples[i]->col[1];
- col[2] += w*samples[i]->col[2];
+ madd_v3_v3fl(ao, samples[i]->ao, w);
+ madd_v3_v3fl(indirect, samples[i]->indirect, w);
}
if(totw >= 0.9f) {
totw= 1.0f/totw;
- col[0] *= totw;
- col[1] *= totw;
- col[2] *= totw;
+ mul_v3_fl(ao, totw);
+ mul_v3_fl(indirect, totw);
return 1;
}
@@ -1469,7 +1542,7 @@ static void sample_occ_surface(ShadeInput *shi)
int *face, *index = RE_strandren_get_face(shi->obr, strand, 0);
float w[4], *co1, *co2, *co3, *co4;
- if(mesh && mesh->face && mesh->co && mesh->col && index) {
+ if(mesh && mesh->face && mesh->co && mesh->ao && index) {
face= mesh->face[*index];
co1= mesh->co[face[0]];
@@ -1477,19 +1550,27 @@ static void sample_occ_surface(ShadeInput *shi)
co3= mesh->co[face[2]];
co4= (face[3])? mesh->co[face[3]]: NULL;
- interp_weights_face_v3( w,co1, co2, co3, co4, strand->vert->co);
+ interp_weights_face_v3(w, co1, co2, co3, co4, strand->vert->co);
+
+ zero_v3(shi->ao);
+ zero_v3(shi->indirect);
- shi->ao[0]= shi->ao[1]= shi->ao[2]= 0.0f;
- VECADDFAC(shi->ao, shi->ao, mesh->col[face[0]], w[0]);
- VECADDFAC(shi->ao, shi->ao, mesh->col[face[1]], w[1]);
- VECADDFAC(shi->ao, shi->ao, mesh->col[face[2]], w[2]);
- if(face[3])
- VECADDFAC(shi->ao, shi->ao, mesh->col[face[3]], w[3]);
+ madd_v3_v3fl(shi->ao, mesh->ao[face[0]], w[0]);
+ madd_v3_v3fl(shi->indirect, mesh->indirect[face[0]], w[0]);
+ madd_v3_v3fl(shi->ao, mesh->ao[face[1]], w[1]);
+ madd_v3_v3fl(shi->indirect, mesh->indirect[face[1]], w[1]);
+ madd_v3_v3fl(shi->ao, mesh->ao[face[2]], w[2]);
+ madd_v3_v3fl(shi->indirect, mesh->indirect[face[2]], w[2]);
+ if(face[3]) {
+ madd_v3_v3fl(shi->ao, mesh->ao[face[3]], w[3]);
+ madd_v3_v3fl(shi->indirect, mesh->indirect[face[3]], w[3]);
+ }
}
else {
shi->ao[0]= 1.0f;
shi->ao[1]= 1.0f;
shi->ao[2]= 1.0f;
+ zero_v3(shi->indirect);
}
}
@@ -1500,7 +1581,7 @@ static void *exec_strandsurface_sample(void *data)
OcclusionThread *othread= (OcclusionThread*)data;
Render *re= othread->re;
StrandSurface *mesh= othread->mesh;
- float col[3], co[3], n[3], *co1, *co2, *co3, *co4;
+ float ao[3], indirect[3], co[3], n[3], *co1, *co2, *co3, *co4;
int a, *face;
for(a=othread->begin; a<othread->end; a++) {
@@ -1521,8 +1602,9 @@ static void *exec_strandsurface_sample(void *data)
}
negate_v3(n);
- sample_occ_tree(re, re->occlusiontree, NULL, co, n, othread->thread, 0, col);
- VECCOPY(othread->facecol[a], col);
+ sample_occ_tree(re, re->occlusiontree, NULL, co, n, othread->thread, 0, ao, indirect);
+ VECCOPY(othread->faceao[a], ao);
+ VECCOPY(othread->faceindirect[a], indirect);
}
return 0;
@@ -1531,9 +1613,10 @@ static void *exec_strandsurface_sample(void *data)
void make_occ_tree(Render *re)
{
OcclusionThread othreads[BLENDER_MAX_THREADS];
+ OcclusionTree *tree;
StrandSurface *mesh;
ListBase threads;
- float col[3], (*facecol)[3];
+ float ao[3], indirect[3], (*faceao)[3], (*faceindirect)[3];
int a, totface, totthread, *face, *count;
/* ugly, needed for occ_face */
@@ -1542,24 +1625,28 @@ void make_occ_tree(Render *re)
re->i.infostr= "Occlusion preprocessing";
re->stats_draw(re->sdh, &re->i);
- re->occlusiontree= occ_tree_build(re);
+ re->occlusiontree= tree= occ_tree_build(re);
- if(re->occlusiontree) {
- if(re->wrld.ao_approx_passes)
- occ_compute_passes(re, re->occlusiontree, re->wrld.ao_approx_passes);
+ if(tree) {
+ if(re->wrld.ao_approx_passes > 0)
+ occ_compute_passes(re, tree, re->wrld.ao_approx_passes);
+ if(tree->doindirect && re->wrld.ao_indirect_bounces > 1)
+ occ_compute_bounces(re, tree, re->wrld.ao_indirect_bounces);
for(mesh=re->strandsurface.first; mesh; mesh=mesh->next) {
- if(!mesh->face || !mesh->co || !mesh->col)
+ if(!mesh->face || !mesh->co || !mesh->ao)
continue;
count= MEM_callocN(sizeof(int)*mesh->totvert, "OcclusionCount");
- facecol= MEM_callocN(sizeof(float)*3*mesh->totface, "StrandSurfFaceCol");
+ faceao= MEM_callocN(sizeof(float)*3*mesh->totface, "StrandSurfFaceAO");
+ faceindirect= MEM_callocN(sizeof(float)*3*mesh->totface, "StrandSurfFaceIndirect");
totthread= (mesh->totface > 10000)? re->r.threads: 1;
totface= mesh->totface/totthread;
for(a=0; a<totthread; a++) {
othreads[a].re= re;
- othreads[a].facecol= facecol;
+ othreads[a].faceao= faceao;
+ othreads[a].faceindirect= faceindirect;
othreads[a].thread= a;
othreads[a].mesh= mesh;
othreads[a].begin= a*totface;
@@ -1581,26 +1668,36 @@ void make_occ_tree(Render *re)
for(a=0; a<mesh->totface; a++) {
face= mesh->face[a];
- VECCOPY(col, facecol[a]);
- VECADD(mesh->col[face[0]], mesh->col[face[0]], col);
+ VECCOPY(ao, faceao[a]);
+ VECCOPY(indirect, faceindirect[a]);
+
+ VECADD(mesh->ao[face[0]], mesh->ao[face[0]], ao);
+ VECADD(mesh->indirect[face[0]], mesh->indirect[face[0]], indirect);
count[face[0]]++;
- VECADD(mesh->col[face[1]], mesh->col[face[1]], col);
+ VECADD(mesh->ao[face[1]], mesh->ao[face[1]], ao);
+ VECADD(mesh->indirect[face[1]], mesh->indirect[face[1]], indirect);
count[face[1]]++;
- VECADD(mesh->col[face[2]], mesh->col[face[2]], col);
+ VECADD(mesh->ao[face[2]], mesh->ao[face[2]], ao);
+ VECADD(mesh->indirect[face[2]], mesh->indirect[face[2]], indirect);
count[face[2]]++;
if(face[3]) {
- VECADD(mesh->col[face[3]], mesh->col[face[3]], col);
+ VECADD(mesh->ao[face[3]], mesh->ao[face[3]], ao);
+ VECADD(mesh->indirect[face[3]], mesh->indirect[face[3]], indirect);
count[face[3]]++;
}
}
- for(a=0; a<mesh->totvert; a++)
- if(count[a])
- mul_v3_fl(mesh->col[a], 1.0f/count[a]);
+ for(a=0; a<mesh->totvert; a++) {
+ if(count[a]) {
+ mul_v3_fl(mesh->ao[a], 1.0f/count[a]);
+ mul_v3_fl(mesh->indirect[a], 1.0f/count[a]);
+ }
+ }
MEM_freeN(count);
- MEM_freeN(facecol);
+ MEM_freeN(faceao);
+ MEM_freeN(faceindirect);
}
}
}
@@ -1626,12 +1723,12 @@ void sample_occ(Render *re, ShadeInput *shi)
sample_occ_surface(shi);
}
/* try to get result from the cache if possible */
- else if(shi->depth!=0 || !sample_occ_cache(tree, shi->co, shi->vno, shi->xs, shi->ys, shi->thread, shi->ao)) {
+ else if(shi->depth!=0 || !sample_occ_cache(tree, shi->co, shi->vno, shi->xs, shi->ys, shi->thread, shi->ao, shi->indirect)) {
/* no luck, let's sample the occlusion */
exclude.obi= shi->obi - re->objectinstance;
exclude.facenr= shi->vlr->index;
onlyshadow= (shi->mat->mode & MA_ONLYSHADOW);
- sample_occ_tree(re, tree, &exclude, shi->co, shi->vno, shi->thread, onlyshadow, shi->ao);
+ sample_occ_tree(re, tree, &exclude, shi->co, shi->vno, shi->thread, onlyshadow, shi->ao, shi->indirect);
/* fill result into sample, each time */
if(tree->cache) {
@@ -1641,8 +1738,10 @@ void sample_occ(Render *re, ShadeInput *shi)
sample= &cache->sample[(shi->ys-cache->y)*cache->w + (shi->xs-cache->x)];
VECCOPY(sample->co, shi->co);
VECCOPY(sample->n, shi->vno);
- VECCOPY(sample->col, shi->ao);
- sample->intensity= MAX3(sample->col[0], sample->col[1], sample->col[2]);
+ VECCOPY(sample->ao, shi->ao);
+ VECCOPY(sample->indirect, shi->indirect);
+ sample->intensity= MAX3(sample->ao[0], sample->ao[1], sample->ao[2]);
+ sample->intensity= MAX2(sample->intensity, MAX3(sample->indirect[0], sample->indirect[1], sample->indirect[2]));
sample->dist2= INPR(shi->dxco, shi->dxco) + INPR(shi->dyco, shi->dyco);
sample->filled= 1;
}
@@ -1653,6 +1752,10 @@ void sample_occ(Render *re, ShadeInput *shi)
shi->ao[0]= 1.0f;
shi->ao[1]= 1.0f;
shi->ao[2]= 1.0f;
+
+ shi->indirect[0]= 0.0f;
+ shi->indirect[1]= 0.0f;
+ shi->indirect[2]= 0.0f;
}
}
@@ -1720,12 +1823,14 @@ void cache_occ_samples(Render *re, RenderPart *pa, ShadeSample *ssamp)
onlyshadow= (shi->mat->mode & MA_ONLYSHADOW);
exclude.obi= shi->obi - re->objectinstance;
exclude.facenr= shi->vlr->index;
- sample_occ_tree(re, tree, &exclude, shi->co, shi->vno, shi->thread, onlyshadow, shi->ao);
+ sample_occ_tree(re, tree, &exclude, shi->co, shi->vno, shi->thread, onlyshadow, shi->ao, shi->indirect);
VECCOPY(sample->co, shi->co);
VECCOPY(sample->n, shi->vno);
- VECCOPY(sample->col, shi->ao);
- sample->intensity= MAX3(sample->col[0], sample->col[1], sample->col[2]);
+ VECCOPY(sample->ao, shi->ao);
+ VECCOPY(sample->indirect, shi->indirect);
+ sample->intensity= MAX3(sample->ao[0], sample->ao[1], sample->ao[2]);
+ sample->intensity= MAX2(sample->intensity, MAX3(sample->indirect[0], sample->indirect[1], sample->indirect[2]));
sample->dist2= INPR(shi->dxco, shi->dxco) + INPR(shi->dyco, shi->dyco);
sample->x= shi->xs;
sample->y= shi->ys;
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index b357a17e244..e2b290f655b 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -48,8 +48,9 @@
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */
-#include "BKE_sequence.h"
+#include "BKE_sequencer.h"
#include "BKE_pointcache.h"
+#include "BKE_animsys.h" /* <------ should this be here?, needed for sequencer update */
#include "MEM_guardedalloc.h"
@@ -1065,12 +1066,25 @@ void RE_ResultGet32(Render *re, unsigned int *rect)
int tot= rres.rectx*rres.recty;
char *cp= (char *)rect;
- for(;tot>0; tot--, cp+=4, fp+=4) {
- cp[0] = FTOCHAR(fp[0]);
- cp[1] = FTOCHAR(fp[1]);
- cp[2] = FTOCHAR(fp[2]);
- cp[3] = FTOCHAR(fp[3]);
+ if (re->r.color_mgt_flag & R_COLOR_MANAGEMENT) {
+ /* Finally convert back to sRGB rendered image */
+ for(;tot>0; tot--, cp+=4, fp+=4) {
+ cp[0] = FTOCHAR(linearrgb_to_srgb(fp[0]));
+ cp[1] = FTOCHAR(linearrgb_to_srgb(fp[1]));
+ cp[2] = FTOCHAR(linearrgb_to_srgb(fp[2]));
+ cp[3] = FTOCHAR(fp[3]);
+ }
+ }
+ else {
+ /* Color management is off : no conversion necessary */
+ for(;tot>0; tot--, cp+=4, fp+=4) {
+ cp[0] = FTOCHAR(fp[0]);
+ cp[1] = FTOCHAR(fp[1]);
+ cp[2] = FTOCHAR(fp[2]);
+ cp[3] = FTOCHAR(fp[3]);
+ }
}
+
}
else
/* else fill with black */
@@ -2426,6 +2440,11 @@ static void do_render_seq(Render * re)
RenderResult *rr = re->result;
int cfra = re->r.cfra;
+ if(recurs_depth==0) {
+ /* otherwise sequencer animation isnt updated */
+ BKE_animsys_evaluate_all_animation(G.main, (float)cfra); // XXX, was frame_to_float(re->scene, cfra)
+ }
+
recurs_depth++;
ibuf= give_ibuf_seq(re->scene, rr->rectx, rr->recty, cfra, 0, 100.0);
@@ -2485,6 +2504,12 @@ static void do_render_seq(Render * re)
/* main loop: doing sequence + fields + blur + 3d render + compositing */
static void do_render_all_options(Render *re)
{
+#ifdef DURIAN_CAMERA_SWITCH
+ Object *camera= scene_find_camera_switch(re->scene);
+ if(camera)
+ re->scene->camera= camera;
+#endif
+
re->i.starttime= PIL_check_seconds_timer();
/* ensure no images are in memory from previous animated sequences */
@@ -2727,10 +2752,11 @@ void RE_BlenderFrame(Render *re, Scene *scene, int frame)
re->result_ok= 1;
}
-static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
+static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, ReportList *reports)
{
char name[FILE_MAX];
RenderResult rres;
+ int ok= 1;
RE_AcquireResultImage(re, &rres);
@@ -2743,7 +2769,7 @@ static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
dofree = 1;
}
RE_ResultGet32(re, (unsigned int *)rres.rect32);
- mh->append_movie(&re->r, scene->r.cfra, rres.rect32, rres.rectx, rres.recty);
+ ok= mh->append_movie(&re->r, scene->r.cfra, rres.rect32, rres.rectx, rres.recty, reports);
if(dofree) {
MEM_freeN(rres.rect32);
}
@@ -2760,7 +2786,6 @@ static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
}
else {
ImBuf *ibuf= IMB_allocImBuf(rres.rectx, rres.recty, scene->r.planes, 0, 0);
- int ok;
/* if not exists, BKE_write_ibuf makes one */
ibuf->rect= (unsigned int *)rres.rect32;
@@ -2777,7 +2802,6 @@ static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
if(ok==0) {
printf("Render error: cannot save %s\n", name);
- G.afbreek=1;
}
else printf("Saved: %s", name);
@@ -2801,10 +2825,12 @@ static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
BLI_timestr(re->i.lastframetime, name);
printf(" Time: %s\n", name);
fflush(stdout); /* needed for renderd !! (not anymore... (ton)) */
+
+ return ok;
}
/* saves images to disk */
-void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra)
+void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra, ReportList *reports)
{
bMovieHandle *mh= BKE_get_movie_handle(scene->r.imtype);
unsigned int lay;
@@ -2821,18 +2847,20 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra)
re->result_ok= 0;
if(BKE_imtype_is_movie(scene->r.imtype))
- mh->start_movie(scene, &re->r, re->rectx, re->recty);
-
+ if(!mh->start_movie(scene, &re->r, re->rectx, re->recty, reports))
+ G.afbreek= 1;
+
if (mh->get_next_frame) {
while (!(G.afbreek == 1)) {
- int nf = mh->get_next_frame(&re->r);
+ int nf = mh->get_next_frame(&re->r, reports);
if (nf >= 0 && nf >= scene->r.sfra && nf <= scene->r.efra) {
scene->r.cfra = re->r.cfra = nf;
do_render_all_options(re);
if(re->test_break(re->tbh) == 0) {
- do_write_image_or_movie(re, scene, mh);
+ if(!do_write_image_or_movie(re, scene, mh, reports))
+ G.afbreek= 1;
}
} else {
if(re->test_break(re->tbh))
@@ -2882,8 +2910,11 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra)
do_render_all_options(re);
- if(re->test_break(re->tbh) == 0)
- do_write_image_or_movie(re, scene, mh);
+ if(re->test_break(re->tbh) == 0) {
+ if(!G.afbreek)
+ if(!do_write_image_or_movie(re, scene, mh, reports))
+ G.afbreek= 1;
+ }
else
G.afbreek= 1;
diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c
index d4b7c403f50..6fef8279c7e 100644
--- a/source/blender/render/intern/source/pixelshading.c
+++ b/source/blender/render/intern/source/pixelshading.c
@@ -537,15 +537,9 @@ void shadeSkyView(float *colf, float *rco, float *view, float *dxyview, short th
/* the fraction of how far we are above the bottom of the screen */
blend= fabs(0.5+ view[1]);
}
-
- if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
- color_manage_linearize(hor, &R.wrld.horr);
- color_manage_linearize(zen, &R.wrld.zenr);
- }
- else {
- VECCOPY(hor, &R.wrld.horr);
- VECCOPY(zen, &R.wrld.zenr);
- }
+
+ VECCOPY(hor, &R.wrld.horr);
+ VECCOPY(zen, &R.wrld.zenr);
/* Careful: SKYTEX and SKYBLEND are NOT mutually exclusive! If */
/* SKYBLEND is active, the texture and color blend are added. */
@@ -633,10 +627,7 @@ void shadeSkyPixel(float *collector, float fx, float fy, short thread)
}
else if((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) {
/* 2. solid color */
- if(R.r.color_mgt_flag & R_COLOR_MANAGEMENT)
- color_manage_linearize(collector, &R.wrld.horr);
- else
- VECCOPY(collector, &R.wrld.horr);
+ VECCOPY(collector, &R.wrld.horr);
collector[3] = 0.0f;
}
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index 396c713cfb7..fd1e27ab28a 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -91,42 +91,16 @@ extern struct Render R;
* doing inverse gamma correction where applicable */
void shade_input_init_material(ShadeInput *shi)
{
- if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
- color_manage_linearize(&shi->r, &shi->mat->r);
- color_manage_linearize(&shi->specr, &shi->mat->specr);
- color_manage_linearize(&shi->mirr, &shi->mat->mirr);
-
- /* material ambr / ambg / ambb is overwritten from world
- color_manage_linearize(shi->ambr, shi->mat->ambr);
- */
-
- /* note, keep this synced with render_types.h */
- memcpy(&shi->amb, &shi->mat->amb, 11*sizeof(float));
- shi->har= shi->mat->har;
- } else {
- /* note, keep this synced with render_types.h */
- memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
- shi->har= shi->mat->har;
- }
-
-}
-
-static void shadeinput_colors_linearize(ShadeInput *shi)
-{
- color_manage_linearize(&shi->r, &shi->r);
- color_manage_linearize(&shi->specr, &shi->specr);
- color_manage_linearize(&shi->mirr, &shi->mirr);
+ /* note, keep this synced with render_types.h */
+ memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
+ shi->har= shi->mat->har;
}
/* also used as callback for nodes */
/* delivers a fully filled in ShadeResult, for all passes */
void shade_material_loop(ShadeInput *shi, ShadeResult *shr)
{
- /* because node materials don't have access to rendering context,
- * inverse gamma correction must happen here. evil. */
- if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT && shi->nodes == 1)
- shadeinput_colors_linearize(shi);
-
+
shade_lamp_loop(shi, shr); /* clears shr */
if(shi->translucency!=0.0f) {
@@ -626,7 +600,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
if(mode & (MA_VERTEXCOL|MA_VERTEXCOLP|MA_FACETEXTURE)) {
- color_manage_linearize(shi->vcol, shi->vcol);
+ srgb_to_linearrgb_v3_v3(shi->vcol, shi->vcol);
}
}
@@ -1291,7 +1265,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
*/
if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
if(mode & (MA_VERTEXCOL|MA_VERTEXCOLP|MA_FACETEXTURE)) {
- color_manage_linearize(shi->vcol, shi->vcol);
+ srgb_to_linearrgb_v3_v3(shi->vcol, shi->vcol);
}
}
diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c
index b98d0c74bea..4596938b536 100644
--- a/source/blender/render/intern/source/shadeoutput.c
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -1022,6 +1022,7 @@ void ambient_occlusion_to_diffuse(ShadeInput *shi, float *diff)
}
VECMUL(diff, f);
+ madd_v3_v3fl(diff, shi->indirect, R.wrld.ao_indirect_energy*shi->amb);
}
else
diff[0]= diff[1]= diff[2]= 0.0f;
diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c
index 25cfc0f1253..e551cf0f3d2 100644
--- a/source/blender/render/intern/source/sss.c
+++ b/source/blender/render/intern/source/sss.c
@@ -926,20 +926,17 @@ static void sss_create_tree_mat(Render *re, Material *mat)
if(!re->test_break(re->tbh)) {
SSSData *sss= MEM_callocN(sizeof(*sss), "SSSData");
float ior= mat->sss_ior, cfac= mat->sss_colfac;
- float col[3], *radius= mat->sss_radius;
+ float *radius= mat->sss_radius;
float fw= mat->sss_front, bw= mat->sss_back;
float error = mat->sss_error;
error= get_render_aosss_error(&re->r, error);
if((re->r.scemode & R_PREVIEWBUTS) && error < 0.5f)
error= 0.5f;
-
- if (re->r.color_mgt_flag & R_COLOR_MANAGEMENT) color_manage_linearize(col, mat->sss_col);
- else VECCOPY(col, mat->sss_col);
- sss->ss[0]= scatter_settings_new(col[0], radius[0], ior, cfac, fw, bw);
- sss->ss[1]= scatter_settings_new(col[1], radius[1], ior, cfac, fw, bw);
- sss->ss[2]= scatter_settings_new(col[2], radius[2], ior, cfac, fw, bw);
+ sss->ss[0]= scatter_settings_new(mat->sss_col[0], radius[0], ior, cfac, fw, bw);
+ sss->ss[1]= scatter_settings_new(mat->sss_col[1], radius[1], ior, cfac, fw, bw);
+ sss->ss[2]= scatter_settings_new(mat->sss_col[2], radius[2], ior, cfac, fw, bw);
sss->tree= scatter_tree_new(sss->ss, mat->sss_scale, error,
co, color, area, totpoint);
diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c
index 9a5ef531f0a..3656b2a359d 100644
--- a/source/blender/render/intern/source/strand.c
+++ b/source/blender/render/intern/source/strand.c
@@ -959,7 +959,8 @@ StrandSurface *cache_strand_surface(Render *re, ObjectRen *obr, DerivedMesh *dm,
mesh->totvert= totvert;
mesh->totface= totface;
mesh->face= MEM_callocN(sizeof(int)*4*mesh->totface, "StrandSurfFaces");
- mesh->col= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfCol");
+ mesh->ao= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfAO");
+ mesh->indirect= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfIndirect");
BLI_addtail(&re->strandsurface, mesh);
}
@@ -997,7 +998,8 @@ void free_strand_surface(Render *re)
if(mesh->co) MEM_freeN(mesh->co);
if(mesh->prevco) MEM_freeN(mesh->prevco);
if(mesh->nextco) MEM_freeN(mesh->nextco);
- if(mesh->col) MEM_freeN(mesh->col);
+ if(mesh->ao) MEM_freeN(mesh->ao);
+ if(mesh->indirect) MEM_freeN(mesh->indirect);
if(mesh->face) MEM_freeN(mesh->face);
}
diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c
index a9f6e7a53fd..9d03889a747 100644
--- a/source/blender/render/intern/source/texture.c
+++ b/source/blender/render/intern/source/texture.c
@@ -1495,6 +1495,14 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen
in= 1.0-(facm+fact*(1.0-tex))*(1.0-out);
break;
+ case MTEX_OVERLAY:
+ facm= 1.0-facg;
+ if(out < 0.5f)
+ in = out * (facm + 2.0f*fact*tex);
+ else
+ in = 1.0f - (facm + 2.0f*fact*(1.0 - tex)) * (1.0 - out);
+ break;
+
case MTEX_SUB:
fact= -fact;
case MTEX_ADD:
@@ -2051,8 +2059,13 @@ void do_material_tex(ShadeInput *shi)
else texres.tin= texres.ta;
/* inverse gamma correction */
- if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
- color_manage_linearize(tcol, tcol);
+ if (tex->type==TEX_IMAGE) {
+ Image *ima = tex->ima;
+ ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser);
+
+ /* don't linearize float buffers, assumed to be linear */
+ if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT)
+ srgb_to_linearrgb_v3_v3(tcol, tcol);
}
if(mtex->mapto & MAP_COL) {
@@ -2404,11 +2417,6 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa
texres.tin= texres.ta;
}
- /* inverse gamma correction */
- if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
- color_manage_linearize(tcol, tcol);
- }
-
/* used for emit */
if((mapto_flag & MAP_EMISSION_COL) && (mtex->mapto & MAP_EMISSION_COL)) {
float colemitfac= mtex->colemitfac*stencilTin;
@@ -2556,8 +2564,13 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float *colf)
else texres.tin= texres.ta;
/* inverse gamma correction */
- if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
- color_manage_linearize(&texres.tr, &texres.tr);
+ if (mtex->tex->type==TEX_IMAGE) {
+ Image *ima = mtex->tex->ima;
+ ImBuf *ibuf = BKE_image_get_ibuf(ima, &mtex->tex->iuser);
+
+ /* don't linearize float buffers, assumed to be linear */
+ if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT)
+ srgb_to_linearrgb_v3_v3(&texres.tr, &texres.tr);
}
fact= texres.tin*mtex->colfac;
@@ -2605,6 +2618,7 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float *colf)
void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, float *blend, int skyflag, short thread)
{
MTex *mtex;
+ Tex *tex;
TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
float *co, fact, stencilTin=1.0;
float tempvec[3], texvec[3], dxt[3], dyt[3];
@@ -2618,7 +2632,8 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f
if(R.wrld.mtex[tex_nr]) {
mtex= R.wrld.mtex[tex_nr];
- if(mtex->tex==0) continue;
+ tex= mtex->tex;
+ if(tex==0) continue;
/* if(mtex->mapto==0) continue; */
/* which coords */
@@ -2700,7 +2715,7 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f
else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
/* texture */
- if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
+ if(tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
rgb= multitex(mtex->tex, texvec, dxt, dyt, R.osa, &texres, thread, mtex->which_output);
@@ -2748,8 +2763,13 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f
tcol[0]= texres.tr; tcol[1]= texres.tg; tcol[2]= texres.tb;
/* inverse gamma correction */
- if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
- color_manage_linearize(tcol, tcol);
+ if (tex->type==TEX_IMAGE) {
+ Image *ima = tex->ima;
+ ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser);
+
+ /* don't linearize float buffers, assumed to be linear */
+ if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT)
+ srgb_to_linearrgb_v3_v3(tcol, tcol);
}
if(mtex->mapto & WOMAP_HORIZ) {
@@ -2947,8 +2967,13 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int ef
else texres.tin= texres.ta;
/* inverse gamma correction */
- if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
- color_manage_linearize(&texres.tr, &texres.tr);
+ if (tex->type==TEX_IMAGE) {
+ Image *ima = tex->ima;
+ ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser);
+
+ /* don't linearize float buffers, assumed to be linear */
+ if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT)
+ srgb_to_linearrgb_v3_v3(&texres.tr, &texres.tr);
}
/* lamp colors were premultiplied with this */
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index a3a714553d2..ac3474e51e5 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -2587,14 +2587,14 @@ void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(vo
v3= vlr->v3;
v4= vlr->v4;
- c1= zbuf_part_project(cache, v1->index, winmat, bounds, v1->co, ho1);
- c2= zbuf_part_project(cache, v2->index, winmat, bounds, v2->co, ho2);
- c3= zbuf_part_project(cache, v3->index, winmat, bounds, v3->co, ho3);
+ c1= zbuf_part_project(cache, v1->index, obwinmat, bounds, v1->co, ho1);
+ c2= zbuf_part_project(cache, v2->index, obwinmat, bounds, v2->co, ho2);
+ c3= zbuf_part_project(cache, v3->index, obwinmat, bounds, v3->co, ho3);
/* partclipping doesn't need viewplane clipping */
partclip= c1 & c2 & c3;
if(v4) {
- c4= zbuf_part_project(cache, v4->index, winmat, bounds, v4->co, ho4);
+ c4= zbuf_part_project(cache, v4->index, obwinmat, bounds, v4->co, ho4);
partclip &= c4;
}