diff options
Diffstat (limited to 'source/blender/render')
-rw-r--r-- | source/blender/render/intern/include/render_result.h | 6 | ||||
-rw-r--r-- | source/blender/render/intern/source/envmap.c | 3 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 60 | ||||
-rw-r--r-- | source/blender/render/intern/source/render_result.c | 41 | ||||
-rw-r--r-- | source/blender/render/intern/source/render_texture.c | 21 | ||||
-rw-r--r-- | source/blender/render/intern/source/rendercore.c | 14 | ||||
-rw-r--r-- | source/blender/render/intern/source/shadeinput.c | 9 |
7 files changed, 93 insertions, 61 deletions
diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h index 303d4094f8e..999fb24ba32 100644 --- a/source/blender/render/intern/include/render_result.h +++ b/source/blender/render/intern/include/render_result.h @@ -47,6 +47,8 @@ struct RenderLayer; struct RenderResult; struct Scene; struct rcti; +struct ColorManagedDisplaySettings; +struct ColorManagedViewSettings; /* New */ @@ -90,7 +92,9 @@ void render_result_rect_from_ibuf(struct RenderResult *rr, struct RenderData *rd void render_result_rect_fill_zero(struct RenderResult *rr); void render_result_rect_get_pixels(struct RenderResult *rr, struct RenderData *rd, - unsigned int *rect, int rectx, int recty); + unsigned int *rect, int rectx, int recty, + const struct ColorManagedViewSettings *view_settings, + const struct ColorManagedDisplaySettings *display_settings); #endif /* __RENDER_RESULT_H__ */ diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 26bd482af69..03eb21dfa23 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -472,9 +472,6 @@ static void render_envmap(Render *re, EnvMap *env) ibuf = IMB_allocImBuf(envre->rectx, envre->recty, 24, IB_rect | IB_rectfloat); memcpy(ibuf->rect_float, rl->rectf, ibuf->channels * ibuf->x * ibuf->y * sizeof(float)); - if (re->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) - ibuf->profile = IB_PROFILE_LINEAR_RGB; - /* envmap renders without alpha */ alpha = ibuf->rect_float + 3; for (y = ibuf->x * ibuf->y - 1; y >= 0; y--, alpha += 4) diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 5f110410978..599d91333e6 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -67,6 +67,7 @@ #include "BLI_callbacks.h" #include "PIL_time.h" +#include "IMB_colormanagement.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -333,7 +334,7 @@ void RE_ResultGet32(Render *re, unsigned int *rect) RenderResult rres; RE_AcquireResultImage(re, &rres); - render_result_rect_get_pixels(&rres, &re->r, rect, re->rectx, re->recty); + render_result_rect_get_pixels(&rres, &re->r, rect, re->rectx, re->recty, &re->scene->view_settings, &re->scene->display_settings); RE_ReleaseResultImage(re); } @@ -1434,7 +1435,7 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree) ntreeCompositTagRender(re->scene); ntreeCompositTagAnimated(ntree); - ntreeCompositExecTree(ntree, &re->r, 1, G.background == 0); + ntreeCompositExecTree(ntree, &re->r, 1, G.background == 0, &re->scene->view_settings, &re->scene->display_settings); } /* ensure we get either composited result or the active layer */ @@ -1598,7 +1599,7 @@ static void do_render_composite_fields_blur_3d(Render *re) if (re->r.scemode & R_FULL_SAMPLE) do_merge_fullsample(re, ntree); else { - ntreeCompositExecTree(ntree, &re->r, 1, G.background == 0); + ntreeCompositExecTree(ntree, &re->r, 1, G.background == 0, &re->scene->view_settings, &re->scene->display_settings); } ntree->stats_draw = NULL; @@ -1647,7 +1648,7 @@ int RE_seq_render_active(Scene *scene, RenderData *rd) static void do_render_seq(Render *re) { static int recurs_depth = 0; - struct ImBuf *ibuf; + struct ImBuf *ibuf, *out; RenderResult *rr; /* don't assign re->result here as it might change during give_ibuf_seq */ int cfra = re->r.cfra; SeqRenderData context; @@ -1674,7 +1675,11 @@ static void do_render_seq(Render *re) 100); } - ibuf = BKE_sequencer_give_ibuf(context, cfra, 0); + out = BKE_sequencer_give_ibuf(context, cfra, 0); + + ibuf = IMB_dupImBuf(out); + IMB_freeImBuf(out); + BKE_sequencer_imbuf_from_sequencer_space(re->scene, ibuf); recurs_depth--; @@ -2069,6 +2074,14 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr G.is_rendering = FALSE; } +static void colormanage_image_for_write(Scene *scene, ImBuf *ibuf) +{ + IMB_display_buffer_to_imbuf_rect(ibuf, &scene->view_settings, &scene->display_settings); + + if (ibuf) + imb_freerectfloatImBuf(ibuf); +} + static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovieHandle *mh, const char *name_override) { char name[FILE_MAX]; @@ -2081,19 +2094,27 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie /* write movie or image */ if (BKE_imtype_is_movie(scene->r.im_format.imtype)) { int do_free = FALSE; - unsigned int *rect32 = (unsigned int *)rres.rect32; + ImBuf *ibuf = render_result_rect_to_ibuf(&rres, &scene->r); + /* note; the way it gets 32 bits rects is weak... */ - if (rres.rect32 == NULL) { - rect32 = MEM_mapallocN(sizeof(int) * rres.rectx * rres.recty, "temp 32 bits rect"); - RE_ResultGet32(re, rect32); + if (ibuf->rect == NULL) { + ibuf->rect = MEM_mapallocN(sizeof(int) * rres.rectx * rres.recty, "temp 32 bits rect"); + RE_ResultGet32(re, ibuf->rect); do_free = TRUE; } - ok = mh->append_movie(&re->r, scene->r.sfra, scene->r.cfra, (int *)rect32, - rres.rectx, rres.recty, re->reports); + colormanage_image_for_write(scene, ibuf); + + ok = mh->append_movie(&re->r, scene->r.sfra, scene->r.cfra, (int *) ibuf->rect, + ibuf->x, ibuf->y, re->reports); if (do_free) { - MEM_freeN(rect32); + MEM_freeN(ibuf->rect); + ibuf->rect = NULL; } + + /* imbuf knows which rects are not part of ibuf */ + IMB_freeImBuf(ibuf); + printf("Append frame %d", scene->r.cfra); } else { @@ -2110,6 +2131,12 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie } else { ImBuf *ibuf = render_result_rect_to_ibuf(&rres, &scene->r); + int do_colormanagement; + + do_colormanagement = !BKE_imtype_supports_float(scene->r.im_format.imtype); + + if (do_colormanagement) + colormanage_image_for_write(scene, ibuf); ok = BKE_imbuf_write_stamp(scene, camera, ibuf, name, &scene->r.im_format); @@ -2127,6 +2154,9 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie name[strlen(name) - 4] = 0; BKE_add_image_extension(name, R_IMF_IMTYPE_JPEG90); ibuf->planes = 24; + + colormanage_image_for_write(scene, ibuf); + BKE_imbuf_write_stamp(scene, camera, ibuf, name, &imf); printf("\nSaved: %s", name); } @@ -2381,7 +2411,8 @@ void RE_init_threadcount(Render *re) * x/y offsets are only used on a partial copy when dimensions don't match */ void RE_layer_load_from_file(RenderLayer *layer, ReportList *reports, const char *filename, int x, int y) { - ImBuf *ibuf = IMB_loadiffname(filename, IB_rect); + /* OCIO_TODO: assume layer was saved in defaule color space */ + ImBuf *ibuf = IMB_loadiffname(filename, IB_rect, NULL); if (ibuf && (ibuf->rect || ibuf->rect_float)) { if (ibuf->x == layer->rectx && ibuf->y == layer->recty) { @@ -2470,8 +2501,7 @@ int RE_WriteEnvmapResult(struct ReportList *reports, Scene *scene, EnvMap *env, return 0; } - if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) - ibuf->profile = IB_PROFILE_LINEAR_RGB; + IMB_display_buffer_to_imbuf_rect(ibuf, &scene->view_settings, &scene->display_settings); /* to save, we first get absolute path */ BLI_strncpy(filepath, relpath, sizeof(filepath)); diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index 2f932b2149e..f11f84c9d3b 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -50,6 +50,7 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" +#include "IMB_colormanagement.h" #include "intern/openexr/openexr_multi.h" @@ -1081,16 +1082,12 @@ ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd) /* float factor for random dither, imbuf takes care of it */ ibuf->dither = rd->dither_intensity; - /* prepare to gamma correct to sRGB color space */ - if (rd->color_mgt_flag & R_COLOR_MANAGEMENT) { - /* sequence editor can generate 8bpc render buffers */ - if (ibuf->rect) { - ibuf->profile = IB_PROFILE_SRGB; - if (BKE_imtype_valid_depths(rd->im_format.imtype) & (R_IMF_CHAN_DEPTH_12 | R_IMF_CHAN_DEPTH_16 | R_IMF_CHAN_DEPTH_24 | R_IMF_CHAN_DEPTH_32)) - IMB_float_from_rect(ibuf); - } - else { - ibuf->profile = IB_PROFILE_LINEAR_RGB; + /* prepare to gamma correct to sRGB color space + * note that sequence editor can generate 8bpc render buffers + */ + if (ibuf->rect) { + if (BKE_imtype_valid_depths(rd->im_format.imtype) & (R_IMF_CHAN_DEPTH_12 | R_IMF_CHAN_DEPTH_16 | R_IMF_CHAN_DEPTH_24 | R_IMF_CHAN_DEPTH_32)) { + IMB_float_from_rect(ibuf); } } @@ -1106,22 +1103,14 @@ ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd) return ibuf; } -void render_result_rect_from_ibuf(RenderResult *rr, RenderData *rd, ImBuf *ibuf) +void render_result_rect_from_ibuf(RenderResult *rr, RenderData *UNUSED(rd), ImBuf *ibuf) { if (ibuf->rect_float) { - /* color management: when off ensure rectf is non-lin, since thats what the internal - * render engine delivers */ - int profile_to = (rd->color_mgt_flag & R_COLOR_MANAGEMENT) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_SRGB; - int profile_from = (ibuf->profile == IB_PROFILE_LINEAR_RGB) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_SRGB; - int predivide = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE); - if (!rr->rectf) rr->rectf = MEM_mallocN(4 * sizeof(float) * rr->rectx * rr->recty, "render_seq rectf"); - IMB_buffer_float_from_float(rr->rectf, ibuf->rect_float, - 4, profile_to, profile_from, predivide, - rr->rectx, rr->recty, rr->rectx, rr->rectx); - + memcpy(rr->rectf, ibuf->rect_float, 4 * sizeof(float) * rr->rectx * rr->recty); + /* TSK! Since sequence render doesn't free the *rr render result, the old rect32 * can hang around when sequence render has rendered a 32 bits one before */ if (rr->rect32) { @@ -1153,19 +1142,17 @@ void render_result_rect_fill_zero(RenderResult *rr) rr->rect32 = MEM_callocN(sizeof(int) * rr->rectx * rr->recty, "render_seq rect"); } -void render_result_rect_get_pixels(RenderResult *rr, RenderData *rd, unsigned int *rect, int rectx, int recty) +void render_result_rect_get_pixels(RenderResult *rr, RenderData *rd, unsigned int *rect, int rectx, int recty, + const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings) { if (rr->rect32) { memcpy(rect, rr->rect32, sizeof(int) * rr->rectx * rr->recty); } else if (rr->rectf) { - int profile_from = (rd->color_mgt_flag & R_COLOR_MANAGEMENT) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_SRGB; int predivide = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE); - int dither = 0; - IMB_buffer_byte_from_float((unsigned char *)rect, rr->rectf, - 4, dither, IB_PROFILE_SRGB, profile_from, predivide, - rr->rectx, rr->recty, rr->rectx, rr->rectx); + IMB_display_buffer_transform_apply((unsigned char *) rect, rr->rectf, rr->rectx, rr->recty, 4, + view_settings, display_settings, predivide); } else /* else fill with black */ diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 4d3b9c2493e..6d22d8991b4 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -50,6 +50,7 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" +#include "IMB_colormanagement.h" #include "BKE_colortools.h" #include "BKE_image.h" @@ -1226,8 +1227,8 @@ int multitex_nodes(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, ImBuf *ibuf = BKE_image_get_ibuf(tex->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); + if (ibuf && !(ibuf->rect_float)) + IMB_colormanagement_colorspace_to_scene_linear_v3(&texres->tr, ibuf->rect_colorspace); } } else { @@ -2379,8 +2380,8 @@ void do_material_tex(ShadeInput *shi, Render *re) ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float) && re->r.color_mgt_flag & R_COLOR_MANAGEMENT) - srgb_to_linearrgb_v3_v3(tcol, tcol); + if (ibuf && !(ibuf->rect_float)) + IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace); } if (mtex->mapto & MAP_COL) { @@ -2891,8 +2892,8 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4]) 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); + if (ibuf && !(ibuf->rect_float)) + IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace); } fact= texres.tin*mtex->colfac; @@ -3106,8 +3107,8 @@ void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float h 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 (ibuf && !(ibuf->rect_float)) + IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace); } if (mtex->mapto & WOMAP_HORIZ) { @@ -3320,8 +3321,8 @@ void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r 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); + if (ibuf && !(ibuf->rect_float)) + IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace); } /* lamp colors were premultiplied with this */ diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index c009c7b7394..97a05e6a4c9 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -62,6 +62,7 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" +#include "IMB_colormanagement.h" /* local include */ #include "rayintersection.h" @@ -1993,6 +1994,8 @@ typedef struct BakeShade { float dxco[3], dyco[3]; short *do_update; + + struct ColorSpace *rect_colorspace; } BakeShade; static void bake_set_shade_input(ObjectInstanceRen *obi, VlakRen *vlr, ShadeInput *shi, int quad, int UNUSED(isect), int x, int y, float u, float v) @@ -2168,8 +2171,12 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua else { unsigned char *col= (unsigned char *)(bs->rect + bs->rectx*y + x); - if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE) && (R.r.color_mgt_flag & R_COLOR_MANAGEMENT)) { - linearrgb_to_srgb_uchar3(col, shr.combined); + if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) { + float rgb[3]; + + copy_v3_v3(rgb, shr.combined); + IMB_colormanagement_scene_linear_to_colorspace_v3(rgb, bs->rect_colorspace); + rgb_float_to_uchar(col, rgb); } else { rgb_float_to_uchar(col, shr.combined); @@ -2503,6 +2510,7 @@ static void shade_tface(BakeShade *bs) bs->rectx= bs->ibuf->x; bs->recty= bs->ibuf->y; bs->rect= bs->ibuf->rect; + bs->rect_colorspace= bs->ibuf->rect_colorspace; bs->rect_float= bs->ibuf->rect_float; bs->quad= 0; @@ -2613,8 +2621,6 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up ima->flag&= ~IMA_USED_FOR_RENDER; if (ibuf) { ibuf->userdata = NULL; /* use for masking if needed */ - if (ibuf->rect_float) - ibuf->profile = IB_PROFILE_LINEAR_RGB; } } diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index bbdcfbb5a73..d1d2c66985e 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -1325,7 +1325,14 @@ void shade_input_initialize(ShadeInput *shi, RenderPart *pa, RenderLayer *rl, in shi->sample = sample; shi->thread = pa->thread; shi->do_preview = (R.r.scemode & R_MATNODE_PREVIEW) != 0; - shi->do_manage = (R.r.color_mgt_flag & R_COLOR_MANAGEMENT); + + /* OCIO_TODO: for now assume color management is always enabled and vertes colors are in sRGB space + * probably would be nice to have this things configurable, but for now it should work + * also probably this flag could be removed (in separated commit) before the release + * since it's not actually meaningful anymore + */ + shi->do_manage = TRUE; + shi->lay = rl->lay; shi->layflag = rl->layflag; shi->passflag = rl->passflag; |