From 21cb6f09ffa82e9d2ef8fc41e7161f824984989b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 25 Aug 2020 15:53:57 +0200 Subject: Fix T77298: Cycles multiple object making not working with multiple samples The previous fix loaded the pixels so existing tiles were not overwritten. However the Cycles render buffer is expected to be scaled by the number of sample, which was not taken into account. This is not ideal in that previews could have a mismatched number of samples between multiple objects, though the result will be correct. The better solution would be to bake all objects together per tile, rather than one after the other. But that is a bigger change than we can do in 2.90. Differential Revision: https://developer.blender.org/D8704 --- intern/cycles/blender/blender_session.cpp | 3 ++- intern/cycles/render/buffers.cpp | 15 ++++++++++++--- intern/cycles/render/buffers.h | 2 +- intern/cycles/render/film.cpp | 2 ++ 4 files changed, 17 insertions(+), 5 deletions(-) (limited to 'intern') diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index a06030c8b7d..8f3802733c6 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -363,7 +363,8 @@ void BlenderSession::do_write_update_render_tile(RenderTile &rtile, PassType pass_type = BlenderSync::get_pass_type(b_pass); int components = b_pass.channels(); - rtile.buffers->set_pass_rect(pass_type, components, (float *)b_pass.rect()); + rtile.buffers->set_pass_rect( + pass_type, components, (float *)b_pass.rect(), rtile.num_samples); } end_render_result(b_engine, b_rr, false, false, false); diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp index b26366af852..3607300cee6 100644 --- a/intern/cycles/render/buffers.cpp +++ b/intern/cycles/render/buffers.cpp @@ -459,7 +459,7 @@ bool RenderBuffers::get_pass_rect( return false; } -bool RenderBuffers::set_pass_rect(PassType type, int components, float *pixels) +bool RenderBuffers::set_pass_rect(PassType type, int components, float *pixels, int samples) { if (buffer.data() == NULL) { return false; @@ -482,8 +482,17 @@ bool RenderBuffers::set_pass_rect(PassType type, int components, float *pixels) assert(pass.components == components); for (int i = 0; i < size; i++, out += pass_stride, pixels += components) { - for (int j = 0; j < components; j++) { - out[j] = pixels[j]; + if (pass.filter) { + /* Scale by the number of samples, inverse of what we do in get_pass_rect. + * A better solution would be to remove the need for set_pass_rect entirely, + * and change baking to bake multiple objects in a tile at once. */ + for (int j = 0; j < components; j++) { + out[j] = pixels[j] * samples; + } + } + else { + /* For non-filtered passes just straight copy, these may contain non-float data. */ + memcpy(out, pixels, sizeof(float) * components); } } diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h index 06b6094e6c9..425400a2c08 100644 --- a/intern/cycles/render/buffers.h +++ b/intern/cycles/render/buffers.h @@ -92,7 +92,7 @@ class RenderBuffers { const string &name, float exposure, int sample, int components, float *pixels); bool get_denoising_pass_rect( int offset, float exposure, int sample, int components, float *pixels); - bool set_pass_rect(PassType type, int components, float *pixels); + bool set_pass_rect(PassType type, int components, float *pixels, int samples); }; /* Display Buffer diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp index d7cbf4a3581..7adf95c9510 100644 --- a/intern/cycles/render/film.cpp +++ b/intern/cycles/render/film.cpp @@ -199,6 +199,8 @@ void Pass::add(PassType type, vector &passes, const char *name) case PASS_BAKE_PRIMITIVE: case PASS_BAKE_DIFFERENTIAL: pass.components = 4; + pass.exposure = false; + pass.filter = false; break; default: assert(false); -- cgit v1.2.3