diff options
Diffstat (limited to 'source/blender/render/intern/source')
-rw-r--r-- | source/blender/render/intern/source/bake_api.c | 4 | ||||
-rw-r--r-- | source/blender/render/intern/source/convertblender.c | 20 | ||||
-rw-r--r-- | source/blender/render/intern/source/envmap.c | 16 | ||||
-rw-r--r-- | source/blender/render/intern/source/external_engine.c | 41 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 79 | ||||
-rw-r--r-- | source/blender/render/intern/source/render_result.c | 671 | ||||
-rw-r--r-- | source/blender/render/intern/source/render_texture.c | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/rendercore.c | 410 | ||||
-rw-r--r-- | source/blender/render/intern/source/renderdatabase.c | 9 | ||||
-rw-r--r-- | source/blender/render/intern/source/shadeoutput.c | 10 | ||||
-rw-r--r-- | source/blender/render/intern/source/sunsky.c | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/volumetric.c | 6 | ||||
-rw-r--r-- | source/blender/render/intern/source/zbuf.c | 229 |
13 files changed, 692 insertions, 807 deletions
diff --git a/source/blender/render/intern/source/bake_api.c b/source/blender/render/intern/source/bake_api.c index 73424a4e846..588c327ab91 100644 --- a/source/blender/render/intern/source/bake_api.c +++ b/source/blender/render/intern/source/bake_api.c @@ -684,6 +684,10 @@ void RE_bake_pixels_populate( int mat_nr = mp->mat_nr; int image_id = bake_images->lookup[mat_nr]; + if (image_id < 0) { + continue; + } + bd.bk_image = &bake_images->data[image_id]; bd.primitive_id = ++p_id; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 263ea3d4ef2..9633d95855e 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -3439,10 +3439,9 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) if (need_nmap_tangent_concrete || need_tangent) { int uv_start = CustomData_get_layer_index(&dm->faceData, CD_MTFACE); int uv_index = CustomData_get_named_layer_index(&dm->faceData, CD_MTFACE, layer->name); - BLI_assert(uv_start >= 0 && uv_index >= 0); - if ((uv_start < 0 || uv_index < 0)) - continue; - int n = uv_index - uv_start; + + /* if there are no UVs, orco tangents are in first slot */ + int n = (uv_start >= 0 && uv_index >= 0) ? uv_index - uv_start : 0; const float *tangent = (const float *) layer->data; float *ftang = RE_vlakren_get_nmap_tangent(obr, vlr, n, true); @@ -4658,14 +4657,22 @@ static void add_render_object(Render *re, Object *ob, Object *par, DupliObject * index= (dob)? dob->persistent_id[0]: 0; + /* It seems that we may generate psys->renderdata recursively in some nasty intricated cases of + * several levels of bupliobject (see T51524). + * For now, basic rule is, do not restore psys if it was already in 'render state'. + * Another, more robust solution could be to add some reference counting to that renderdata... */ + bool psys_has_renderdata = false; + /* the emitter has to be processed first (render levels of modifiers) */ /* so here we only check if the emitter should be rendered */ if (ob->particlesystem.first) { show_emitter= 0; for (psys=ob->particlesystem.first; psys; psys=psys->next) { show_emitter += psys->part->draw & PART_DRAW_EMITTER; - if (!(re->r.scemode & R_VIEWPORT_PREVIEW)) + if (!(re->r.scemode & R_VIEWPORT_PREVIEW)) { + psys_has_renderdata |= (psys->renderdata != NULL); psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, timeoffset); + } } /* if no psys has "show emitter" selected don't render emitter */ @@ -4712,8 +4719,9 @@ static void add_render_object(Render *re, Object *ob, Object *par, DupliObject * if (dob) psys->flag |= PSYS_USE_IMAT; init_render_object_data(re, obr, timeoffset); - if (!(re->r.scemode & R_VIEWPORT_PREVIEW)) + if (!(re->r.scemode & R_VIEWPORT_PREVIEW) && !psys_has_renderdata) { psys_render_restore(ob, psys); + } psys->flag &= ~PSYS_USE_IMAT; /* only add instance for objects that have not been used for dupli */ diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index d97e18d6511..156b4215992 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -61,6 +61,7 @@ #include "renderpipeline.h" #include "texture.h" #include "zbuf.h" +#include "render_result.h" /* ------------------------------------------------------------------------- */ @@ -142,8 +143,8 @@ static Render *envmap_render_copy(Render *re, EnvMap *env) /* set up renderdata */ render_copy_renderdata(&envre->r, &re->r); envre->r.mode &= ~(R_BORDER | R_PANORAMA | R_ORTHO | R_MBLUR); - BLI_listbase_clear(&envre->r.layers); - BLI_listbase_clear(&envre->r.views); + BLI_freelistN(&envre->r.layers); + BLI_freelistN(&envre->r.views); envre->r.filtertype = 0; envre->r.tilex = envre->r.xsch / 2; envre->r.tiley = envre->r.ysch / 2; @@ -493,13 +494,20 @@ static void render_envmap(Render *re, EnvMap *env) env_rotate_scene(envre, tmat, 0); if (re->test_break(re->tbh) == 0) { - RenderLayer *rl = envre->result->layers.first; int y; float *alpha; float *rect; + if (envre->result->do_exr_tile) { + BLI_rw_mutex_lock(&envre->resultmutex, THREAD_LOCK_WRITE); + render_result_exr_file_end(envre); + BLI_rw_mutex_unlock(&envre->resultmutex); + } + + RenderLayer *rl = envre->result->layers.first; + /* envmap is rendered independently of multiview */ - rect = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, ""); + rect = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, ""); ibuf = IMB_allocImBuf(envre->rectx, envre->recty, 24, IB_rect | IB_rectfloat); memcpy(ibuf->rect_float, rect, ibuf->channels * ibuf->x * ibuf->y * sizeof(float)); diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index fd9d95c63b6..a581f7bd198 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -62,13 +62,14 @@ #include "renderpipeline.h" #include "render_types.h" #include "render_result.h" +#include "rendercore.h" /* Render Engine Types */ static RenderEngineType internal_render_type = { NULL, NULL, "BLENDER_RENDER", N_("Blender Render"), RE_INTERNAL, - NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, render_internal_update_passes, {NULL, NULL, NULL} }; @@ -77,7 +78,7 @@ static RenderEngineType internal_render_type = { static RenderEngineType internal_game_type = { NULL, NULL, "BLENDER_GAME", N_("Blender Game"), RE_INTERNAL | RE_GAME, - NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, {NULL, NULL, NULL} }; @@ -212,6 +213,8 @@ RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, /* can be NULL if we CLAMP the width or height to 0 */ if (result) { + render_result_clone_passes(re, result, viewname); + RenderPart *pa; /* Copy EXR tile settings, so pipeline knows whether this is a result @@ -245,7 +248,18 @@ void RE_engine_update_result(RenderEngine *engine, RenderResult *result) } } -void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel, int merge_results) +void RE_engine_add_pass(RenderEngine *engine, const char *name, int channels, const char *chan_id, const char *layername) +{ + Render *re = engine->re; + + if (!re || !re->result) { + return; + } + + render_result_add_pass(re->result, name, channels, chan_id, layername, NULL); +} + +void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel, int highlight, int merge_results) { Render *re = engine->re; @@ -254,7 +268,7 @@ void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel } /* merge. on break, don't merge in result for preview renders, looks nicer */ - if (!cancel) { + if (!highlight) { /* for exr tile render, detect tiles that are done */ RenderPart *pa = get_part_from_result(re, result); @@ -760,3 +774,22 @@ int RE_engine_render(Render *re, int do_all) return 1; } +void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl, + const char *name, int UNUSED(channels), const char *UNUSED(chanid), int type) +{ + /* The channel information is currently not used, but is part of the API in case it's needed in the future. */ + + if (!(scene && srl && engine)) { + return; + } + + /* Register the pass in all scenes that have a render layer node for this layer. + * Since multiple scenes can be used in the compositor, the code must loop over all scenes + * and check whether their nodetree has a node that needs to be updated. */ + Scene *sce; + for (sce = G.main->scene.first; sce; sce = sce->id.next) { + if (sce->nodetree) { + ntreeCompositRegisterPass(sce->nodetree, scene, srl, name, type); + } + } +} diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 52eca5f7005..e078365e1ed 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -239,9 +239,9 @@ void RE_FreeRenderResult(RenderResult *res) render_result_free(res); } -float *RE_RenderLayerGetPass(volatile RenderLayer *rl, int passtype, const char *viewname) +float *RE_RenderLayerGetPass(volatile RenderLayer *rl, const char *name, const char *viewname) { - RenderPass *rpass = RE_pass_find_by_type(rl, passtype, viewname); + RenderPass *rpass = RE_pass_find_by_name(rl, name, viewname); return rpass ? rpass->rect : NULL; } @@ -382,13 +382,13 @@ void RE_AcquireResultImageViews(Render *re, RenderResult *rr) if (rl) { if (rv->rectf == NULL) { for (rview = (RenderView *)rr->views.first; rview; rview = rview->next) { - rview->rectf = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, rview->name); + rview->rectf = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, rview->name); } } if (rv->rectz == NULL) { for (rview = (RenderView *)rr->views.first; rview; rview = rview->next) { - rview->rectz = RE_RenderLayerGetPass(rl, SCE_PASS_Z, rview->name); + rview->rectz = RE_RenderLayerGetPass(rl, RE_PASSNAME_Z, rview->name); } } } @@ -442,10 +442,10 @@ void RE_AcquireResultImage(Render *re, RenderResult *rr, const int view_id) if (rl) { if (rv->rectf == NULL) - rr->rectf = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, rv->name); + rr->rectf = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, rv->name); if (rv->rectz == NULL) - rr->rectz = RE_RenderLayerGetPass(rl, SCE_PASS_Z, rv->name); + rr->rectz = RE_RenderLayerGetPass(rl, RE_PASSNAME_Z, rv->name); } rr->have_combined = (rv->rectf != NULL); @@ -723,6 +723,8 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, re->r.size = source->r.size; } + re_init_resolution(re, source, winx, winy, disprect); + /* disable border if it's a full render anyway */ if (re->r.border.xmin == 0.0f && re->r.border.xmax == 1.0f && re->r.border.ymin == 0.0f && re->r.border.ymax == 1.0f) @@ -730,8 +732,6 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, re->r.mode &= ~R_BORDER; } - re_init_resolution(re, source, winx, winy, disprect); - if (re->rectx < 1 || re->recty < 1 || (BKE_imtype_is_movie(rd->im_format.imtype) && (re->rectx < 16 || re->recty < 16) )) { @@ -842,7 +842,7 @@ static void render_result_rescale(Render *re) if (src_rectf == NULL) { RenderLayer *rl = render_get_active_layer(re, re->result); if (rl != NULL) { - src_rectf = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, NULL); + src_rectf = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, NULL); } } @@ -861,7 +861,7 @@ static void render_result_rescale(Render *re) RenderLayer *rl; rl = render_get_active_layer(re, re->result); if (rl != NULL) { - dst_rectf = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, NULL); + dst_rectf = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, NULL); } } @@ -1655,7 +1655,7 @@ static void merge_renderresult_blur(RenderResult *rr, RenderResult *brr, float b /* passes are allocated in sync */ rpass1 = rl1->passes.first; for (rpass = rl->passes.first; rpass && rpass1; rpass = rpass->next, rpass1 = rpass1->next) { - if ((rpass->passtype & SCE_PASS_COMBINED) && key_alpha) + if (STREQ(rpass->name, RE_PASSNAME_COMBINED) && key_alpha) addblur_rect_key(rr, rpass->rect, rpass1->rect, blurfac); else addblur_rect(rr, rpass->rect, rpass1->rect, blurfac, rpass->channels); @@ -1855,6 +1855,8 @@ static void render_result_uncrop(Render *re) rres = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS); + render_result_clone_passes(re, rres, NULL); + render_result_merge(rres, re->result); render_result_free(re->result); re->result = rres; @@ -3887,7 +3889,7 @@ void RE_layer_load_from_file(RenderLayer *layer, ReportList *reports, const char /* multiview: since the API takes no 'view', we use the first combined pass found */ for (rpass = layer->passes.first; rpass; rpass = rpass->next) - if (rpass->passtype == SCE_PASS_COMBINED) + if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) break; if (rpass == NULL) @@ -4013,13 +4015,12 @@ bool RE_layers_have_name(struct RenderResult *rr) return false; } -RenderPass *RE_pass_find_by_type(volatile RenderLayer *rl, int passtype, const char *viewname) +RenderPass *RE_pass_find_by_name(volatile RenderLayer *rl, const char *name, const char *viewname) { RenderPass *rp = NULL; for (rp = rl->passes.last; rp; rp = rp->prev) { - if (rp->passtype == passtype) { - + if (STREQ(rp->name, name)) { if (viewname == NULL || viewname[0] == '\0') break; else if (STREQ(rp->view, viewname)) @@ -4029,6 +4030,50 @@ RenderPass *RE_pass_find_by_type(volatile RenderLayer *rl, int passtype, const c return rp; } +/* Only provided for API compatibility, don't use this in new code! */ +RenderPass *RE_pass_find_by_type(volatile RenderLayer *rl, int passtype, const char *viewname) +{ +#define CHECK_PASS(NAME) \ + if (passtype == SCE_PASS_ ## NAME) \ + return RE_pass_find_by_name(rl, RE_PASSNAME_ ## NAME, viewname); + + CHECK_PASS(COMBINED); + CHECK_PASS(Z); + CHECK_PASS(VECTOR); + CHECK_PASS(NORMAL); + CHECK_PASS(UV); + CHECK_PASS(RGBA); + CHECK_PASS(EMIT); + CHECK_PASS(DIFFUSE); + CHECK_PASS(SPEC); + CHECK_PASS(SHADOW); + CHECK_PASS(AO); + CHECK_PASS(ENVIRONMENT); + CHECK_PASS(INDIRECT); + CHECK_PASS(REFLECT); + CHECK_PASS(REFRACT); + CHECK_PASS(INDEXOB); + CHECK_PASS(INDEXMA); + CHECK_PASS(MIST); + CHECK_PASS(RAYHITS); + CHECK_PASS(DIFFUSE_DIRECT); + CHECK_PASS(DIFFUSE_INDIRECT); + CHECK_PASS(DIFFUSE_COLOR); + CHECK_PASS(GLOSSY_DIRECT); + CHECK_PASS(GLOSSY_INDIRECT); + CHECK_PASS(GLOSSY_COLOR); + CHECK_PASS(TRANSM_DIRECT); + CHECK_PASS(TRANSM_INDIRECT); + CHECK_PASS(TRANSM_COLOR); + CHECK_PASS(SUBSURFACE_DIRECT); + CHECK_PASS(SUBSURFACE_INDIRECT); + CHECK_PASS(SUBSURFACE_COLOR); + +#undef CHECK_PASS + + return NULL; +} + /* create a renderlayer and renderpass for grease pencil layer */ RenderPass *RE_create_gp_pass(RenderResult *rr, const char *layername, const char *viewname) { @@ -4046,7 +4091,7 @@ RenderPass *RE_create_gp_pass(RenderResult *rr, const char *layername, const cha } /* clear previous pass if exist or the new image will be over previous one*/ - RenderPass *rp = RE_pass_find_by_type(rl, SCE_PASS_COMBINED, viewname); + RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, viewname); if (rp) { if (rp->rect) { MEM_freeN(rp->rect); @@ -4054,5 +4099,5 @@ RenderPass *RE_create_gp_pass(RenderResult *rr, const char *layername, const cha BLI_freelinkN(&rl->passes, rp); } /* create a totally new pass */ - return gp_add_pass(rr, rl, 4, SCE_PASS_COMBINED, viewname); + return gp_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, viewname); } diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index f276c01e86a..8e6e6c9bb7d 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -173,363 +173,72 @@ void render_result_views_shallowdelete(RenderResult *rr) } } -static const char *name_from_passtype(int passtype, int channel) -{ - if (passtype == SCE_PASS_COMBINED) { - if (channel == -1) return "Combined"; - if (channel == 0) return "Combined.R"; - if (channel == 1) return "Combined.G"; - if (channel == 2) return "Combined.B"; - return "Combined.A"; - } - if (passtype == SCE_PASS_Z) { - if (channel == -1) return "Depth"; - return "Depth.Z"; - } - if (passtype == SCE_PASS_VECTOR) { - if (channel == -1) return "Vector"; - if (channel == 0) return "Vector.X"; - if (channel == 1) return "Vector.Y"; - if (channel == 2) return "Vector.Z"; - return "Vector.W"; - } - if (passtype == SCE_PASS_NORMAL) { - if (channel == -1) return "Normal"; - if (channel == 0) return "Normal.X"; - if (channel == 1) return "Normal.Y"; - return "Normal.Z"; - } - if (passtype == SCE_PASS_UV) { - if (channel == -1) return "UV"; - if (channel == 0) return "UV.U"; - if (channel == 1) return "UV.V"; - return "UV.A"; - } - if (passtype == SCE_PASS_RGBA) { - if (channel == -1) return "Color"; - if (channel == 0) return "Color.R"; - if (channel == 1) return "Color.G"; - if (channel == 2) return "Color.B"; - return "Color.A"; - } - if (passtype == SCE_PASS_EMIT) { - if (channel == -1) return "Emit"; - if (channel == 0) return "Emit.R"; - if (channel == 1) return "Emit.G"; - return "Emit.B"; - } - if (passtype == SCE_PASS_DIFFUSE) { - if (channel == -1) return "Diffuse"; - if (channel == 0) return "Diffuse.R"; - if (channel == 1) return "Diffuse.G"; - return "Diffuse.B"; - } - if (passtype == SCE_PASS_SPEC) { - if (channel == -1) return "Spec"; - if (channel == 0) return "Spec.R"; - if (channel == 1) return "Spec.G"; - return "Spec.B"; - } - if (passtype == SCE_PASS_SHADOW) { - if (channel == -1) return "Shadow"; - if (channel == 0) return "Shadow.R"; - if (channel == 1) return "Shadow.G"; - return "Shadow.B"; - } - if (passtype == SCE_PASS_AO) { - if (channel == -1) return "AO"; - if (channel == 0) return "AO.R"; - if (channel == 1) return "AO.G"; - return "AO.B"; - } - if (passtype == SCE_PASS_ENVIRONMENT) { - if (channel == -1) return "Env"; - if (channel == 0) return "Env.R"; - if (channel == 1) return "Env.G"; - return "Env.B"; - } - if (passtype == SCE_PASS_INDIRECT) { - if (channel == -1) return "Indirect"; - if (channel == 0) return "Indirect.R"; - if (channel == 1) return "Indirect.G"; - return "Indirect.B"; - } - if (passtype == SCE_PASS_REFLECT) { - if (channel == -1) return "Reflect"; - if (channel == 0) return "Reflect.R"; - if (channel == 1) return "Reflect.G"; - return "Reflect.B"; - } - if (passtype == SCE_PASS_REFRACT) { - if (channel == -1) return "Refract"; - if (channel == 0) return "Refract.R"; - if (channel == 1) return "Refract.G"; - return "Refract.B"; - } - if (passtype == SCE_PASS_INDEXOB) { - if (channel == -1) return "IndexOB"; - return "IndexOB.X"; - } - if (passtype == SCE_PASS_INDEXMA) { - if (channel == -1) return "IndexMA"; - return "IndexMA.X"; - } - if (passtype == SCE_PASS_MIST) { - if (channel == -1) return "Mist"; - return "Mist.Z"; - } - if (passtype == SCE_PASS_RAYHITS) { - if (channel == -1) return "Rayhits"; - if (channel == 0) return "Rayhits.R"; - if (channel == 1) return "Rayhits.G"; - return "Rayhits.B"; - } - if (passtype == SCE_PASS_DIFFUSE_DIRECT) { - if (channel == -1) return "DiffDir"; - if (channel == 0) return "DiffDir.R"; - if (channel == 1) return "DiffDir.G"; - return "DiffDir.B"; - } - if (passtype == SCE_PASS_DIFFUSE_INDIRECT) { - if (channel == -1) return "DiffInd"; - if (channel == 0) return "DiffInd.R"; - if (channel == 1) return "DiffInd.G"; - return "DiffInd.B"; - } - if (passtype == SCE_PASS_DIFFUSE_COLOR) { - if (channel == -1) return "DiffCol"; - if (channel == 0) return "DiffCol.R"; - if (channel == 1) return "DiffCol.G"; - return "DiffCol.B"; - } - if (passtype == SCE_PASS_GLOSSY_DIRECT) { - if (channel == -1) return "GlossDir"; - if (channel == 0) return "GlossDir.R"; - if (channel == 1) return "GlossDir.G"; - return "GlossDir.B"; - } - if (passtype == SCE_PASS_GLOSSY_INDIRECT) { - if (channel == -1) return "GlossInd"; - if (channel == 0) return "GlossInd.R"; - if (channel == 1) return "GlossInd.G"; - return "GlossInd.B"; - } - if (passtype == SCE_PASS_GLOSSY_COLOR) { - if (channel == -1) return "GlossCol"; - if (channel == 0) return "GlossCol.R"; - if (channel == 1) return "GlossCol.G"; - return "GlossCol.B"; - } - if (passtype == SCE_PASS_TRANSM_DIRECT) { - if (channel == -1) return "TransDir"; - if (channel == 0) return "TransDir.R"; - if (channel == 1) return "TransDir.G"; - return "TransDir.B"; - } - if (passtype == SCE_PASS_TRANSM_INDIRECT) { - if (channel == -1) return "TransInd"; - if (channel == 0) return "TransInd.R"; - if (channel == 1) return "TransInd.G"; - return "TransInd.B"; - } - if (passtype == SCE_PASS_TRANSM_COLOR) { - if (channel == -1) return "TransCol"; - if (channel == 0) return "TransCol.R"; - if (channel == 1) return "TransCol.G"; - return "TransCol.B"; - } - if (passtype == SCE_PASS_SUBSURFACE_DIRECT) { - if (channel == -1) return "SubsurfaceDir"; - if (channel == 0) return "SubsurfaceDir.R"; - if (channel == 1) return "SubsurfaceDir.G"; - return "SubsurfaceDir.B"; - } - if (passtype == SCE_PASS_SUBSURFACE_INDIRECT) { - if (channel == -1) return "SubsurfaceInd"; - if (channel == 0) return "SubsurfaceInd.R"; - if (channel == 1) return "SubsurfaceInd.G"; - return "SubsurfaceInd.B"; - } - if (passtype == SCE_PASS_SUBSURFACE_COLOR) { - if (channel == -1) return "SubsurfaceCol"; - if (channel == 0) return "SubsurfaceCol.R"; - if (channel == 1) return "SubsurfaceCol.G"; - return "SubsurfaceCol.B"; - } - return "Unknown"; -} -static int passtype_from_name(const char *str, int passflag) +static char* set_pass_name(char *outname, const char *name, int channel, const char *chan_id) { - /* We do not really support several pass of the same types, so in case we are opening an EXR file with several pass - * names detected as same pass type, only return that pass type the first time, and return 'uknown' for the others. - * See T48466. */ -#define RETURN_PASS(_passtype) return (passflag & (_passtype)) ? 0 : (_passtype) - - if (STRPREFIX(str, "Combined")) - RETURN_PASS(SCE_PASS_COMBINED); - - if (STRPREFIX(str, "Depth")) - RETURN_PASS(SCE_PASS_Z); - - if (STRPREFIX(str, "Vector")) - RETURN_PASS(SCE_PASS_VECTOR); - - if (STRPREFIX(str, "Normal")) - RETURN_PASS(SCE_PASS_NORMAL); - - if (STRPREFIX(str, "UV")) - RETURN_PASS(SCE_PASS_UV); - - if (STRPREFIX(str, "Color")) - RETURN_PASS(SCE_PASS_RGBA); - - if (STRPREFIX(str, "Emit")) - RETURN_PASS(SCE_PASS_EMIT); - - if (STRPREFIX(str, "Diffuse")) - RETURN_PASS(SCE_PASS_DIFFUSE); - - if (STRPREFIX(str, "Spec")) - RETURN_PASS(SCE_PASS_SPEC); - - if (STRPREFIX(str, "Shadow")) - RETURN_PASS(SCE_PASS_SHADOW); - - if (STRPREFIX(str, "AO")) - RETURN_PASS(SCE_PASS_AO); - - if (STRPREFIX(str, "Env")) - RETURN_PASS(SCE_PASS_ENVIRONMENT); - - if (STRPREFIX(str, "Indirect")) - RETURN_PASS(SCE_PASS_INDIRECT); - - if (STRPREFIX(str, "Reflect")) - RETURN_PASS(SCE_PASS_REFLECT); - - if (STRPREFIX(str, "Refract")) - RETURN_PASS(SCE_PASS_REFRACT); - - if (STRPREFIX(str, "IndexOB")) - RETURN_PASS(SCE_PASS_INDEXOB); - - if (STRPREFIX(str, "IndexMA")) - RETURN_PASS(SCE_PASS_INDEXMA); - - if (STRPREFIX(str, "Mist")) - RETURN_PASS(SCE_PASS_MIST); - - if (STRPREFIX(str, "RayHits")) - RETURN_PASS(SCE_PASS_RAYHITS); - - if (STRPREFIX(str, "DiffDir")) - RETURN_PASS(SCE_PASS_DIFFUSE_DIRECT); - - if (STRPREFIX(str, "DiffInd")) - RETURN_PASS(SCE_PASS_DIFFUSE_INDIRECT); - - if (STRPREFIX(str, "DiffCol")) - RETURN_PASS(SCE_PASS_DIFFUSE_COLOR); - - if (STRPREFIX(str, "GlossDir")) - RETURN_PASS(SCE_PASS_GLOSSY_DIRECT); - - if (STRPREFIX(str, "GlossInd")) - RETURN_PASS(SCE_PASS_GLOSSY_INDIRECT); - - if (STRPREFIX(str, "GlossCol")) - RETURN_PASS(SCE_PASS_GLOSSY_COLOR); - - if (STRPREFIX(str, "TransDir")) - RETURN_PASS(SCE_PASS_TRANSM_DIRECT); - - if (STRPREFIX(str, "TransInd")) - RETURN_PASS(SCE_PASS_TRANSM_INDIRECT); - - if (STRPREFIX(str, "TransCol")) - RETURN_PASS(SCE_PASS_TRANSM_COLOR); - - if (STRPREFIX(str, "SubsurfaceDir")) - RETURN_PASS(SCE_PASS_SUBSURFACE_DIRECT); - - if (STRPREFIX(str, "SubsurfaceInd")) - RETURN_PASS(SCE_PASS_SUBSURFACE_INDIRECT); - - if (STRPREFIX(str, "SubsurfaceCol")) - RETURN_PASS(SCE_PASS_SUBSURFACE_COLOR); - - return 0; - -#undef RETURN_PASS + BLI_strncpy(outname, name, EXR_PASS_MAXNAME); + if (channel >= 0) { + char token[3] = {'.', chan_id[channel], '\0'}; + strncat(outname, token, EXR_PASS_MAXNAME); + } + return outname; } - -static void set_pass_name(char *passname, int passtype, int channel, const char *view) +static void set_pass_full_name(char *fullname, const char *name, int channel, const char *view, const char *chan_id) { - const char delims[] = {'.', '\0'}; - const char *sep; - const char *token; - size_t len; - - const char *passtype_name = name_from_passtype(passtype, channel); - - if (view == NULL || view[0] == '\0') { - BLI_strncpy(passname, passtype_name, EXR_PASS_MAXNAME); - return; - } - - len = BLI_str_rpartition(passtype_name, delims, &sep, &token); - - if (sep) { - BLI_snprintf(passname, EXR_PASS_MAXNAME, "%.*s.%s.%s", (int)len, passtype_name, view, token); + BLI_strncpy(fullname, name, EXR_PASS_MAXNAME); + if (view && view[0]) { + strncat(fullname, ".", EXR_PASS_MAXNAME); + strncat(fullname, view, EXR_PASS_MAXNAME); } - else { - BLI_snprintf(passname, EXR_PASS_MAXNAME, "%s.%s", passtype_name, view); + if (channel >= 0) { + char token[3] = {'.', chan_id[channel], '\0'}; + strncat(fullname, token, EXR_PASS_MAXNAME); } } /********************************** New **************************************/ -static RenderPass *render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype, const char *viewname) +static RenderPass *render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, const char *name, const char *viewname, const char *chan_id) { const int view_id = BLI_findstringindex(&rr->views, viewname, offsetof(RenderView, name)); - const char *typestr = name_from_passtype(passtype, -1); - RenderPass *rpass = MEM_callocN(sizeof(RenderPass), typestr); + RenderPass *rpass = MEM_callocN(sizeof(RenderPass), name); size_t rectsize = ((size_t)rr->rectx) * rr->recty * channels; - rpass->passtype = passtype; rpass->channels = channels; rpass->rectx = rl->rectx; rpass->recty = rl->recty; rpass->view_id = view_id; - set_pass_name(rpass->name, rpass->passtype, -1, viewname); - BLI_strncpy(rpass->internal_name, typestr, sizeof(rpass->internal_name)); + BLI_strncpy(rpass->name, name, sizeof(rpass->name)); + BLI_strncpy(rpass->chan_id, chan_id, sizeof(rpass->chan_id)); BLI_strncpy(rpass->view, viewname, sizeof(rpass->view)); + set_pass_full_name(rpass->fullname, rpass->name, -1, rpass->view, rpass->chan_id); if (rl->exrhandle) { int a; - for (a = 0; a < channels; a++) - IMB_exr_add_channel(rl->exrhandle, rl->name, name_from_passtype(passtype, a), viewname, 0, 0, NULL, false); + for (a = 0; a < channels; a++) { + char passname[EXR_PASS_MAXNAME]; + IMB_exr_add_channel(rl->exrhandle, rl->name, set_pass_name(passname, rpass->name, a, rpass->chan_id), viewname, 0, 0, NULL, false); + } } else { float *rect; int x; - rpass->rect = MEM_mapallocN(sizeof(float) * rectsize, typestr); + rpass->rect = MEM_mapallocN(sizeof(float) * rectsize, name); if (rpass->rect == NULL) { MEM_freeN(rpass); return NULL; } - if (passtype == SCE_PASS_VECTOR) { + if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) { /* initialize to max speed */ rect = rpass->rect; for (x = rectsize - 1; x >= 0; x--) rect[x] = PASS_VECTOR_MAX; } - else if (passtype == SCE_PASS_Z) { + else if (STREQ(rpass->name, RE_PASSNAME_Z)) { rect = rpass->rect; for (x = rectsize - 1; x >= 0; x--) rect[x] = 10e10; @@ -541,58 +250,10 @@ static RenderPass *render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int return rpass; } /* wrapper called from render_opengl */ -RenderPass *gp_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype, const char *viewname) -{ - return render_layer_add_pass(rr, rl, channels, passtype, viewname); -} - -#ifdef WITH_CYCLES_DEBUG -const char *RE_debug_pass_name_get(int debug_type) -{ - switch (debug_type) { - case RENDER_PASS_DEBUG_BVH_TRAVERSED_NODES: - return "BVH Traversed Nodes"; - case RENDER_PASS_DEBUG_BVH_TRAVERSED_INSTANCES: - return "BVH Traversed Instances"; - case RENDER_PASS_DEBUG_BVH_INTERSECTIONS: - return "BVH Primitive Intersections"; - case RENDER_PASS_DEBUG_RAY_BOUNCES: - return "Ray Bounces"; - } - return "Unknown"; -} - -int RE_debug_pass_num_channels_get(int UNUSED(debug_type)) -{ - /* Only single case currently, might be handy for further debug passes. */ - return 1; -} - -static RenderPass *render_layer_add_debug_pass(RenderResult *rr, - RenderLayer *rl, - int pass_type, - int debug_type, - const char *view) -{ - const char *name = RE_debug_pass_name_get(debug_type); - int channels = RE_debug_pass_num_channels_get(debug_type); - RenderPass *rpass = render_layer_add_pass(rr, rl, channels, pass_type, view); - if (rpass == NULL) { - return NULL; - } - rpass->debug_type = debug_type; - BLI_strncpy(rpass->name, - name, - sizeof(rpass->name)); - BLI_strncpy(rpass->internal_name, rpass->name, sizeof(rpass->internal_name)); - return rpass; -} - -int RE_debug_pass_type_get(Render *re) +RenderPass *gp_add_pass(RenderResult *rr, RenderLayer *rl, int channels, const char *name, const char *viewname) { - return re->r.debug_pass_type; + return render_layer_add_pass(rr, rl, channels, name, viewname, "RGBA"); } -#endif /* called by main render as well for parts */ /* will read info from Render *re to define layers */ @@ -683,89 +344,77 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf if (rr->do_exr_tile) IMB_exr_add_view(rl->exrhandle, view); -#define RENDER_LAYER_ADD_PASS_SAFE(rr, rl, channels, passtype, viewname) \ +#define RENDER_LAYER_ADD_PASS_SAFE(rr, rl, channels, name, viewname, chan_id) \ do { \ - if (render_layer_add_pass(rr, rl, channels, passtype, viewname) == NULL) { \ + if (render_layer_add_pass(rr, rl, channels, name, viewname, chan_id) == NULL) { \ render_result_free(rr); \ return NULL; \ } \ } while (false) /* a renderlayer should always have a Combined pass*/ - render_layer_add_pass(rr, rl, 4, SCE_PASS_COMBINED, view); + render_layer_add_pass(rr, rl, 4, "Combined", view, "RGBA"); if (srl->passflag & SCE_PASS_Z) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, SCE_PASS_Z, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_Z, view, "Z"); if (srl->passflag & SCE_PASS_VECTOR) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, SCE_PASS_VECTOR, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, RE_PASSNAME_VECTOR, view, "XYZW"); if (srl->passflag & SCE_PASS_NORMAL) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_NORMAL, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_NORMAL, view, "XYZ"); if (srl->passflag & SCE_PASS_UV) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_UV, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_UV, view, "UVA"); if (srl->passflag & SCE_PASS_RGBA) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, SCE_PASS_RGBA, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, RE_PASSNAME_RGBA, view, "RGBA"); if (srl->passflag & SCE_PASS_EMIT) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_EMIT, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_EMIT, view, "RGB"); if (srl->passflag & SCE_PASS_DIFFUSE) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_DIFFUSE, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_DIFFUSE, view, "RGB"); if (srl->passflag & SCE_PASS_SPEC) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_SPEC, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SPEC, view, "RGB"); if (srl->passflag & SCE_PASS_AO) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_AO, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_AO, view, "RGB"); if (srl->passflag & SCE_PASS_ENVIRONMENT) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_ENVIRONMENT, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_ENVIRONMENT, view, "RGB"); if (srl->passflag & SCE_PASS_INDIRECT) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_INDIRECT, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_INDIRECT, view, "RGB"); if (srl->passflag & SCE_PASS_SHADOW) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_SHADOW, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SHADOW, view, "RGB"); if (srl->passflag & SCE_PASS_REFLECT) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_REFLECT, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_REFLECT, view, "RGB"); if (srl->passflag & SCE_PASS_REFRACT) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_REFRACT, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_REFRACT, view, "RGB"); if (srl->passflag & SCE_PASS_INDEXOB) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, SCE_PASS_INDEXOB, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_INDEXOB, view, "X"); if (srl->passflag & SCE_PASS_INDEXMA) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, SCE_PASS_INDEXMA, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_INDEXMA, view, "X"); if (srl->passflag & SCE_PASS_MIST) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, SCE_PASS_MIST, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_MIST, view, "Z"); if (rl->passflag & SCE_PASS_RAYHITS) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, SCE_PASS_RAYHITS, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, RE_PASSNAME_RAYHITS, view, "RGB"); if (srl->passflag & SCE_PASS_DIFFUSE_DIRECT) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_DIFFUSE_DIRECT, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_DIFFUSE_DIRECT, view, "RGB"); if (srl->passflag & SCE_PASS_DIFFUSE_INDIRECT) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_DIFFUSE_INDIRECT, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_DIFFUSE_INDIRECT, view, "RGB"); if (srl->passflag & SCE_PASS_DIFFUSE_COLOR) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_DIFFUSE_COLOR, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_DIFFUSE_COLOR, view, "RGB"); if (srl->passflag & SCE_PASS_GLOSSY_DIRECT) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_GLOSSY_DIRECT, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_GLOSSY_DIRECT, view, "RGB"); if (srl->passflag & SCE_PASS_GLOSSY_INDIRECT) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_GLOSSY_INDIRECT, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_GLOSSY_INDIRECT, view, "RGB"); if (srl->passflag & SCE_PASS_GLOSSY_COLOR) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_GLOSSY_COLOR, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_GLOSSY_COLOR, view, "RGB"); if (srl->passflag & SCE_PASS_TRANSM_DIRECT) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_TRANSM_DIRECT, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_TRANSM_DIRECT, view, "RGB"); if (srl->passflag & SCE_PASS_TRANSM_INDIRECT) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_TRANSM_INDIRECT, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_TRANSM_INDIRECT, view, "RGB"); if (srl->passflag & SCE_PASS_TRANSM_COLOR) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_TRANSM_COLOR, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_TRANSM_COLOR, view, "RGB"); if (srl->passflag & SCE_PASS_SUBSURFACE_DIRECT) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_SUBSURFACE_DIRECT, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SUBSURFACE_DIRECT, view, "RGB"); if (srl->passflag & SCE_PASS_SUBSURFACE_INDIRECT) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_SUBSURFACE_INDIRECT, view); + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SUBSURFACE_INDIRECT, view, "RGB"); if (srl->passflag & SCE_PASS_SUBSURFACE_COLOR) - RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_SUBSURFACE_COLOR, view); - -#ifdef WITH_CYCLES_DEBUG - if (BKE_scene_use_new_shading_nodes(re->scene)) { - if (render_layer_add_debug_pass(rr, rl, SCE_PASS_DEBUG, - re->r.debug_pass_type, view) == NULL) - { - render_result_free(rr); - return NULL; - } - } -#endif - + RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SUBSURFACE_COLOR, view, "RGB"); #undef RENDER_LAYER_ADD_PASS_SAFE } } @@ -794,7 +443,7 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf IMB_exr_add_view(rl->exrhandle, view); /* a renderlayer should always have a Combined pass */ - render_layer_add_pass(rr, rl, 4, SCE_PASS_COMBINED, view); + render_layer_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, view, "RGBA"); } /* note, this has to be in sync with scene.c */ @@ -813,6 +462,60 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf return rr; } +void render_result_clone_passes(Render *re, RenderResult *rr, const char *viewname) +{ + RenderLayer *rl; + RenderPass *main_rp; + + for (rl = rr->layers.first; rl; rl = rl->next) { + RenderLayer *main_rl = BLI_findstring(&re->result->layers, rl->name, offsetof(RenderLayer, name)); + if (!main_rl) { + continue; + } + + for (main_rp = main_rl->passes.first; main_rp; main_rp = main_rp->next) { + if (viewname && viewname[0] && !STREQ(main_rp->view, viewname)) { + continue; + } + + /* Compare fullname to make sure that the view also is equal. */ + RenderPass *rp = BLI_findstring(&rl->passes, main_rp->fullname, offsetof(RenderPass, fullname)); + if (!rp) { + render_layer_add_pass(rr, rl, main_rp->channels, main_rp->name, main_rp->view, main_rp->chan_id); + } + } + } +} + +void render_result_add_pass(RenderResult *rr, const char *name, int channels, const char *chan_id, const char *layername, const char *viewname) +{ + RenderLayer *rl; + RenderPass *rp; + RenderView *rv; + + for (rl = rr->layers.first; rl; rl = rl->next) { + if (layername && layername[0] && !STREQ(rl->name, layername)) { + continue; + } + + for (rv = rr->views.first; rv; rv = rv->next) { + const char *view = rv->name; + + if (viewname && viewname[0] && !STREQ(view, viewname)) continue; + + /* Ensure that the pass doesn't exist yet. */ + for (rp = rl->passes.first; rp; rp = rp->next) { + if (!STREQ(rp->name, name)) continue; + if (!STREQ(rp->view, view)) continue; + } + + if (!rp) { + render_layer_add_pass(rr, rl, channels, name, view, chan_id); + } + } + } +} + /* allocate osa new results for samples */ RenderResult *render_result_new_full_sample(Render *re, ListBase *lb, rcti *partrct, int crop, int savebuffers, const char *viewname) { @@ -830,6 +533,50 @@ RenderResult *render_result_new_full_sample(Render *re, ListBase *lb, rcti *part return lb->first; } +static int passtype_from_name(const char *name) +{ + const char delim[] = {'.', '\0'}; + const char *sep, *suf; + int len = BLI_str_partition(name, delim, &sep, &suf); + +#define CHECK_PASS(NAME) if (STREQLEN(name, RE_PASSNAME_ ## NAME, len)) return SCE_PASS_ ## NAME + + CHECK_PASS(COMBINED); + CHECK_PASS(Z); + CHECK_PASS(VECTOR); + CHECK_PASS(NORMAL); + CHECK_PASS(UV); + CHECK_PASS(RGBA); + CHECK_PASS(EMIT); + CHECK_PASS(DIFFUSE); + CHECK_PASS(SPEC); + CHECK_PASS(SHADOW); + CHECK_PASS(AO); + CHECK_PASS(ENVIRONMENT); + CHECK_PASS(INDIRECT); + CHECK_PASS(REFLECT); + CHECK_PASS(REFRACT); + CHECK_PASS(INDEXOB); + CHECK_PASS(INDEXMA); + CHECK_PASS(MIST); + CHECK_PASS(RAYHITS); + CHECK_PASS(DIFFUSE_DIRECT); + CHECK_PASS(DIFFUSE_INDIRECT); + CHECK_PASS(DIFFUSE_COLOR); + CHECK_PASS(GLOSSY_DIRECT); + CHECK_PASS(GLOSSY_INDIRECT); + CHECK_PASS(GLOSSY_COLOR); + CHECK_PASS(TRANSM_DIRECT); + CHECK_PASS(TRANSM_INDIRECT); + CHECK_PASS(TRANSM_COLOR); + CHECK_PASS(SUBSURFACE_DIRECT); + CHECK_PASS(SUBSURFACE_INDIRECT); + CHECK_PASS(SUBSURFACE_COLOR); + +#undef CHECK_PASS + return 0; +} + /* callbacks for render_result_new_from_exr */ static void *ml_addlayer_cb(void *base, const char *str) { @@ -843,36 +590,30 @@ static void *ml_addlayer_cb(void *base, const char *str) return rl; } -static void ml_addpass_cb(void *base, void *lay, const char *str, float *rect, int totchan, const char *chan_id, const char *view) +static void ml_addpass_cb(void *base, void *lay, const char *name, float *rect, int totchan, const char *chan_id, const char *view) { RenderResult *rr = base; RenderLayer *rl = lay; RenderPass *rpass = MEM_callocN(sizeof(RenderPass), "loaded pass"); - int a; - + BLI_addtail(&rl->passes, rpass); rpass->channels = totchan; - rpass->passtype = passtype_from_name(str, rl->passflag); - if (rpass->passtype == 0) - printf("unknown pass %s\n", str); - rl->passflag |= rpass->passtype; - + rl->passflag |= passtype_from_name(name); + /* channel id chars */ - for (a = 0; a < totchan; a++) - rpass->chan_id[a] = chan_id[a]; + BLI_strncpy(rpass->chan_id, chan_id, sizeof(rpass->chan_id)); rpass->rect = rect; + BLI_strncpy(rpass->name, name, EXR_PASS_MAXNAME); + BLI_strncpy(rpass->view, view, sizeof(rpass->view)); + set_pass_full_name(rpass->fullname, name, -1, view, rpass->chan_id); + if (view[0] != '\0') { - BLI_snprintf(rpass->name, sizeof(rpass->name), "%s.%s", str, view); rpass->view_id = BLI_findstringindex(&rr->views, view, offsetof(RenderView, name)); } else { - BLI_strncpy(rpass->name, str, sizeof(rpass->name)); rpass->view_id = 0; } - - BLI_strncpy(rpass->view, view, sizeof(rpass->view)); - BLI_strncpy(rpass->internal_name, str, sizeof(rpass->internal_name)); } static void *ml_addview_cb(void *base, const char *str) @@ -912,12 +653,30 @@ static int order_render_passes(const void *a, const void *b) // 1 if a is after b RenderPass *rpa = (RenderPass *) a; RenderPass *rpb = (RenderPass *) b; + unsigned int passtype_a = passtype_from_name(rpa->name); + unsigned int passtype_b = passtype_from_name(rpb->name); - if (rpa->passtype > rpb->passtype) + /* Render passes with default type always go first. */ + if (passtype_b && !passtype_a) return 1; - else if (rpa->passtype < rpb->passtype) + if (passtype_a && !passtype_b) return 0; + if (passtype_a && passtype_b) { + if (passtype_a > passtype_b) + return 1; + else if (passtype_a < passtype_b) + return 0; + } + else { + int cmp = strncmp(rpa->name, rpb->name, EXR_PASS_MAXNAME); + if (cmp > 0) + return 1; + if (cmp < 0) + return 0; + } + + /* they have the same type */ /* left first */ if (STREQ(rpa->view, STEREO_LEFT_NAME)) @@ -1049,7 +808,7 @@ void render_result_merge(RenderResult *rr, RenderResult *rrpart) rpass = rpass->next) { /* renderresult have all passes, renderpart only the active view's passes */ - if (strcmp(rpassp->name, rpass->name) != 0) + if (strcmp(rpassp->fullname, rpass->fullname) != 0) continue; do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels); @@ -1061,21 +820,6 @@ void render_result_merge(RenderResult *rr, RenderResult *rrpart) } } -/* for passes read from files, these have names stored */ -static char *make_pass_name(RenderPass *rpass, int chan) -{ - static char name[EXR_PASS_MAXNAME]; - int len; - - BLI_strncpy(name, rpass->name, EXR_PASS_MAXNAME); - len = strlen(name); - name[len] = '.'; - name[len + 1] = rpass->chan_id[chan]; - name[len + 2] = 0; - - return name; -} - /* called from within UI and render pipeline, saves both rendered result as a file-read result * if multiview is true saves all views in a multiview exr * else if view is not NULL saves single view @@ -1136,8 +880,10 @@ bool RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *fil IMB_exr_add_view(exrhandle, rview->name); if (rview->rectf) { + char passname[EXR_PASS_MAXNAME]; for (a = 0; a < 4; a++) { - IMB_exr_add_channel(exrhandle, "Composite", name_from_passtype(SCE_PASS_COMBINED, a), + set_pass_name(passname, RE_PASSNAME_COMBINED, a, "RGBA"); + IMB_exr_add_channel(exrhandle, RE_PASSNAME_COMBINED, passname, chan_view, 4, 4 * width, rview->rectf + a, use_half_float); } @@ -1150,6 +896,7 @@ bool RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *fil /* passes are allocated in sync */ for (rpass = rl->passes.first; rpass; rpass = rpass->next) { const int xstride = rpass->channels; + char passname[EXR_PASS_MAXNAME]; if (is_mono) { if (!STREQ(view, rpass->view)) { @@ -1163,16 +910,10 @@ bool RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *fil } for (a = 0; a < xstride; a++) { - if (rpass->passtype) { - IMB_exr_add_channel(exrhandle, rl->name, name_from_passtype(rpass->passtype, a), chan_view, - xstride, xstride * width, rpass->rect + a, - rpass->passtype == SCE_PASS_Z ? false : use_half_float); - } - else { - IMB_exr_add_channel(exrhandle, rl->name, make_pass_name(rpass, a), chan_view, - xstride, xstride * width, rpass->rect + a, - use_half_float); - } + set_pass_name(passname, rpass->name, a, rpass->chan_id); + IMB_exr_add_channel(exrhandle, rl->name, passname, chan_view, + xstride, xstride * width, rpass->rect + a, + STREQ(rpass->name, RE_PASSNAME_Z) ? false : use_half_float); } } } @@ -1281,12 +1022,12 @@ static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart, cons for (rpassp = rlp->passes.first; rpassp; rpassp = rpassp->next) { const int xstride = rpassp->channels; int a; - char passname[EXR_PASS_MAXNAME]; + char fullname[EXR_PASS_MAXNAME]; for (a = 0; a < xstride; a++) { - set_pass_name(passname, rpassp->passtype, a, rpassp->view); + set_pass_full_name(fullname, rpassp->name, a, viewname, rpassp->chan_id); - IMB_exr_set_channel(rl->exrhandle, rlp->name, passname, + IMB_exr_set_channel(rl->exrhandle, rlp->name, fullname, xstride, xstride * rrpart->rectx, rpassp->rect + a + xstride * offs); } } @@ -1449,15 +1190,15 @@ int render_result_exr_file_read_path(RenderResult *rr, RenderLayer *rl_single, c for (rpass = rl->passes.first; rpass; rpass = rpass->next) { const int xstride = rpass->channels; int a; - char passname[EXR_PASS_MAXNAME]; + char fullname[EXR_PASS_MAXNAME]; for (a = 0; a < xstride; a++) { - set_pass_name(passname, rpass->passtype, a, rpass->view); - IMB_exr_set_channel(exrhandle, rl->name, passname, + set_pass_full_name(fullname, rpass->name, a, rpass->view, rpass->chan_id); + IMB_exr_set_channel(exrhandle, rl->name, fullname, xstride, xstride * rectx, rpass->rect + a); } - set_pass_name(rpass->name, rpass->passtype, -1, rpass->view); + set_pass_full_name(rpass->fullname, rpass->name, -1, rpass->view, rpass->chan_id); } } diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 42e4d4f27f6..22dc2b28900 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -1495,6 +1495,7 @@ void texture_rgb_blend(float in[3], const float tex[3], const float out[3], floa case MTEX_SUB: fact= -fact; + ATTR_FALLTHROUGH; case MTEX_ADD: fact*= facg; in[0]= (fact*tex[0] + out[0]); @@ -1609,6 +1610,7 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen case MTEX_SUB: fact= -fact; + ATTR_FALLTHROUGH; case MTEX_ADD: in= fact*tex + out; break; diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 910ea16607e..77f399d08d1 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -180,11 +180,12 @@ static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, in flarec= 0; if (fullsample) { - for (sample=0; sample<totsample; sample++) + for (sample=0; sample<totsample; sample++) { if (ps->mask & (1 << sample)) { - float *pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname); + float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname); addalphaAddfacFloat(pass + od*4, col, har->add); } + } } else { fac= ((float)amountm)/(float)R.osa; @@ -215,11 +216,12 @@ static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, in } if (fullsample) { - for (sample=0; sample<totsample; sample++) + for (sample=0; sample<totsample; sample++) { if (!(mask & (1 << sample))) { - float *pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname); + float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname); addalphaAddfacFloat(pass + od*4, col, har->add); } + } } else { col[0]= accol[0]; @@ -228,7 +230,7 @@ static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, in col[3]= accol[3]; for (sample=0; sample<totsample; sample++) { - float *pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname); + float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname); addalphaAddfacFloat(pass + od*4, col, har->add); } } @@ -312,7 +314,7 @@ static void halo_tile(RenderPart *pa, RenderLayer *rl) if ((zz> har->zs) || (har->mat && (har->mat->mode & MA_HALO_SOFT))) { if (shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec)) { for (sample=0; sample<totsample; sample++) { - float * rect= RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname); + float * rect= RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname); addalphaAddfacFloat(rect + od*4, col, har->add); } } @@ -367,7 +369,7 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl) if (fullsample) { for (sample=0; sample<totsample; sample++) { if (ps->mask & (1 << sample)) { - pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname); + pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname); pass += od * 4; pass[0]+= col[0]; pass[1]+= col[1]; @@ -379,7 +381,7 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl) } else { fac= ((float)count)/(float)R.osa; - pass = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, R.viewname); + pass = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname); pass += od * 4; pass[0]+= fac*col[0]; pass[1]+= fac*col[1]; @@ -401,7 +403,7 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl) for (sample=0; sample<totsample; sample++) { if (!(mask & (1 << sample))) { - pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname); + pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname); pass += od * 4; pass[0]+= col[0]; pass[1]+= col[1]; @@ -413,7 +415,7 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl) } else { fac= ((float)R.osa-totsamp)/(float)R.osa; - pass = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, R.viewname); + pass = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname); pass += od * 4; pass[0]+= fac*col[0]; pass[1]+= fac*col[1]; @@ -433,7 +435,7 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl) renderspothalo(&shi, col, 1.0f); for (sample=0; sample<totsample; sample++) { - pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname); + pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname); pass += od * 4; pass[0]+= col[0]; pass[1]+= col[1]; @@ -462,101 +464,96 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, float *fp, *col= NULL; int pixsize= 3; - switch (rpass->passtype) { - case SCE_PASS_COMBINED: - add_filt_fmask(curmask, shr->combined, rpass->rect + 4*offset, rectx); - break; - case SCE_PASS_Z: - fp= rpass->rect + offset; - *fp= shr->z; - break; - case SCE_PASS_RGBA: - col= shr->col; - pixsize= 4; - break; - case SCE_PASS_EMIT: - col= shr->emit; - break; - case SCE_PASS_DIFFUSE: - col= shr->diff; - break; - case SCE_PASS_SPEC: - col= shr->spec; - break; - case SCE_PASS_SHADOW: - col= shr->shad; - break; - case SCE_PASS_AO: - col= shr->ao; - break; - case SCE_PASS_ENVIRONMENT: - col= shr->env; - break; - case SCE_PASS_INDIRECT: - col= shr->indirect; - break; - case SCE_PASS_REFLECT: - col= shr->refl; - break; - case SCE_PASS_REFRACT: - col= shr->refr; - break; - case SCE_PASS_NORMAL: - col= shr->nor; - break; - case SCE_PASS_UV: - /* box filter only, gauss will screwup UV too much */ - if (shi->totuv) { - float mult= (float)count_mask(curmask)/(float)R.osa; - fp= rpass->rect + 3*offset; - fp[0]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[0]); - fp[1]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[1]); - fp[2]+= mult; - } - break; - case SCE_PASS_INDEXOB: - /* no filter */ - if (shi->vlr) { - fp= rpass->rect + offset; + if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) { + add_filt_fmask(curmask, shr->combined, rpass->rect + 4*offset, rectx); + } + else if (STREQ(rpass->name, RE_PASSNAME_Z)) { + fp = rpass->rect + offset; + *fp = shr->z; + } + else if (STREQ(rpass->name, RE_PASSNAME_RGBA)) { + col = shr->col; + pixsize = 4; + } + else if (STREQ(rpass->name, RE_PASSNAME_EMIT)) { + col = shr->emit; + } + else if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) { + col = shr->diff; + } + else if (STREQ(rpass->name, RE_PASSNAME_SPEC)) { + col = shr->spec; + } + else if (STREQ(rpass->name, RE_PASSNAME_SHADOW)) { + col = shr->shad; + } + else if (STREQ(rpass->name, RE_PASSNAME_AO)) { + col = shr->ao; + } + else if (STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) { + col = shr->env; + } + else if (STREQ(rpass->name, RE_PASSNAME_INDIRECT)) { + col = shr->indirect; + } + else if (STREQ(rpass->name, RE_PASSNAME_REFLECT)) { + col = shr->refl; + } + else if (STREQ(rpass->name, RE_PASSNAME_REFRACT)) { + col = shr->refr; + } + else if (STREQ(rpass->name, RE_PASSNAME_NORMAL)) { + col = shr->nor; + } + else if (STREQ(rpass->name, RE_PASSNAME_UV)) { + /* box filter only, gauss will screwup UV too much */ + if (shi->totuv) { + float mult = (float)count_mask(curmask)/(float)R.osa; + fp = rpass->rect + 3*offset; + fp[0]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[0]); + fp[1]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[1]); + fp[2]+= mult; + } + } + else if (STREQ(rpass->name, RE_PASSNAME_INDEXOB)) { + /* no filter */ + if (shi->vlr) { + fp = rpass->rect + offset; + if (*fp==0.0f) + *fp = (float)shi->obr->ob->index; + } + } + else if (STREQ(rpass->name, RE_PASSNAME_INDEXMA)) { + /* no filter */ + if (shi->vlr) { + fp = rpass->rect + offset; if (*fp==0.0f) - *fp= (float)shi->obr->ob->index; - } - break; - case SCE_PASS_INDEXMA: - /* no filter */ - if (shi->vlr) { - fp= rpass->rect + offset; - if (*fp==0.0f) - *fp= (float)shi->mat->index; - } - break; - case SCE_PASS_MIST: - /* */ - col= &shr->mist; - pixsize= 1; - break; - - case SCE_PASS_VECTOR: - { - /* add minimum speed in pixel, no filter */ - fp= rpass->rect + 4*offset; - if ( (ABS(shr->winspeed[0]) + ABS(shr->winspeed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) { - fp[0]= shr->winspeed[0]; - fp[1]= shr->winspeed[1]; - } - if ( (ABS(shr->winspeed[2]) + ABS(shr->winspeed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) { - fp[2]= shr->winspeed[2]; - fp[3]= shr->winspeed[3]; - } - - break; + *fp = (float)shi->mat->index; + } + } + else if (STREQ(rpass->name, RE_PASSNAME_MIST)) { + /* */ + col = &shr->mist; + pixsize = 1; + } + else if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) { + /* add minimum speed in pixel, no filter */ + fp = rpass->rect + 4*offset; + if ( (ABS(shr->winspeed[0]) + ABS(shr->winspeed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) { + fp[0] = shr->winspeed[0]; + fp[1] = shr->winspeed[1]; + } + if ( (ABS(shr->winspeed[2]) + ABS(shr->winspeed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) { + fp[2] = shr->winspeed[2]; + fp[3] = shr->winspeed[3]; } - case SCE_PASS_RAYHITS: - /* */ - col= shr->rayhits; - pixsize= 4; - break; } + else if (STREQ(rpass->name, RE_PASSNAME_RAYHITS)) { + /* */ + col = shr->rayhits; + pixsize= 4; + } + if (col) { fp= rpass->rect + pixsize*offset; add_filt_fmask_pixsize(curmask, col, fp, rectx, pixsize); @@ -574,86 +571,85 @@ static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult float *col= NULL, uvcol[3]; int a, pixsize= 3; - switch (rpass->passtype) { - case SCE_PASS_COMBINED: - /* copy combined to use for preview */ - copy_v4_v4(rpass->rect + 4*offset, shr->combined); - break; - case SCE_PASS_Z: - fp= rpass->rect + offset; - *fp= shr->z; - break; - case SCE_PASS_RGBA: - col= shr->col; - pixsize= 4; - break; - case SCE_PASS_EMIT: - col= shr->emit; - break; - case SCE_PASS_DIFFUSE: - col= shr->diff; - break; - case SCE_PASS_SPEC: - col= shr->spec; - break; - case SCE_PASS_SHADOW: - col= shr->shad; - break; - case SCE_PASS_AO: - col= shr->ao; - break; - case SCE_PASS_ENVIRONMENT: - col= shr->env; - break; - case SCE_PASS_INDIRECT: - col= shr->indirect; - break; - case SCE_PASS_REFLECT: - col= shr->refl; - break; - case SCE_PASS_REFRACT: - col= shr->refr; - break; - case SCE_PASS_NORMAL: - col= shr->nor; - break; - case SCE_PASS_UV: - if (shi->totuv) { - uvcol[0]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[0]; - uvcol[1]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[1]; - uvcol[2]= 1.0f; - col= uvcol; - } - break; - case SCE_PASS_VECTOR: - col= shr->winspeed; - pixsize= 4; - break; - case SCE_PASS_INDEXOB: - if (shi->vlr) { - fp= rpass->rect + offset; - *fp= (float)shi->obr->ob->index; - } - break; - case SCE_PASS_INDEXMA: - if (shi->vlr) { - fp= rpass->rect + offset; - *fp= (float)shi->mat->index; - } - break; - case SCE_PASS_MIST: - fp= rpass->rect + offset; - *fp= shr->mist; - break; - case SCE_PASS_RAYHITS: - col= shr->rayhits; - pixsize= 4; - break; + if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) { + /* copy combined to use for preview */ + copy_v4_v4(rpass->rect + 4*offset, shr->combined); + } + else if (STREQ(rpass->name, RE_PASSNAME_Z)) { + fp = rpass->rect + offset; + *fp = shr->z; + } + else if (STREQ(rpass->name, RE_PASSNAME_RGBA)) { + col = shr->col; + pixsize = 4; + } + else if (STREQ(rpass->name, RE_PASSNAME_EMIT)) { + col = shr->emit; + } + else if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) { + col = shr->diff; + } + else if (STREQ(rpass->name, RE_PASSNAME_SPEC)) { + col = shr->spec; + } + else if (STREQ(rpass->name, RE_PASSNAME_SHADOW)) { + col = shr->shad; + } + else if (STREQ(rpass->name, RE_PASSNAME_AO)) { + col = shr->ao; + } + else if (STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) { + col = shr->env; + } + else if (STREQ(rpass->name, RE_PASSNAME_INDIRECT)) { + col = shr->indirect; + } + else if (STREQ(rpass->name, RE_PASSNAME_REFLECT)) { + col = shr->refl; + } + else if (STREQ(rpass->name, RE_PASSNAME_REFRACT)) { + col = shr->refr; + } + else if (STREQ(rpass->name, RE_PASSNAME_NORMAL)) { + col = shr->nor; + } + else if (STREQ(rpass->name, RE_PASSNAME_UV)) { + if (shi->totuv) { + uvcol[0] = 0.5f + 0.5f*shi->uv[shi->actuv].uv[0]; + uvcol[1] = 0.5f + 0.5f*shi->uv[shi->actuv].uv[1]; + uvcol[2] = 1.0f; + col = uvcol; + } + } + else if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) { + col = shr->winspeed; + pixsize = 4; + } + else if (STREQ(rpass->name, RE_PASSNAME_INDEXOB)) { + if (shi->vlr) { + fp = rpass->rect + offset; + *fp = (float)shi->obr->ob->index; + } + } + else if (STREQ(rpass->name, RE_PASSNAME_INDEXMA)) { + if (shi->vlr) { + fp = rpass->rect + offset; + *fp = (float)shi->mat->index; + } + } + else if (STREQ(rpass->name, RE_PASSNAME_MIST)) { + fp = rpass->rect + offset; + *fp = shr->mist; + } + else if (STREQ(rpass->name, RE_PASSNAME_RAYHITS)) { + col = shr->rayhits; + pixsize = 4; } + if (col) { - fp= rpass->rect + pixsize*offset; + fp = rpass->rect + pixsize*offset; for (a=0; a<pixsize; a++) - fp[a]= col[a]; + fp[a] = col[a]; } } } @@ -696,7 +692,7 @@ static void sky_tile(RenderPart *pa, RenderLayer *rl) bool done = false; for (sample= 0; sample<totsample; sample++) { - float *pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname); + float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname); pass += od; if (pass[3]<1.0f) { @@ -737,7 +733,7 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl) /* check that z pass is enabled */ if (pa->rectz==NULL) return; for (zpass= rl->passes.first; zpass; zpass= zpass->next) - if (zpass->passtype==SCE_PASS_Z) + if (STREQ(zpass->name, RE_PASSNAME_Z)) break; if (zpass==NULL) return; @@ -758,8 +754,8 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl) int sample; for (sample=0; sample<totsample; sample++) { - const float *zrect = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_Z, R.viewname) + od; - float *rgbrect = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname) + 4*od; + const float *zrect = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_Z, R.viewname) + od; + float *rgbrect = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname) + 4*od; float rgb[3] = {0}; bool done = false; @@ -994,7 +990,7 @@ static void clamp_alpha_rgb_range(RenderPart *pa, RenderLayer *rl) return; for (sample= 0; sample<totsample; sample++) { - float *rectf = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname); + float *rectf = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname); for (y= pa->rectx*pa->recty; y>0; y--, rectf+=4) { rectf[0] = MAX2(rectf[0], 0.0f); @@ -1076,7 +1072,7 @@ static void reset_sky_speed(RenderPart *pa, RenderLayer *rl) totsample= get_sample_layers(pa, rl, rlpp); for (sample= 0; sample<totsample; sample++) { - fp= RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_VECTOR, R.viewname); + fp= RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_VECTOR, R.viewname); if (fp==NULL) break; for (a= 4*pa->rectx*pa->recty - 1; a>=0; a--) @@ -1187,7 +1183,7 @@ void zbufshadeDA_tile(RenderPart *pa) pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp"); pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz"); for (rl= rr->layers.first; rl; rl= rl->next) { - float *rect = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, R.viewname); + float *rect = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname); if ((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK)) pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask"); @@ -1339,7 +1335,7 @@ void zbufshade_tile(RenderPart *pa) pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz"); for (rl= rr->layers.first; rl; rl= rl->next) { - float *rect= RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, R.viewname); + float *rect= RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname); if ((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK)) pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask"); @@ -1676,7 +1672,7 @@ void zbufshade_sss_tile(RenderPart *pa) return; } - fcol= RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, R.viewname); + fcol= RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname); co= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSCo"); color= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSColor"); @@ -1969,7 +1965,7 @@ void add_halo_flare(Render *re) if ((rl->layflag & SCE_LAY_HALO) == 0) continue; - rect = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, re->viewname); + rect = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, re->viewname); if (rect==NULL) continue; @@ -1998,3 +1994,37 @@ void add_halo_flare(Render *re) } } +void render_internal_update_passes(RenderEngine *engine, Scene *scene, SceneRenderLayer *srl) +{ + int type; + + RE_engine_register_pass(engine, scene, srl, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA); + +#define CHECK_PASS(name, channels, chanid) \ + if (srl->passflag & (SCE_PASS_ ## name)) { \ + if (channels == 4) type = SOCK_RGBA; \ + else if (channels == 3) type = SOCK_VECTOR; \ + else type = SOCK_FLOAT; \ + RE_engine_register_pass(engine, scene, srl, RE_PASSNAME_ ## name, channels, chanid, type); \ + } + + CHECK_PASS(Z, 1, "Z"); + CHECK_PASS(VECTOR, 4, "XYZW"); + CHECK_PASS(NORMAL, 3, "XYZ"); + CHECK_PASS(UV, 3, "UVA"); + CHECK_PASS(RGBA, 4, "RGBA"); + CHECK_PASS(EMIT, 3, "RGB"); + CHECK_PASS(DIFFUSE, 3, "RGB"); + CHECK_PASS(SPEC, 3, "RGB"); + CHECK_PASS(AO, 3, "RGB"); + CHECK_PASS(ENVIRONMENT, 3, "RGB"); + CHECK_PASS(INDIRECT, 3, "RGB"); + CHECK_PASS(SHADOW, 3, "RGB"); + CHECK_PASS(REFLECT, 3, "RGB"); + CHECK_PASS(REFRACT, 3, "RGB"); + CHECK_PASS(INDEXOB, 1, "X"); + CHECK_PASS(INDEXMA, 1, "X"); + CHECK_PASS(MIST, 1, "Z"); + +#undef CHECK_PASS +} diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 76e6ca8d467..199322795f3 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -66,6 +66,7 @@ #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BLI_hash.h" #include "DNA_material_types.h" #include "DNA_meshdata_types.h" @@ -1458,6 +1459,14 @@ ObjectInstanceRen *RE_addRenderInstance( } } + /* Fill object info */ + if (dob) { + obi->random_id = dob->random_id; + } + else { + obi->random_id = BLI_hash_int_2d(BLI_hash_string(obi->ob->id.name + 2), 0); + } + RE_updateRenderInstance(re, obi, RE_OBJECT_INSTANCES_UPDATE_OBMAT | RE_OBJECT_INSTANCES_UPDATE_VIEW); if (mat) { diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index a8fb72fb7f8..8dea0930b9e 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -2141,6 +2141,16 @@ const float (*RE_object_instance_get_matrix(struct ObjectInstanceRen *obi, int m return NULL; } +float RE_object_instance_get_object_pass_index(struct ObjectInstanceRen *obi) +{ + return obi->ob->index; +} + +float RE_object_instance_get_random_id(struct ObjectInstanceRen *obi) +{ + return obi->random_id; +} + const float (*RE_render_current_get_matrix(int matrix_id))[4] { switch (matrix_id) { diff --git a/source/blender/render/intern/source/sunsky.c b/source/blender/render/intern/source/sunsky.c index d4e53eb7305..f0cf29e98ca 100644 --- a/source/blender/render/intern/source/sunsky.c +++ b/source/blender/render/intern/source/sunsky.c @@ -398,7 +398,7 @@ void InitAtmosphere(struct SunSky *sunSky, float sun_intens, float mief, float r vLambda2[0] = fLambda2[0]; vLambda2[1] = fLambda2[1]; vLambda2[2] = fLambda2[2]; - + vLambda4[0] = fLambda4[0]; vLambda4[1] = fLambda4[1]; vLambda4[2] = fLambda4[2]; diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index 610e86caa13..7fe52328781 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -275,10 +275,12 @@ static float metadensity(Object *ob, const float co[3]) break; case MB_CUBE: tp[2] = (tp[2] > ml->expz) ? (tp[2] - ml->expz) : ((tp[2] < -ml->expz) ? (tp[2] + ml->expz) : 0.f); - /* no break, xy as plane */ + /* no break, xy as plane */ + ATTR_FALLTHROUGH; case MB_PLANE: tp[1] = (tp[1] > ml->expy) ? (tp[1] - ml->expy) : ((tp[1] < -ml->expy) ? (tp[1] + ml->expy) : 0.f); - /* no break, x as tube */ + /* no break, x as tube */ + ATTR_FALLTHROUGH; case MB_TUBE: tp[0] = (tp[0] > ml->expx) ? (tp[0] - ml->expx) : ((tp[0] < -ml->expx) ? (tp[0] + ml->expx) : 0.f); } diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 9f777631e52..68707f163af 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -1601,7 +1601,6 @@ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float * * Note: uses globals. * \param v1 start coordinate s * \param v2 target coordinate t - * \param b1 * \param b2 * \param b3 * \param a index for coordinate (x, y, or z) @@ -3494,7 +3493,7 @@ static void add_transp_speed(RenderLayer *rl, int offset, float speed[4], float RenderPass *rpass; for (rpass= rl->passes.first; rpass; rpass= rpass->next) { - if (rpass->passtype==SCE_PASS_VECTOR) { + if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) { float *fp= rpass->rect + 4*offset; if (speed==NULL) { @@ -3528,7 +3527,7 @@ static void add_transp_obindex(RenderLayer *rl, int offset, Object *ob) RenderPass *rpass; for (rpass= rl->passes.first; rpass; rpass= rpass->next) { - if (rpass->passtype == SCE_PASS_INDEXOB) { + if (STREQ(rpass->name, RE_PASSNAME_INDEXOB)) { float *fp= rpass->rect + offset; *fp= (float)ob->index; break; @@ -3541,7 +3540,7 @@ static void add_transp_material_index(RenderLayer *rl, int offset, Material *mat RenderPass *rpass; for (rpass= rl->passes.first; rpass; rpass= rpass->next) { - if (rpass->passtype == SCE_PASS_INDEXMA) { + if (STREQ(rpass->name, RE_PASSNAME_INDEXMA)) { float *fp= rpass->rect + offset; *fp= (float)mat->index; break; @@ -3558,78 +3557,74 @@ static void merge_transp_passes(RenderLayer *rl, ShadeResult *shr) int delta= sizeof(ShadeResult)/4; for (rpass= rl->passes.first; rpass; rpass= rpass->next) { - float *col= NULL; - int pixsize= 3; + float *col = NULL; + int pixsize = 3; - switch (rpass->passtype) { - case SCE_PASS_RGBA: - col= shr->col; - pixsize= 4; - break; - case SCE_PASS_EMIT: - col= shr->emit; - break; - case SCE_PASS_DIFFUSE: - col= shr->diff; - break; - case SCE_PASS_SPEC: - col= shr->spec; - break; - case SCE_PASS_SHADOW: - col= shr->shad; - break; - case SCE_PASS_AO: - col= shr->ao; - break; - case SCE_PASS_ENVIRONMENT: - col= shr->env; - break; - case SCE_PASS_INDIRECT: - col= shr->indirect; - break; - case SCE_PASS_REFLECT: - col= shr->refl; - break; - case SCE_PASS_REFRACT: - col= shr->refr; - break; - case SCE_PASS_NORMAL: - col= shr->nor; - break; - case SCE_PASS_MIST: - col= &shr->mist; - pixsize= 1; - break; - case SCE_PASS_Z: - col= &shr->z; - pixsize= 1; - break; - case SCE_PASS_VECTOR: + if (STREQ(rpass->name, RE_PASSNAME_RGBA)) { + col = shr->col; + pixsize = 4; + } + else if (STREQ(rpass->name, RE_PASSNAME_EMIT)) { + col = shr->emit; + } + else if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) { + col = shr->diff; + } + else if (STREQ(rpass->name, RE_PASSNAME_SPEC)) { + col = shr->spec; + } + else if (STREQ(rpass->name, RE_PASSNAME_SHADOW)) { + col = shr->shad; + } + else if (STREQ(rpass->name, RE_PASSNAME_AO)) { + col = shr->ao; + } + else if (STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) { + col = shr->env; + } + else if (STREQ(rpass->name, RE_PASSNAME_INDIRECT)) { + col = shr->indirect; + } + else if (STREQ(rpass->name, RE_PASSNAME_REFLECT)) { + col = shr->refl; + } + else if (STREQ(rpass->name, RE_PASSNAME_REFRACT)) { + col = shr->refr; + } + else if (STREQ(rpass->name, RE_PASSNAME_NORMAL)) { + col = shr->nor; + } + else if (STREQ(rpass->name, RE_PASSNAME_MIST)) { + col = &shr->mist; + pixsize = 1; + } + else if (STREQ(rpass->name, RE_PASSNAME_Z)) { + col = &shr->z; + pixsize = 1; + } + else if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) { + ShadeResult *shr_t = shr+1; + float *fp = shr->winspeed; /* was initialized */ + int samp; + + /* add minimum speed in pixel */ + for (samp = 1; samp<R.osa; samp++, shr_t++) { - { - ShadeResult *shr_t= shr+1; - float *fp= shr->winspeed; /* was initialized */ - int samp; + if (shr_t->combined[3] > 0.0f) { + const float *speed = shr_t->winspeed; - /* add minimum speed in pixel */ - for (samp= 1; samp<R.osa; samp++, shr_t++) { - - if (shr_t->combined[3] > 0.0f) { - const float *speed= shr_t->winspeed; - - if ( (ABS(speed[0]) + ABS(speed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) { - fp[0]= speed[0]; - fp[1]= speed[1]; - } - if ( (ABS(speed[2]) + ABS(speed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) { - fp[2]= speed[2]; - fp[3]= speed[3]; - } - } + if ( (ABS(speed[0]) + ABS(speed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) { + fp[0] = speed[0]; + fp[1] = speed[1]; + } + if ( (ABS(speed[2]) + ABS(speed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) { + fp[2] = speed[2]; + fp[3] = speed[3]; } } - break; + } } + if (col) { const float *fp= col+delta; int samp; @@ -3661,53 +3656,51 @@ static void add_transp_passes(RenderLayer *rl, int offset, ShadeResult *shr, flo float *fp, *col= NULL; int pixsize= 3; - switch (rpass->passtype) { - case SCE_PASS_Z: - fp= rpass->rect + offset; - if (shr->z < *fp) - *fp= shr->z; - break; - case SCE_PASS_RGBA: - fp= rpass->rect + 4*offset; - addAlphaOverFloat(fp, shr->col); - break; - case SCE_PASS_EMIT: - col= shr->emit; - break; - case SCE_PASS_DIFFUSE: - col= shr->diff; - break; - case SCE_PASS_SPEC: - col= shr->spec; - break; - case SCE_PASS_SHADOW: - col= shr->shad; - break; - case SCE_PASS_AO: - col= shr->ao; - break; - case SCE_PASS_ENVIRONMENT: - col= shr->env; - break; - case SCE_PASS_INDIRECT: - col= shr->indirect; - break; - case SCE_PASS_REFLECT: - col= shr->refl; - break; - case SCE_PASS_REFRACT: - col= shr->refr; - break; - case SCE_PASS_NORMAL: - col= shr->nor; - break; - case SCE_PASS_MIST: - col= &shr->mist; - pixsize= 1; - break; + if (STREQ(rpass->name, RE_PASSNAME_Z)) { + fp = rpass->rect + offset; + if (shr->z < *fp) + *fp = shr->z; + } + else if (STREQ(rpass->name, RE_PASSNAME_RGBA)) { + fp = rpass->rect + 4*offset; + addAlphaOverFloat(fp, shr->col); + } + else if (STREQ(rpass->name, RE_PASSNAME_EMIT)) { + col = shr->emit; + } + else if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) { + col = shr->diff; + } + else if (STREQ(rpass->name, RE_PASSNAME_SPEC)) { + col = shr->spec; + } + else if (STREQ(rpass->name, RE_PASSNAME_SHADOW)) { + col = shr->shad; + } + else if (STREQ(rpass->name, RE_PASSNAME_AO)) { + col = shr->ao; + } + else if (STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) { + col = shr->env; + } + else if (STREQ(rpass->name, RE_PASSNAME_INDIRECT)) { + col = shr->indirect; + } + else if (STREQ(rpass->name, RE_PASSNAME_REFLECT)) { + col = shr->refl; + } + else if (STREQ(rpass->name, RE_PASSNAME_REFRACT)) { + col = shr->refr; + } + else if (STREQ(rpass->name, RE_PASSNAME_NORMAL)) { + col = shr->nor; + } + else if (STREQ(rpass->name, RE_PASSNAME_MIST)) { + col = &shr->mist; + pixsize = 1; } - if (col) { + if (col) { fp= rpass->rect + pixsize*offset; fp[0]= col[0] + (1.0f-alpha)*fp[0]; if (pixsize==3) { @@ -3964,7 +3957,7 @@ static void reset_sky_speedvectors(RenderPart *pa, RenderLayer *rl, float *rectf float *fp, *col; int a; - fp = RE_RenderLayerGetPass(rl, SCE_PASS_VECTOR, R.viewname); + fp = RE_RenderLayerGetPass(rl, RE_PASSNAME_VECTOR, R.viewname); if (fp==NULL) return; col= rectf+3; @@ -4058,7 +4051,7 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas /* zero alpha pixels get speed vector max again */ if (addpassflag & SCE_PASS_VECTOR) if (rl->layflag & SCE_LAY_SOLID) { - float *rect = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, R.viewname); + float *rect = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname); reset_sky_speedvectors(pa, rl, rl->acolrect ? rl->acolrect : rect); /* if acolrect is set we use it */ } /* filtered render, for now we assume only 1 filter size */ @@ -4246,7 +4239,7 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas if (alpha != 0.0f) { RenderLayer *rl_other = ssamp.rlpp[a]; - float *rect = RE_RenderLayerGetPass(rl_other , SCE_PASS_COMBINED, R.viewname); + float *rect = RE_RenderLayerGetPass(rl_other , RE_PASSNAME_COMBINED, R.viewname); addAlphaOverFloat(rect + 4 * od, samp_shr[a].combined); add_transp_passes(rl_other , od, &samp_shr[a], alpha); |