Realtime Compositor: Make vectors four dimensional

Currently, the realtime compositor treat vector types as 3D vectors,
which is true for most operations. However, some operations deal with
vector types as 4D vectors that encode two 2D vectors or one 3D vector
with the last component ignored. So this patch expands vector types to
include a fourth component that is only sometimes used.

Since we already stored vectors in RGBA textures, the necessary changes
are straightforward and are mostly concerned with adjusting the Result
class.

Differential Revision: https://developer.blender.org/D16359

Reviewed By: Clement Foucault
This commit is contained in:
Omar Emara 2022-11-02 13:48:20 +02:00
parent 14e4c96b64
commit c394f510a5
6 changed files with 19 additions and 17 deletions

View File

@ -14,7 +14,9 @@
namespace blender::realtime_compositor {
/* Possible data types that operations can operate on. They either represent the base type of the
* result texture or a single value result. */
* result texture or a single value result. The color type represents an RGBA color. And the vector
* type represents a generic 4-component vector, which can encode two 2D vectors, one 3D vector
* with the last component ignored, or other dimensional data. */
enum class ResultType : uint8_t {
Float,
Vector,
@ -85,7 +87,7 @@ class Result {
* is a texture. */
union {
float float_value_;
float3 vector_value_;
float4 vector_value_;
float4 color_value_;
};
/* The domain of the result. This only matters if the result was a texture. See the discussion in
@ -157,7 +159,7 @@ class Result {
/* If the result is a single value result of type vector, return its vector value. Otherwise, an
* uninitialized value is returned. */
float3 get_vector_value() const;
float4 get_vector_value() const;
/* If the result is a single value result of type color, return its color value. Otherwise, an
* uninitialized value is returned. */
@ -167,7 +169,7 @@ class Result {
float get_float_value_default(float default_value) const;
/* Same as get_vector_value but returns a default value if the result is not a single value. */
float3 get_vector_value_default(const float3 &default_value) const;
float4 get_vector_value_default(const float4 &default_value) const;
/* Same as get_color_value but returns a default value if the result is not a single value. */
float4 get_color_value_default(const float4 &default_value) const;
@ -178,7 +180,7 @@ class Result {
/* If the result is a single value result of type vector, set its vector value and upload it to
* the texture. Otherwise, an undefined behavior is invoked. */
void set_vector_value(const float3 &value);
void set_vector_value(const float4 &value);
/* If the result is a single value result of type color, set its color value and upload it to the
* texture. Otherwise, an undefined behavior is invoked. */

View File

@ -60,8 +60,8 @@ class TexturePool {
/* Shorthand for acquire with GPU_RGBA16F format. */
GPUTexture *acquire_color(int2 size);
/* Shorthand for acquire with GPU_RGBA16F format. Identical to acquire_color because vectors
* are stored in RGBA textures, due to the limited support for RGB textures. */
/* Shorthand for acquire with GPU_RGBA16F format. Identical to acquire_color because vectors are
* 4D, and are thus stored in RGBA textures. */
GPUTexture *acquire_vector(int2 size);
/* Shorthand for acquire with GPU_R16F format. */

View File

@ -96,7 +96,7 @@ ConvertFloatToVectorOperation::ConvertFloatToVectorOperation(Context &context)
void ConvertFloatToVectorOperation::execute_single(const Result &input, Result &output)
{
output.set_vector_value(float3(input.get_float_value()));
output.set_vector_value(float4(float3(input.get_float_value()), 0.0f));
}
GPUShader *ConvertFloatToVectorOperation::get_conversion_shader() const
@ -175,7 +175,7 @@ ConvertColorToVectorOperation::ConvertColorToVectorOperation(Context &context)
void ConvertColorToVectorOperation::execute_single(const Result &input, Result &output)
{
float4 color = input.get_color_value();
output.set_vector_value(float3(color));
output.set_vector_value(float4(float3(color), 0.0f));
}
GPUShader *ConvertColorToVectorOperation::get_conversion_shader() const
@ -200,7 +200,7 @@ ConvertVectorToFloatOperation::ConvertVectorToFloatOperation(Context &context)
void ConvertVectorToFloatOperation::execute_single(const Result &input, Result &output)
{
float3 vector = input.get_vector_value();
float4 vector = input.get_vector_value();
output.set_float_value((vector[0] + vector[1] + vector[2]) / 3.0f);
}
@ -226,7 +226,7 @@ ConvertVectorToColorOperation::ConvertVectorToColorOperation(Context &context)
void ConvertVectorToColorOperation::execute_single(const Result &input, Result &output)
{
output.set_color_value(float4(input.get_vector_value(), 1.0f));
output.set_color_value(float4(float3(input.get_vector_value()), 1.0f));
}
GPUShader *ConvertVectorToColorOperation::get_conversion_shader() const

View File

@ -38,7 +38,7 @@ void InputSingleValueOperation::execute()
break;
case ResultType::Vector:
result.set_vector_value(
float3(bsocket->default_value_typed<bNodeSocketValueVector>()->value));
float4(float3(bsocket->default_value_typed<bNodeSocketValueVector>()->value), 0.0f));
break;
case ResultType::Color:
result.set_color_value(float4(bsocket->default_value_typed<bNodeSocketValueRGBA>()->value));

View File

@ -62,7 +62,7 @@ void Result::allocate_invalid()
set_float_value(0.0f);
break;
case ResultType::Vector:
set_vector_value(float3(0.0f));
set_vector_value(float4(0.0f));
break;
case ResultType::Color:
set_color_value(float4(0.0f));
@ -125,7 +125,7 @@ float Result::get_float_value() const
return float_value_;
}
float3 Result::get_vector_value() const
float4 Result::get_vector_value() const
{
return vector_value_;
}
@ -143,7 +143,7 @@ float Result::get_float_value_default(float default_value) const
return default_value;
}
float3 Result::get_vector_value_default(const float3 &default_value) const
float4 Result::get_vector_value_default(const float4 &default_value) const
{
if (is_single_value()) {
return get_vector_value();
@ -165,7 +165,7 @@ void Result::set_float_value(float value)
GPU_texture_update(texture_, GPU_DATA_FLOAT, &float_value_);
}
void Result::set_vector_value(const float3 &value)
void Result::set_vector_value(const float4 &value)
{
vector_value_ = value;
GPU_texture_update(texture_, GPU_DATA_FLOAT, vector_value_);

View File

@ -64,7 +64,7 @@ GPUTexture *TexturePool::acquire_color(int2 size)
GPUTexture *TexturePool::acquire_vector(int2 size)
{
/* Vectors are stored in RGBA textures because RGB textures have limited support. */
/* Vectors are 4D, and are thus stored in RGBA textures. */
return acquire(size, GPU_RGBA16F);
}