Fix #126604: Legacy Cryptomatte doesn't work in GPU
The Legacy Cryptomatte node doesn't work in GPU execution mode if Precision is set to Auto. That's because the colors picked from the Pick layer might be in half precision and thus will not match the colors in the Cryptomatte layers. This is due to the compositor using the context's precision for Viewer outputs as opposed to the precision of the image that actually needs to be viewed in the Viewer node. To fix this, we set the Viewer node precision to be the precision of its input, that way, the Cryptomatte pick layer will be output in full precision as intended. Pull Request: https://projects.blender.org/blender/blender/pulls/128495
This commit is contained in:
@@ -85,8 +85,11 @@ class Context {
|
||||
virtual Result get_output_result() = 0;
|
||||
|
||||
/* Get the result where the result of the compositor viewer should be written, given the domain
|
||||
* of the result to be viewed and whether the output is a non-color data image. */
|
||||
virtual Result get_viewer_output_result(Domain domain, bool is_data) = 0;
|
||||
* of the result to be viewed, its precision, and whether the output is a non-color data image
|
||||
* that should be displayed without view transform. */
|
||||
virtual Result get_viewer_output_result(Domain domain,
|
||||
bool is_data,
|
||||
ResultPrecision precision) = 0;
|
||||
|
||||
/* Get the texture where the given render pass is stored. This should be called by the Render
|
||||
* Layer node to populate its outputs. */
|
||||
|
||||
@@ -141,8 +141,10 @@ class Context : public realtime_compositor::Context {
|
||||
return result;
|
||||
}
|
||||
|
||||
realtime_compositor::Result get_viewer_output_result(realtime_compositor::Domain /*domain*/,
|
||||
bool /*is_data*/) override
|
||||
realtime_compositor::Result get_viewer_output_result(
|
||||
realtime_compositor::Domain /*domain*/,
|
||||
bool /*is_data*/,
|
||||
realtime_compositor::ResultPrecision /*precision*/) override
|
||||
{
|
||||
realtime_compositor::Result result = this->create_result(
|
||||
realtime_compositor::ResultType::Color, realtime_compositor::ResultPrecision::Half);
|
||||
|
||||
@@ -94,7 +94,8 @@ class ViewerOperation : public NodeOperation {
|
||||
}
|
||||
|
||||
const Domain domain = compute_domain();
|
||||
Result output = context().get_viewer_output_result(domain, image.meta_data.is_non_color_data);
|
||||
Result output = context().get_viewer_output_result(
|
||||
domain, image.meta_data.is_non_color_data, image.precision());
|
||||
if (this->context().use_gpu()) {
|
||||
GPU_texture_clear(output, GPU_DATA_FLOAT, color);
|
||||
}
|
||||
@@ -118,7 +119,8 @@ class ViewerOperation : public NodeOperation {
|
||||
{
|
||||
const Result &image = get_input("Image");
|
||||
const Domain domain = compute_domain();
|
||||
Result output = context().get_viewer_output_result(domain, image.meta_data.is_non_color_data);
|
||||
Result output = context().get_viewer_output_result(
|
||||
domain, image.meta_data.is_non_color_data, image.precision());
|
||||
|
||||
GPUShader *shader = context().get_shader("compositor_write_output_opaque", output.precision());
|
||||
GPU_shader_bind(shader);
|
||||
@@ -142,7 +144,8 @@ class ViewerOperation : public NodeOperation {
|
||||
{
|
||||
const Domain domain = compute_domain();
|
||||
const Result &image = get_input("Image");
|
||||
Result output = context().get_viewer_output_result(domain, image.meta_data.is_non_color_data);
|
||||
Result output = context().get_viewer_output_result(
|
||||
domain, image.meta_data.is_non_color_data, image.precision());
|
||||
|
||||
const Bounds<int2> bounds = get_output_bounds();
|
||||
parallel_for(domain.size, [&](const int2 texel) {
|
||||
@@ -170,7 +173,8 @@ class ViewerOperation : public NodeOperation {
|
||||
{
|
||||
const Result &image = get_input("Image");
|
||||
const Domain domain = compute_domain();
|
||||
Result output = context().get_viewer_output_result(domain, image.meta_data.is_non_color_data);
|
||||
Result output = context().get_viewer_output_result(
|
||||
domain, image.meta_data.is_non_color_data, image.precision());
|
||||
|
||||
GPUShader *shader = context().get_shader("compositor_write_output", output.precision());
|
||||
GPU_shader_bind(shader);
|
||||
@@ -194,7 +198,8 @@ class ViewerOperation : public NodeOperation {
|
||||
{
|
||||
const Domain domain = compute_domain();
|
||||
const Result &image = get_input("Image");
|
||||
Result output = context().get_viewer_output_result(domain, image.meta_data.is_non_color_data);
|
||||
Result output = context().get_viewer_output_result(
|
||||
domain, image.meta_data.is_non_color_data, image.precision());
|
||||
|
||||
const Bounds<int2> bounds = get_output_bounds();
|
||||
parallel_for(domain.size, [&](const int2 texel) {
|
||||
@@ -221,7 +226,8 @@ class ViewerOperation : public NodeOperation {
|
||||
{
|
||||
const Result &image = get_input("Image");
|
||||
const Domain domain = compute_domain();
|
||||
Result output = context().get_viewer_output_result(domain, image.meta_data.is_non_color_data);
|
||||
Result output = context().get_viewer_output_result(
|
||||
domain, image.meta_data.is_non_color_data, image.precision());
|
||||
|
||||
GPUShader *shader = context().get_shader("compositor_write_output_alpha", output.precision());
|
||||
GPU_shader_bind(shader);
|
||||
@@ -250,7 +256,8 @@ class ViewerOperation : public NodeOperation {
|
||||
const Domain domain = compute_domain();
|
||||
const Result &image = get_input("Image");
|
||||
const Result &alpha = get_input("Alpha");
|
||||
Result output = context().get_viewer_output_result(domain, image.meta_data.is_non_color_data);
|
||||
Result output = context().get_viewer_output_result(
|
||||
domain, image.meta_data.is_non_color_data, image.precision());
|
||||
|
||||
const Bounds<int2> bounds = get_output_bounds();
|
||||
parallel_for(domain.size, [&](const int2 texel) {
|
||||
|
||||
@@ -256,25 +256,30 @@ class Context : public realtime_compositor::Context {
|
||||
return output_result_;
|
||||
}
|
||||
|
||||
realtime_compositor::Result get_viewer_output_result(realtime_compositor::Domain domain,
|
||||
const bool is_data) override
|
||||
realtime_compositor::Result get_viewer_output_result(
|
||||
realtime_compositor::Domain domain,
|
||||
const bool is_data,
|
||||
realtime_compositor::ResultPrecision precision) override
|
||||
{
|
||||
viewer_output_result_.set_transformation(domain.transformation);
|
||||
viewer_output_result_.meta_data.is_non_color_data = is_data;
|
||||
|
||||
if (viewer_output_result_.is_allocated()) {
|
||||
/* If the allocated result have the same size as the requested domain, return it as is. */
|
||||
if (domain.size == viewer_output_result_.domain().size) {
|
||||
/* If the allocated result have the same size and precision as requested, return it as is. */
|
||||
if (domain.size == viewer_output_result_.domain().size &&
|
||||
precision == viewer_output_result_.precision())
|
||||
{
|
||||
return viewer_output_result_;
|
||||
}
|
||||
else {
|
||||
/* Otherwise, the size changed, so release its data and reset it, then we reallocate it on
|
||||
* the new domain below. */
|
||||
/* Otherwise, the size or precision changed, so release its data and reset it, then we
|
||||
* reallocate it on the new domain below. */
|
||||
viewer_output_result_.release();
|
||||
viewer_output_result_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
viewer_output_result_.set_precision(precision);
|
||||
viewer_output_result_.allocate_texture(domain, false);
|
||||
return viewer_output_result_;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user