34 b.use_custom_socket_order();
35 b.allow_any_socket_order();
38 .default_value({1.0f, 1.0f, 1.0f, 1.0f})
41 .structure_type(StructureType::Dynamic);
42 b.add_output<
decl::Color>(
"Image").structure_type(StructureType::Dynamic).align_with_previous();
45 .default_value({1.0f, 0.0f, 0.0f})
49 "The UV coordinates at which to sample the texture. The Z component is assumed to "
50 "contain an alpha channel")
51 .structure_type(StructureType::Dynamic);
58 .description(
"Interpolation method");
63 .description(
"The extension mode applied to the X axis");
68 .description(
"The extension mode applied to the Y axis");
98 if (this->
context().use_gpu()) {
118 const bool use_bilinear =
ELEM(
148 switch (interpolation) {
150 return "compositor_map_uv_anisotropic";
152 return "compositor_map_uv_bicubic";
155 return "compositor_map_uv";
158 return "compositor_map_uv";
199 output.allocate_single_value();
215 float2 uv_coordinates = input_uv.load_pixel<float3>(texel).xy();
216 float4 sampled_color = input_image.sample(
217 uv_coordinates, interpolation, extension_mode_x, extension_mode_y);
224 float alpha = input_uv.load_pixel<float3>(texel).z;
226 float4 result = sampled_color * alpha;
228 output_image.store_pixel(texel, result);
250 const int x = base_texel.x * 2;
251 const int y = base_texel.y * 2;
254 const int2 lower_right_texel =
int2(
x + 1,
y);
256 const int2 upper_right_texel =
int2(
x + 1,
y + 1);
265 const float2 lower_x_gradient = (lower_right_uv - lower_left_uv) / uv_size.x;
266 const float2 left_y_gradient = (upper_left_uv - lower_left_uv) / uv_size.y;
267 const float2 right_y_gradient = (upper_right_uv - lower_right_uv) / uv_size.y;
268 const float2 upper_x_gradient = (upper_right_uv - upper_left_uv) / uv_size.x;
271 auto compute_pixel = [&](
const int2 &texel,
272 const float2 &coordinates,
274 const float2 &y_gradient) {
294 compute_pixel(lower_left_texel, lower_left_uv, lower_x_gradient, left_y_gradient);
295 if (lower_right_texel.x !=
size.x) {
296 compute_pixel(lower_right_texel, lower_right_uv, lower_x_gradient, right_y_gradient);
298 if (upper_left_texel.y !=
size.y) {
299 compute_pixel(upper_left_texel, upper_left_uv, upper_x_gradient, left_y_gradient);
301 if (upper_right_texel.x !=
size.x && upper_right_texel.y !=
size.y) {
302 compute_pixel(upper_right_texel, upper_right_uv, upper_x_gradient, right_y_gradient);
311 const MenuValue menu_value =
input.get_single_value_default(default_menu_value);
313 switch (interpolation) {
331 const MenuValue menu_value =
input.get_single_value_default(default_menu_value);
333 switch (extension_x) {
349 const MenuValue menu_value =
input.get_single_value_default(default_menu_value);
351 switch (extension_y) {
380 "Map a texture using UV coordinates, to apply a texture to objects in compositing";
383 ntype.
declare = file_ns::cmp_node_map_uv_declare;
385 ntype.
initfunc = file_ns::node_composit_init_map_uv;
#define NODE_CLASS_DISTORT
@ CMP_NODE_INTERPOLATION_NEAREST
@ CMP_NODE_INTERPOLATION_BILINEAR
@ CMP_NODE_INTERPOLATION_BICUBIC
@ CMP_NODE_INTERPOLATION_ANISOTROPIC
@ CMP_NODE_EXTENSION_MODE_EXTEND
@ CMP_NODE_EXTENSION_MODE_CLIP
@ CMP_NODE_EXTENSION_MODE_REPEAT
void GPU_shader_bind(blender::gpu::Shader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
void GPU_texture_extend_mode_y(blender::gpu::Texture *texture, GPUSamplerExtendMode extend_mode)
void GPU_texture_extend_mode_x(blender::gpu::Texture *texture, GPUSamplerExtendMode extend_mode)
void GPU_texture_anisotropic_filter(blender::gpu::Texture *texture, bool use_aniso)
void GPU_texture_mipmap_mode(blender::gpu::Texture *texture, bool use_mipmap, bool use_filter)
void GPU_texture_filter_mode(blender::gpu::Texture *texture, bool use_filter)
Read Guarded memory(de)allocation.
#define NOD_REGISTER_NODE(REGISTER_FUNC)
BMesh const char void * data
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
gpu::Shader * get_shader(const char *info_name, ResultPrecision precision)
NodeOperation(Context &context, DNode node)
Result & get_result(StringRef identifier)
Context & context() const
Result & get_input(StringRef identifier) const
virtual Domain compute_domain()
void share_data(const Result &source)
void store_pixel(const int2 &texel, const T &pixel_value)
void allocate_texture(const Domain domain, const bool from_pool=true, const std::optional< ResultStorageType > storage_type=std::nullopt)
void unbind_as_texture() const
void bind_as_texture(gpu::Shader *shader, const char *texture_name) const
T load_pixel_extended(const int2 &texel) const
const Domain & domain() const
T load_pixel(const int2 &texel) const
void unbind_as_image() const
float4 sample_ewa_zero(const float2 &coordinates, const float2 &x_gradient, const float2 &y_gradient) const
void bind_as_image(gpu::Shader *shader, const char *image_name, bool read=false) const
bool is_single_value() const
const T & get_single_value() const
DeclType::Builder & add_input(StringRef name, StringRef identifier="")
const CompositorInputRealizationMode & compositor_realization_mode() const
void execute_cpu_anisotropic()
void execute_cpu_interpolation(const Interpolation &interpolation)
ExtensionMode get_extension_mode_y()
ExtensionMode get_extension_mode_x()
Interpolation get_interpolation()
char const * get_shader_name(const Interpolation &interpolation)
NodeOperation(Context &context, DNode node)
void * MEM_callocN(size_t len, const char *str)
void node_register_type(bNodeType &ntype)
void node_type_storage(bNodeType &ntype, std::optional< StringRefNull > storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
float4 sample_pixel(Context &context, const Result &input, const Interpolation &interpolation, const ExtensionMode &extension_mode_x, const ExtensionMode &extension_mode_y, const float2 coordinates)
void compute_dispatch_threads_at_least(gpu::Shader *shader, int2 threads_range, int2 local_size=int2(16))
GPUSamplerExtendMode map_extension_mode_to_extend_mode(const ExtensionMode &mode)
void parallel_for(const int2 range, const Function &function)
VecBase< T, Size > divide_ceil(const VecBase< T, Size > &a, const VecBase< T, Size > &b)
static void node_composit_init_map_uv(bNodeTree *, bNode *node)
static void cmp_node_map_uv_declare(NodeDeclarationBuilder &b)
static NodeOperation * get_compositor_operation(Context &context, DNode node)
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
VecBase< float, 3 > float3
static void register_node_type_cmp_mapuv()
void cmp_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
void node_free_standard_storage(bNode *node)
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
const EnumPropertyItem rna_enum_node_compositor_extension_items[]
const EnumPropertyItem rna_enum_node_compositor_interpolation_items[]
std::string ui_description
NodeGetCompositorOperationFunction get_compositor_operation
void(* initfunc)(bNodeTree *ntree, bNode *node)
const char * enum_name_legacy
NodeDeclareFunction declare