Fix #101263: Vector pass wrongly saved in File Output

The vector pass and potentially other vectors that store 4 values are
stored wrongly, in particular, the last channel is ignored. To fix this
we identify if a vector pass is 4D and store the information in the
result meta data, then use this information to either save a 3D or a 4D
pass in the File Output node.

This is a partial fix for the GPU compositor only. The complete fix for
the CPU compositor will be submitted separately as it is not
straightforward and will likely require a refactor.

Pull Request: https://projects.blender.org/blender/blender/pulls/124522
This commit is contained in:
Omar Emara
2024-07-11 16:08:19 +02:00
committed by Omar Emara
parent 5133a498b1
commit 57a6832b17
5 changed files with 30 additions and 4 deletions

View File

@@ -91,7 +91,7 @@ class Context {
const char *pass_name) = 0;
/* Get the name of the view currently being rendered. */
virtual StringRef get_view_name() = 0;
virtual StringRef get_view_name() const = 0;
/* Get the precision of the intermediate results of the compositor. */
virtual ResultPrecision get_precision() const = 0;

View File

@@ -28,6 +28,10 @@ struct CryptomatteMetaData {
struct MetaData {
/* The result stores non color data, which is not to be color-managed. */
bool is_non_color_data = false;
/* The result stores a 4D vector as opposed to a 3D vector. This is the case for things like
* velocity passes, and we need to mark them as 4D in order to write them to file correctly. This
* field can be ignored for results that are not of type Vector. */
bool is_4d_vector = false;
/* Stores Cryptomatte meta data. This will only be initialized for results that represent
* Cryptomatte information. See the CryptomatteMetaData structure for more information. */
CryptomatteMetaData cryptomatte;

View File

@@ -156,7 +156,7 @@ class Context : public realtime_compositor::Context {
}
}
StringRef get_view_name() override
StringRef get_view_name() const override
{
const SceneRenderView *view = static_cast<SceneRenderView *>(
BLI_findlink(&get_render_data().views, DRW_context_state_get()->v3d->multiview_eye));

View File

@@ -641,7 +641,12 @@ class FileOutputOperation : public NodeOperation {
}
break;
case ResultType::Vector:
file_output.add_pass(pass_name, view_name, "XYZ", float4_to_float3_image(size, buffer));
if (result.meta_data.is_4d_vector) {
file_output.add_pass(pass_name, view_name, "XYZW", buffer);
}
else {
file_output.add_pass(pass_name, view_name, "XYZ", float4_to_float3_image(size, buffer));
}
break;
case ResultType::Float:
file_output.add_pass(pass_name, view_name, "V", buffer);

View File

@@ -327,7 +327,7 @@ class Context : public realtime_compositor::Context {
return input_texture;
}
StringRef get_view_name() override
StringRef get_view_name() const override
{
return input_data_.view_name;
}
@@ -429,6 +429,23 @@ class Context : public realtime_compositor::Context {
},
false);
RenderLayer *render_layer = RE_GetRenderLayer(render_result, view_layer->name);
if (!render_layer) {
RE_ReleaseResult(render);
return;
}
RenderPass *render_pass = RE_pass_find_by_name(
render_layer, pass_name, this->get_view_name().data());
if (!render_pass) {
RE_ReleaseResult(render);
return;
}
if (StringRef(render_pass->chan_id) == "XYZW") {
meta_data.is_4d_vector = true;
}
RE_ReleaseResult(render);
}