Fix: incorrect configuration of imbuf used for render passes #117184

Merged
Sergey Sharybin merged 2 commits from Sergey/blender:fix_render_result_planes into main 2024-01-17 10:03:09 +01:00
3 changed files with 44 additions and 4 deletions

View File

@ -813,7 +813,7 @@ bool BKE_image_render_write_exr(ReportList *reports,
/* We only store RGBA passes as half float, for
* others precision loss can be problematic. */
const bool pass_RGBA = STR_ELEM(rp->chan_id, "RGB", "RGBA", "R", "G", "B", "A");
const bool pass_RGBA = RE_RenderPassIsColor(rp);
const bool pass_half_float = half_float && pass_RGBA;
/* Color-space conversion only happens on RGBA passes. */

View File

@ -502,6 +502,9 @@ RenderResult *RE_DuplicateRenderResult(RenderResult *rr);
struct ImBuf *RE_RenderPassEnsureImBuf(RenderPass *render_pass);
struct ImBuf *RE_RenderViewEnsureImBuf(const RenderResult *render_result, RenderView *render_view);
/* Returns true if the pass is a color (as opposite of data) and needs to be color managed. */
bool RE_RenderPassIsColor(const RenderPass *render_pass);
#ifdef __cplusplus
}
#endif

View File

@ -167,6 +167,31 @@ void render_result_views_shallowdelete(RenderResult *rr)
/** \name New
* \{ */
static int get_num_planes_for_pass_ibuf(const RenderPass &render_pass)
{
switch (render_pass.channels) {
case 1:
return R_IMF_PLANES_BW;
case 3:
return R_IMF_PLANES_RGB;
case 4:
return R_IMF_PLANES_RGBA;
}
/* Fallback to a commonly used default value of planes for odd-ball number of channel. */
return R_IMF_PLANES_RGBA;
}
static void assign_render_pass_ibuf_colorspace(RenderPass &render_pass)
{
if (RE_RenderPassIsColor(&render_pass)) {
return;
}
const char *data_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DATA);
IMB_colormanagement_assign_float_colorspace(render_pass.ibuf, data_colorspace);
}
static void render_layer_allocate_pass(RenderResult *rr, RenderPass *rp)
{
if (rp->ibuf && rp->ibuf->float_buffer.data) {
@ -179,9 +204,10 @@ static void render_layer_allocate_pass(RenderResult *rr, RenderPass *rp)
const size_t rectsize = size_t(rr->rectx) * rr->recty * rp->channels;
float *buffer_data = MEM_cnew_array<float>(rectsize, rp->name);
rp->ibuf = IMB_allocImBuf(rr->rectx, rr->recty, 32, 0);
rp->ibuf = IMB_allocImBuf(rr->rectx, rr->recty, get_num_planes_for_pass_ibuf(*rp), 0);
rp->ibuf->channels = rp->channels;
IMB_assign_float_buffer(rp->ibuf, buffer_data, IB_TAKE_OWNERSHIP);
assign_render_pass_ibuf_colorspace(*rp);
if (STREQ(rp->name, RE_PASSNAME_VECTOR)) {
/* initialize to max speed */
@ -680,6 +706,7 @@ RenderResult *render_result_new_from_exr(
RenderResult *rr = MEM_cnew<RenderResult>(__func__);
const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get(
COLOR_ROLE_SCENE_LINEAR);
const char *data_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DATA);
rr->rectx = rectx;
rr->recty = recty;
@ -696,7 +723,7 @@ RenderResult *render_result_new_from_exr(
rpass->rectx = rectx;
rpass->recty = recty;
if (rpass->channels >= 3) {
if (RE_RenderPassIsColor(rpass)) {
IMB_colormanagement_transform(rpass->ibuf->float_buffer.data,
rpass->rectx,
rpass->recty,
@ -705,6 +732,9 @@ RenderResult *render_result_new_from_exr(
to_colorspace,
predivide);
}
else {
IMB_colormanagement_assign_float_colorspace(rpass->ibuf, data_colorspace);
}
}
}
@ -1302,8 +1332,10 @@ RenderResult *RE_DuplicateRenderResult(RenderResult *rr)
ImBuf *RE_RenderPassEnsureImBuf(RenderPass *render_pass)
{
if (!render_pass->ibuf) {
render_pass->ibuf = IMB_allocImBuf(render_pass->rectx, render_pass->recty, 32, 0);
render_pass->ibuf = IMB_allocImBuf(
render_pass->rectx, render_pass->recty, get_num_planes_for_pass_ibuf(*render_pass), 0);
render_pass->ibuf->channels = render_pass->channels;
assign_render_pass_ibuf_colorspace(*render_pass);
}
return render_pass->ibuf;
@ -1318,4 +1350,9 @@ ImBuf *RE_RenderViewEnsureImBuf(const RenderResult *render_result, RenderView *r
return render_view->ibuf;
}
bool RE_RenderPassIsColor(const RenderPass *render_pass)
{
return STR_ELEM(render_pass->chan_id, "RGB", "RGBA", "R", "G", "B", "A");
}
/** \} */