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
This commit is contained in:
Brecht Van Lommel 2020-08-25 15:53:57 +02:00
parent 33ac3582bb
commit 21cb6f09ff
Notes: blender-bot 2023-02-14 06:17:14 +01:00
Referenced by issue #80258, Crash on choosing Lattice in panel property
Referenced by issue #80088, Mantaflow FLIP particles not working correctly
Referenced by issue #79859, MacOS EEVEE 2.90 crash on second render
Referenced by issue #79780, Texture baking from multiple objects doesn't work.
Referenced by issue #79533, Crash when opening file
Referenced by issue #77910, Sometimes the Viewport is damaged.
Referenced by issue #77298, Can't bake texture with multiple objects.
4 changed files with 17 additions and 5 deletions

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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

View File

@ -199,6 +199,8 @@ void Pass::add(PassType type, vector<Pass> &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);