Compositor: Add boolean socket support
This patch adds support for boolean sockets in the compositor. This involves adding a new Bool ResultType and handling it in relevant code. For shader operations, booleans are passes as floats since GPUMaterial does not yet support boolean types. Pull Request: https://projects.blender.org/blender/blender/pulls/136296
This commit is contained in:
@@ -41,6 +41,7 @@ enum class ResultType : uint8_t {
|
||||
Int,
|
||||
Int2,
|
||||
Color,
|
||||
Bool,
|
||||
};
|
||||
|
||||
/* The precision of the data. CPU data is always stored using full precision at the moment. */
|
||||
@@ -129,7 +130,7 @@ class Result {
|
||||
* which will be identical to that stored in the data_ member. The active variant member depends
|
||||
* on the type of the result. This member is uninitialized and should not be used if the result
|
||||
* is not a single value. */
|
||||
std::variant<float, float2, float3, float4, int32_t, int2> single_value_ = 0.0f;
|
||||
std::variant<float, float2, float3, float4, int32_t, int2, bool> single_value_ = 0.0f;
|
||||
/* The domain of the result. This only matters if the result was not a single value. See the
|
||||
* discussion in COM_domain.hh for more information. */
|
||||
Domain domain_ = Domain::identity();
|
||||
@@ -449,6 +450,7 @@ BLI_INLINE_METHOD int64_t Result::channels_count() const
|
||||
switch (type_) {
|
||||
case ResultType::Float:
|
||||
case ResultType::Int:
|
||||
case ResultType::Bool:
|
||||
return 1;
|
||||
case ResultType::Float2:
|
||||
case ResultType::Int2:
|
||||
|
||||
@@ -53,7 +53,7 @@ void ConversionOperation::execute()
|
||||
GPU_shader_bind(shader);
|
||||
|
||||
if (this->get_input().type() == ResultType::Color &&
|
||||
ELEM(this->get_result().type(), ResultType::Float, ResultType::Int))
|
||||
ELEM(this->get_result().type(), ResultType::Float, ResultType::Int, ResultType::Bool))
|
||||
{
|
||||
float luminance_coefficients[3];
|
||||
IMB_colormanagement_get_luminance_coefficients(luminance_coefficients);
|
||||
|
||||
@@ -39,6 +39,11 @@ void InputSingleValueOperation::execute()
|
||||
result.set_single_value(value);
|
||||
break;
|
||||
}
|
||||
case SOCK_BOOLEAN: {
|
||||
const bool value = input_socket_->default_value_typed<bNodeSocketValueBoolean>()->value;
|
||||
result.set_single_value(value);
|
||||
break;
|
||||
}
|
||||
case SOCK_VECTOR: {
|
||||
const float3 value = input_socket_->default_value_typed<bNodeSocketValueVector>()->value;
|
||||
result.set_single_value(value);
|
||||
|
||||
@@ -219,6 +219,11 @@ mf::Variable *MultiFunctionProcedureOperation::get_constant_input_variable(DInpu
|
||||
constant_function = &procedure_.construct_function<mf::CustomMF_Constant<int32_t>>(value);
|
||||
break;
|
||||
}
|
||||
case SOCK_BOOLEAN: {
|
||||
const bool value = input->default_value_typed<bNodeSocketValueBoolean>()->value;
|
||||
constant_function = &procedure_.construct_function<mf::CustomMF_Constant<bool>>(value);
|
||||
break;
|
||||
}
|
||||
case SOCK_VECTOR: {
|
||||
const float3 value = float3(input->default_value_typed<bNodeSocketValueVector>()->value);
|
||||
constant_function = &procedure_.construct_function<mf::CustomMF_Constant<float3>>(value);
|
||||
|
||||
@@ -137,6 +137,7 @@ const char *RealizeOnDomainOperation::get_realization_shader_name()
|
||||
case ResultType::Int:
|
||||
case ResultType::Int2:
|
||||
case ResultType::Float2:
|
||||
case ResultType::Bool:
|
||||
/* Realization does not support internal image types. */
|
||||
break;
|
||||
}
|
||||
@@ -152,6 +153,7 @@ const char *RealizeOnDomainOperation::get_realization_shader_name()
|
||||
case ResultType::Int:
|
||||
case ResultType::Int2:
|
||||
case ResultType::Float2:
|
||||
case ResultType::Bool:
|
||||
/* Realization does not support internal image types. */
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -59,6 +59,9 @@ eGPUTextureFormat Result::gpu_texture_format(ResultType type, ResultPrecision pr
|
||||
return GPU_R16I;
|
||||
case ResultType::Int2:
|
||||
return GPU_RG16I;
|
||||
case ResultType::Bool:
|
||||
/* No bool texture formats, so we store in an 8-bit integer. Precision doesn't matter. */
|
||||
return GPU_R8I;
|
||||
}
|
||||
break;
|
||||
case ResultPrecision::Full:
|
||||
@@ -78,6 +81,9 @@ eGPUTextureFormat Result::gpu_texture_format(ResultType type, ResultPrecision pr
|
||||
return GPU_R32I;
|
||||
case ResultType::Int2:
|
||||
return GPU_RG32I;
|
||||
case ResultType::Bool:
|
||||
/* No bool texture formats, so we store in an 8-bit integer. Precision doesn't matter. */
|
||||
return GPU_R8I;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -100,6 +106,10 @@ eGPUTextureFormat Result::gpu_texture_format(eGPUTextureFormat format, ResultPre
|
||||
case GPU_RG16I:
|
||||
return format;
|
||||
|
||||
/* Used to store booleans where precision doesn't matter. */
|
||||
case GPU_R8I:
|
||||
return format;
|
||||
|
||||
case GPU_R32F:
|
||||
return GPU_R16F;
|
||||
case GPU_RG32F:
|
||||
@@ -127,6 +137,10 @@ eGPUTextureFormat Result::gpu_texture_format(eGPUTextureFormat format, ResultPre
|
||||
case GPU_RG32I:
|
||||
return format;
|
||||
|
||||
/* Used to store booleans where precision doesn't matter. */
|
||||
case GPU_R8I:
|
||||
return format;
|
||||
|
||||
case GPU_R16F:
|
||||
return GPU_R32F;
|
||||
case GPU_RG16F:
|
||||
@@ -166,6 +180,9 @@ ResultPrecision Result::precision(eGPUTextureFormat format)
|
||||
case GPU_R32I:
|
||||
case GPU_RG32I:
|
||||
return ResultPrecision::Full;
|
||||
/* Used to store booleans where precision doesn't matter. */
|
||||
case GPU_R8I:
|
||||
return ResultPrecision::Full;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -195,6 +212,8 @@ ResultType Result::type(eGPUTextureFormat format)
|
||||
case GPU_RG16I:
|
||||
case GPU_RG32I:
|
||||
return ResultType::Int2;
|
||||
case GPU_R8I:
|
||||
return ResultType::Bool;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -239,6 +258,8 @@ const CPPType &Result::cpp_type(const ResultType type)
|
||||
return CPPType::get<float3>();
|
||||
case ResultType::Int2:
|
||||
return CPPType::get<int2>();
|
||||
case ResultType::Bool:
|
||||
return CPPType::get<bool>();
|
||||
}
|
||||
|
||||
BLI_assert_unreachable();
|
||||
@@ -262,6 +283,8 @@ const char *Result::type_name(const ResultType type)
|
||||
return "int2";
|
||||
case ResultType::Int:
|
||||
return "int";
|
||||
case ResultType::Bool:
|
||||
return "bool";
|
||||
}
|
||||
|
||||
BLI_assert_unreachable();
|
||||
@@ -328,6 +351,9 @@ void Result::allocate_single_value()
|
||||
case ResultType::Int2:
|
||||
this->set_single_value(int2(0));
|
||||
break;
|
||||
case ResultType::Bool:
|
||||
this->set_single_value(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -648,6 +674,7 @@ void Result::update_single_value_data()
|
||||
}
|
||||
case ResultType::Int:
|
||||
case ResultType::Int2:
|
||||
case ResultType::Bool:
|
||||
GPU_texture_update(this->gpu_texture(), GPU_DATA_INT, this->single_value().get());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -176,6 +176,12 @@ static void initialize_input_stack_value(const DInputSocket input, GPUNodeStack
|
||||
stack.vec[0] = int(value);
|
||||
break;
|
||||
}
|
||||
case SOCK_BOOLEAN: {
|
||||
/* GPUMaterial doesn't support bool, so it is stored as a float. */
|
||||
const bool value = input->default_value_typed<bNodeSocketValueBoolean>()->value;
|
||||
stack.vec[0] = float(value);
|
||||
break;
|
||||
}
|
||||
case SOCK_VECTOR: {
|
||||
const float3 value = float3(input->default_value_typed<bNodeSocketValueVector>()->value);
|
||||
copy_v3_v3(stack.vec, value);
|
||||
@@ -200,6 +206,9 @@ static const char *get_set_function_name(const ResultType type)
|
||||
case ResultType::Int:
|
||||
/* GPUMaterial doesn't support int, so it is passed as a float. */
|
||||
return "set_value";
|
||||
case ResultType::Bool:
|
||||
/* GPUMaterial doesn't support bool, so it is passed as a float. */
|
||||
return "set_value";
|
||||
case ResultType::Float3:
|
||||
return "set_rgb";
|
||||
case ResultType::Color:
|
||||
@@ -345,6 +354,8 @@ static const char *get_store_function_name(ResultType type)
|
||||
return "node_compositor_store_output_float";
|
||||
case ResultType::Int:
|
||||
return "node_compositor_store_output_int";
|
||||
case ResultType::Bool:
|
||||
return "node_compositor_store_output_bool";
|
||||
case ResultType::Float3:
|
||||
return "node_compositor_store_output_float3";
|
||||
case ResultType::Color:
|
||||
@@ -443,6 +454,10 @@ static const char *glsl_store_expression_from_result_type(ResultType type)
|
||||
/* GPUMaterial doesn't support int, so it is passed as a float, and we need to convert it
|
||||
* back to int before writing it. */
|
||||
return "ivec4(int(value))";
|
||||
case ResultType::Bool:
|
||||
/* GPUMaterial doesn't support bool, so it is passed as a float and stored as an int, and we
|
||||
* need to convert it back to bool and then to an int before writing it. */
|
||||
return "ivec4(bool(value))";
|
||||
case ResultType::Float3:
|
||||
return "vec4(value, 0.0)";
|
||||
case ResultType::Color:
|
||||
@@ -474,6 +489,7 @@ static ImageType gpu_image_type_from_result_type(const ResultType type)
|
||||
return ImageType::FLOAT_2D;
|
||||
case ResultType::Int:
|
||||
case ResultType::Int2:
|
||||
case ResultType::Bool:
|
||||
return ImageType::INT_2D;
|
||||
}
|
||||
|
||||
@@ -486,6 +502,8 @@ void ShaderOperation::generate_code_for_outputs(ShaderCreateInfo &shader_create_
|
||||
const std::string store_float_function_header = "void store_float(const uint id, float value)";
|
||||
/* GPUMaterial doesn't support int, so it is passed as a float. */
|
||||
const std::string store_int_function_header = "void store_int(const uint id, float value)";
|
||||
/* GPUMaterial doesn't support bool, so it is passed as a float. */
|
||||
const std::string store_bool_function_header = "void store_bool(const uint id, float value)";
|
||||
const std::string store_float3_function_header = "void store_float3(const uint id, vec3 value)";
|
||||
const std::string store_color_function_header = "void store_color(const uint id, vec4 value)";
|
||||
const std::string store_float4_function_header = "void store_float4(const uint id, vec4 value)";
|
||||
@@ -500,6 +518,7 @@ void ShaderOperation::generate_code_for_outputs(ShaderCreateInfo &shader_create_
|
||||
if (GPU_backend_get_type() != GPU_BACKEND_METAL) {
|
||||
shader_create_info.typedef_source_generated += store_float_function_header + ";\n";
|
||||
shader_create_info.typedef_source_generated += store_int_function_header + ";\n";
|
||||
shader_create_info.typedef_source_generated += store_bool_function_header + ";\n";
|
||||
shader_create_info.typedef_source_generated += store_float3_function_header + ";\n";
|
||||
shader_create_info.typedef_source_generated += store_color_function_header + ";\n";
|
||||
shader_create_info.typedef_source_generated += store_float4_function_header + ";\n";
|
||||
@@ -512,6 +531,7 @@ void ShaderOperation::generate_code_for_outputs(ShaderCreateInfo &shader_create_
|
||||
* the functions. */
|
||||
std::stringstream store_float_function;
|
||||
std::stringstream store_int_function;
|
||||
std::stringstream store_bool_function;
|
||||
std::stringstream store_float3_function;
|
||||
std::stringstream store_color_function;
|
||||
std::stringstream store_float4_function;
|
||||
@@ -520,6 +540,7 @@ void ShaderOperation::generate_code_for_outputs(ShaderCreateInfo &shader_create_
|
||||
const std::string store_function_start = "\n{\n switch (id) {\n";
|
||||
store_float_function << store_float_function_header << store_function_start;
|
||||
store_int_function << store_int_function_header << store_function_start;
|
||||
store_bool_function << store_bool_function_header << store_function_start;
|
||||
store_float3_function << store_float3_function_header << store_function_start;
|
||||
store_color_function << store_color_function_header << store_function_start;
|
||||
store_float4_function << store_float4_function_header << store_function_start;
|
||||
@@ -555,6 +576,9 @@ void ShaderOperation::generate_code_for_outputs(ShaderCreateInfo &shader_create_
|
||||
case ResultType::Int:
|
||||
store_int_function << case_code.str();
|
||||
break;
|
||||
case ResultType::Bool:
|
||||
store_bool_function << case_code.str();
|
||||
break;
|
||||
case ResultType::Float3:
|
||||
store_float3_function << case_code.str();
|
||||
break;
|
||||
@@ -577,19 +601,17 @@ void ShaderOperation::generate_code_for_outputs(ShaderCreateInfo &shader_create_
|
||||
const std::string store_function_end = " }\n}\n\n";
|
||||
store_float_function << store_function_end;
|
||||
store_int_function << store_function_end;
|
||||
store_bool_function << store_function_end;
|
||||
store_float3_function << store_function_end;
|
||||
store_color_function << store_function_end;
|
||||
store_float4_function << store_function_end;
|
||||
store_float2_function << store_function_end;
|
||||
store_int2_function << store_function_end;
|
||||
|
||||
shader_create_info.compute_source_generated += store_float_function.str() +
|
||||
store_int_function.str() +
|
||||
store_float3_function.str() +
|
||||
store_color_function.str() +
|
||||
store_float4_function.str() +
|
||||
store_float2_function.str() +
|
||||
store_int2_function.str();
|
||||
shader_create_info.compute_source_generated +=
|
||||
store_float_function.str() + store_int_function.str() + store_bool_function.str() +
|
||||
store_float3_function.str() + store_color_function.str() + store_float4_function.str() +
|
||||
store_float2_function.str() + store_int2_function.str();
|
||||
}
|
||||
|
||||
static const char *glsl_type_from_result_type(ResultType type)
|
||||
@@ -600,6 +622,9 @@ static const char *glsl_type_from_result_type(ResultType type)
|
||||
case ResultType::Int:
|
||||
/* GPUMaterial doesn't support int, so it is passed as a float. */
|
||||
return "float";
|
||||
case ResultType::Bool:
|
||||
/* GPUMaterial doesn't support bool, so it is passed as a float. */
|
||||
return "float";
|
||||
case ResultType::Float3:
|
||||
return "vec3";
|
||||
case ResultType::Color:
|
||||
@@ -624,6 +649,7 @@ static const char *glsl_swizzle_from_result_type(ResultType type)
|
||||
switch (type) {
|
||||
case ResultType::Float:
|
||||
case ResultType::Int:
|
||||
case ResultType::Bool:
|
||||
return "x";
|
||||
case ResultType::Float3:
|
||||
return "xyz";
|
||||
|
||||
@@ -58,6 +58,8 @@ ResultType get_node_socket_result_type(const bNodeSocket *socket)
|
||||
return ResultType::Float;
|
||||
case SOCK_INT:
|
||||
return ResultType::Int;
|
||||
case SOCK_BOOLEAN:
|
||||
return ResultType::Bool;
|
||||
case SOCK_VECTOR:
|
||||
/* Vector sockets can also be ResultType::Float4 or ResultType::Float2, but the
|
||||
* developer is expected to define that manually since there is no way to distinguish them
|
||||
|
||||
@@ -66,6 +66,13 @@ DEFINE_VALUE("CONVERT_EXPRESSION(value)", "vec4(float_to_float4(value.x))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_float_to_bool)
|
||||
ADDITIONAL_INFO(compositor_convert_float_shared)
|
||||
IMAGE(0, GPU_R8I, WRITE, INT_2D, output_img)
|
||||
DEFINE_VALUE("CONVERT_EXPRESSION(value)", "ivec4(float_to_bool(value.x))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Int to other.
|
||||
*/
|
||||
@@ -112,6 +119,13 @@ DEFINE_VALUE("CONVERT_EXPRESSION(value)", "vec4(int_to_float4(value.x))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_int_to_bool)
|
||||
ADDITIONAL_INFO(compositor_convert_int_shared)
|
||||
IMAGE(0, GPU_R8I, WRITE, INT_2D, output_img)
|
||||
DEFINE_VALUE("CONVERT_EXPRESSION(value)", "ivec4(int_to_bool(value.x))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Int2 to other.
|
||||
*/
|
||||
@@ -158,6 +172,13 @@ DEFINE_VALUE("CONVERT_EXPRESSION(value)", "vec4(int2_to_float4(value.xy))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_int2_to_bool)
|
||||
ADDITIONAL_INFO(compositor_convert_int_shared)
|
||||
IMAGE(0, GPU_R8I, WRITE, INT_2D, output_img)
|
||||
DEFINE_VALUE("CONVERT_EXPRESSION(value)", "ivec4(int2_to_bool(value.xy))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Float2 to other.
|
||||
*/
|
||||
@@ -204,6 +225,13 @@ DEFINE_VALUE("CONVERT_EXPRESSION(value)", "vec4(float2_to_float4(value.xy))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_float2_to_bool)
|
||||
ADDITIONAL_INFO(compositor_convert_float_shared)
|
||||
IMAGE(0, GPU_R8I, WRITE, INT_2D, output_img)
|
||||
DEFINE_VALUE("CONVERT_EXPRESSION(value)", "ivec4(float2_to_bool(value.xy))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Float3 to other.
|
||||
*/
|
||||
@@ -250,6 +278,13 @@ DEFINE_VALUE("CONVERT_EXPRESSION(value)", "vec4(float3_to_float4(value.xyz))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_float3_to_bool)
|
||||
ADDITIONAL_INFO(compositor_convert_float_shared)
|
||||
IMAGE(0, GPU_R8I, WRITE, INT_2D, output_img)
|
||||
DEFINE_VALUE("CONVERT_EXPRESSION(value)", "ivec4(float3_to_bool(value.xyz))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Color to other.
|
||||
*/
|
||||
@@ -300,6 +335,14 @@ DEFINE_VALUE("CONVERT_EXPRESSION(value)", "vec4(color_to_float4(value))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_color_to_bool)
|
||||
ADDITIONAL_INFO(compositor_convert_float_shared)
|
||||
PUSH_CONSTANT(VEC3, luminance_coefficients_u)
|
||||
IMAGE(0, GPU_R8I, WRITE, INT_2D, output_img)
|
||||
DEFINE_VALUE("CONVERT_EXPRESSION(value)", "ivec4(color_to_bool(value, luminance_coefficients_u))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Float4 to other.
|
||||
*/
|
||||
@@ -346,6 +389,66 @@ DEFINE_VALUE("CONVERT_EXPRESSION(value)", "vec4(float4_to_color(value))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_float4_to_bool)
|
||||
ADDITIONAL_INFO(compositor_convert_float_shared)
|
||||
IMAGE(0, GPU_R8I, WRITE, INT_2D, output_img)
|
||||
DEFINE_VALUE("CONVERT_EXPRESSION(value)", "ivec4(float4_to_bool(value))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Bool to other.
|
||||
*/
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_bool_to_float)
|
||||
ADDITIONAL_INFO(compositor_convert_int_shared)
|
||||
IMAGE(0, GPU_R16F, WRITE, FLOAT_2D, output_img)
|
||||
DEFINE_VALUE("CONVERT_EXPRESSION(value)", "vec4(bool_to_float(bool(value.x)), vec3(0.0))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_bool_to_int)
|
||||
ADDITIONAL_INFO(compositor_convert_int_shared)
|
||||
IMAGE(0, GPU_R16I, WRITE, INT_2D, output_img)
|
||||
DEFINE_VALUE("CONVERT_EXPRESSION(value)", "ivec4(bool_to_int(bool(value.x)), ivec3(0))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_bool_to_int2)
|
||||
ADDITIONAL_INFO(compositor_convert_int_shared)
|
||||
IMAGE(0, GPU_RG16I, WRITE, INT_2D, output_img)
|
||||
DEFINE_VALUE("CONVERT_EXPRESSION(value)", "ivec4(bool_to_int2(bool(value.x)), ivec2(0))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_bool_to_float2)
|
||||
ADDITIONAL_INFO(compositor_convert_int_shared)
|
||||
IMAGE(0, GPU_RG16F, WRITE, FLOAT_2D, output_img)
|
||||
DEFINE_VALUE("CONVERT_EXPRESSION(value)", "vec4(bool_to_float2(bool(value.x)), vec2(0.0))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_bool_to_float3)
|
||||
ADDITIONAL_INFO(compositor_convert_int_shared)
|
||||
IMAGE(0, GPU_RGBA16F, WRITE, FLOAT_2D, output_img)
|
||||
DEFINE_VALUE("CONVERT_EXPRESSION(value)", "vec4(bool_to_float3(bool(value.x)), 0.0)")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_bool_to_color)
|
||||
ADDITIONAL_INFO(compositor_convert_int_shared)
|
||||
IMAGE(0, GPU_RGBA16F, WRITE, FLOAT_2D, output_img)
|
||||
DEFINE_VALUE("CONVERT_EXPRESSION(value)", "vec4(bool_to_color(bool(value.x)))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_bool_to_float4)
|
||||
ADDITIONAL_INFO(compositor_convert_int_shared)
|
||||
IMAGE(0, GPU_RGBA16F, WRITE, FLOAT_2D, output_img)
|
||||
DEFINE_VALUE("CONVERT_EXPRESSION(value)", "vec4(bool_to_float4(bool(value.x)))")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Color to channel.
|
||||
*/
|
||||
|
||||
@@ -55,3 +55,10 @@ void node_compositor_store_output_int2(const float id, vec3 value, out vec3 out_
|
||||
store_int2(floatBitsToUint(id), value);
|
||||
out_value = value;
|
||||
}
|
||||
|
||||
/* GPUMaterial doesn't support bool, so it is passed as a float. */
|
||||
void node_compositor_store_output_bool(const float id, float value, out float out_value)
|
||||
{
|
||||
store_bool(floatBitsToUint(id), value);
|
||||
out_value = value;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,11 @@ vec4 float_to_float4(float value)
|
||||
return vec4(value);
|
||||
}
|
||||
|
||||
bool float_to_bool(float value)
|
||||
{
|
||||
return value > 0.0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Int to other.
|
||||
*/
|
||||
@@ -70,6 +75,11 @@ vec4 int_to_float4(int value)
|
||||
return float_to_float4(int_to_float(value));
|
||||
}
|
||||
|
||||
bool int_to_bool(int value)
|
||||
{
|
||||
return value > 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Float2 to other.
|
||||
*/
|
||||
@@ -104,6 +114,11 @@ vec4 float2_to_float4(vec2 value)
|
||||
return vec4(value, 0.0, 0.0);
|
||||
}
|
||||
|
||||
bool float2_to_bool(vec2 value)
|
||||
{
|
||||
return !all(equal(value, vec2(0.0)));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Float3 to other.
|
||||
*/
|
||||
@@ -138,6 +153,11 @@ vec4 float3_to_float4(vec3 value)
|
||||
return vec4(value, 0.0);
|
||||
}
|
||||
|
||||
bool float3_to_bool(vec3 value)
|
||||
{
|
||||
return !all(equal(value, vec3(0.0)));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Color to other.
|
||||
*/
|
||||
@@ -172,6 +192,11 @@ vec4 color_to_float4(vec4 value)
|
||||
return value;
|
||||
}
|
||||
|
||||
bool color_to_bool(vec4 value, vec3 luminance_coefficients)
|
||||
{
|
||||
return color_to_float(value, luminance_coefficients) > 0.0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Float4 to other.
|
||||
*/
|
||||
@@ -206,6 +231,11 @@ vec4 float4_to_color(vec4 value)
|
||||
return value;
|
||||
}
|
||||
|
||||
bool float4_to_bool(vec4 value)
|
||||
{
|
||||
return !all(equal(value, vec4(0.0)));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Int2 to other.
|
||||
*/
|
||||
@@ -240,6 +270,50 @@ vec4 int2_to_float4(ivec2 value)
|
||||
return vec4(vec2(value), 0.0, 0.0);
|
||||
}
|
||||
|
||||
bool int2_to_bool(ivec2 value)
|
||||
{
|
||||
return !all(equal(value, ivec2(0)));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Bool to other.
|
||||
*/
|
||||
|
||||
float bool_to_float(bool value)
|
||||
{
|
||||
return float(value);
|
||||
}
|
||||
|
||||
int bool_to_int(bool value)
|
||||
{
|
||||
return int(value);
|
||||
}
|
||||
|
||||
vec2 bool_to_float2(bool value)
|
||||
{
|
||||
return vec2(value);
|
||||
}
|
||||
|
||||
vec3 bool_to_float3(bool value)
|
||||
{
|
||||
return vec3(value);
|
||||
}
|
||||
|
||||
vec4 bool_to_color(bool value)
|
||||
{
|
||||
return vec4(value);
|
||||
}
|
||||
|
||||
vec4 bool_to_float4(bool value)
|
||||
{
|
||||
return vec4(value);
|
||||
}
|
||||
|
||||
ivec2 bool_to_int2(bool value)
|
||||
{
|
||||
return ivec2(value);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* GPUMatrial-specific implicit conversion functions.
|
||||
*
|
||||
|
||||
@@ -138,7 +138,7 @@ static bool composite_node_tree_socket_type_valid(blender::bke::bNodeTreeType *
|
||||
blender::bke::bNodeSocketType *socket_type)
|
||||
{
|
||||
return blender::bke::node_is_static_socket_type(*socket_type) &&
|
||||
ELEM(socket_type->type, SOCK_FLOAT, SOCK_INT, SOCK_VECTOR, SOCK_RGBA);
|
||||
ELEM(socket_type->type, SOCK_FLOAT, SOCK_INT, SOCK_BOOLEAN, SOCK_VECTOR, SOCK_RGBA);
|
||||
}
|
||||
|
||||
static bool composite_validate_link(eNodeSocketDatatype /*from*/, eNodeSocketDatatype /*to*/)
|
||||
|
||||
@@ -703,6 +703,8 @@ class FileOutputOperation : public NodeOperation {
|
||||
break;
|
||||
case ResultType::Int:
|
||||
file_output.add_pass(pass_name, view_name, "V", buffer);
|
||||
case ResultType::Bool:
|
||||
file_output.add_pass(pass_name, view_name, "V", buffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -737,6 +739,11 @@ class FileOutputOperation : public NodeOperation {
|
||||
CPPType::get<float2>().fill_assign_n(&value, buffer, length);
|
||||
return buffer;
|
||||
}
|
||||
case ResultType::Bool: {
|
||||
const float value = float(result.get_single_value<bool>());
|
||||
CPPType::get<float>().fill_assign_n(&value, buffer, length);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
BLI_assert_unreachable();
|
||||
@@ -782,6 +789,7 @@ class FileOutputOperation : public NodeOperation {
|
||||
case ResultType::Float2:
|
||||
case ResultType::Int2:
|
||||
case ResultType::Int:
|
||||
case ResultType::Bool:
|
||||
/* Not supported. */
|
||||
BLI_assert_unreachable();
|
||||
break;
|
||||
|
||||
@@ -797,6 +797,7 @@ class RenderLayerOperation : public NodeOperation {
|
||||
case ResultType::Int:
|
||||
case ResultType::Int2:
|
||||
case ResultType::Float2:
|
||||
case ResultType::Bool:
|
||||
/* Not supported. */
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -440,7 +440,7 @@ class CompositorNodeGroupInterfaceTest(AbstractNodeGroupInterfaceTest, NodeGroup
|
||||
self.do_test_sockets_in_out("NodeSocketFloat")
|
||||
|
||||
def test_all_socket_types(self):
|
||||
self.do_test_invalid_socket_type("NodeSocketBool")
|
||||
self.do_test_socket_type("NodeSocketBool")
|
||||
self.do_test_invalid_socket_type("NodeSocketCollection")
|
||||
self.do_test_socket_type("NodeSocketColor")
|
||||
self.do_test_socket_type("NodeSocketFloat")
|
||||
|
||||
Reference in New Issue
Block a user