Commit: a7195ad45058a0536c4a3f2f8af4d100cf248b34 Author: Omar Emara Date: Fri Mar 4 21:55:27 2022 +0200 Branches: temp-viewport-compositor-compiler https://developer.blender.org/rBa7195ad45058a0536c4a3f2f8af4d100cf248b34
Viewport Compositor: Add support for domains This patch supports compositing of arbitrary image sizes, supports transformation operations, and supports infinit canvase compositing. =================================================================== A source/blender/blenlib/BLI_transformation_2d.hh M source/blender/blenlib/CMakeLists.txt M source/blender/gpu/CMakeLists.txt M source/blender/gpu/GPU_shader.h M source/blender/gpu/intern/gpu_shader.cc A source/blender/gpu/shaders/compositor/compositor_realize_on_domain.glsl A source/blender/gpu/shaders/compositor/infos/compositor_realize_on_domain_info.hh M source/blender/nodes/NOD_compositor_execute.hh M source/blender/nodes/NOD_node_declaration.hh M source/blender/nodes/composite/nodes/node_composite_composite.cc M source/blender/nodes/composite/nodes/node_composite_transform.cc M source/blender/nodes/intern/node_compositor_execute.cc =================================================================== diff --git a/source/blender/blenlib/BLI_transformation_2d.hh b/source/blender/blenlib/BLI_transformation_2d.hh new file mode 100644 index 00000000000..28127432888 --- /dev/null +++ b/source/blender/blenlib/BLI_transformation_2d.hh @@ -0,0 +1,175 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include <cmath> +#include <cstdint> + +#include "BLI_assert.h" +#include "BLI_math_base.h" +#include "BLI_math_matrix.h" +#include "BLI_math_vec_types.hh" + +namespace blender { + +/* A 2D affine transformation stored in a transformation matrix in homogeneous coordinates form. + * The stores matrix is stored column major order. */ +struct Transformation2D { + private: + float matrix_[3][3]; + + public: + static Transformation2D zero() + { + Transformation2D result; + result.matrix_[0][0] = 0.0f; + result.matrix_[0][1] = 0.0f; + result.matrix_[0][2] = 0.0f; + result.matrix_[1][0] = 0.0f; + result.matrix_[1][1] = 0.0f; + result.matrix_[1][2] = 0.0f; + result.matrix_[2][0] = 0.0f; + result.matrix_[2][1] = 0.0f; + result.matrix_[2][2] = 0.0f; + return result; + } + + static Transformation2D identity() + { + Transformation2D result = zero(); + result.matrix_[0][0] = 1.0f; + result.matrix_[1][1] = 1.0f; + result.matrix_[2][2] = 1.0f; + return result; + } + + static Transformation2D from_translation(const float2 translation) + { + Transformation2D result = identity(); + result.matrix_[2][0] = translation.x; + result.matrix_[2][1] = translation.y; + return result; + } + + static Transformation2D from_rotation(float rotation) + { + Transformation2D result = zero(); + const float cosine = std::cos(rotation); + const float sine = std::sin(rotation); + result.matrix_[0][0] = cosine; + result.matrix_[0][1] = sine; + result.matrix_[1][0] = -sine; + result.matrix_[1][1] = cosine; + result.matrix_[2][2] = 1.0f; + return result; + } + + static Transformation2D from_translation_rotation_scale(const float2 translation, + float rotation, + const float2 scale) + { + Transformation2D result; + const float cosine = std::cos(rotation); + const float sine = std::sin(rotation); + result.matrix_[0][0] = scale.x * cosine; + result.matrix_[0][1] = scale.y * sine; + result.matrix_[0][2] = 0.0f; + result.matrix_[1][0] = scale.x * -sine; + result.matrix_[1][1] = scale.y * cosine; + result.matrix_[1][2] = 0.0f; + result.matrix_[2][0] = translation.x; + result.matrix_[2][1] = translation.y; + result.matrix_[2][2] = 1.0f; + return result; + } + + static Transformation2D from_normalized_axes(const float2 translation, + const float2 horizontal, + const float2 vertical) + { + BLI_ASSERT_UNIT_V2(horizontal); + BLI_ASSERT_UNIT_V2(vertical); + + Transformation2D result; + result.matrix_[0][0] = horizontal.x; + result.matrix_[0][1] = horizontal.y; + result.matrix_[0][2] = 0.0f; + result.matrix_[1][0] = vertical.x; + result.matrix_[1][1] = vertical.y; + result.matrix_[1][2] = 0.0f; + result.matrix_[2][0] = translation.x; + result.matrix_[2][1] = translation.y; + result.matrix_[2][2] = 1.0f; + return result; + } + + friend Transformation2D operator*(const Transformation2D &a, const Transformation2D &b) + { + Transformation2D result; + mul_m3_m3m3(result.matrix_, a.matrix_, b.matrix_); + return result; + } + + void operator*=(const Transformation2D &other) + { + mul_m3_m3_post(matrix_, other.matrix_); + } + + friend float2 operator*(const Transformation2D &transformation, const float2 &vector) + { + float2 result; + mul_v2_m3v2(result, transformation.matrix_, vector); + return result; + } + + friend float2 operator*(const Transformation2D &transformation, const float (*vector)[2]) + { + return transformation * float2(vector); + } + + Transformation2D transposed() const + { + Transformation2D result; + transpose_m3_m3(result.matrix_, matrix_); + return result; + } + + Transformation2D inverted() const + { + Transformation2D result; + invert_m3_m3(result.matrix_, matrix_); + return result; + } + + Transformation2D set_pivot(float2 pivot) const + { + return from_translation(pivot) * *this * from_translation(-pivot); + } + + using matrix_array = float[3][3]; + const matrix_array &matrix() const + { + return matrix_; + } + + friend bool operator==(const Transformation2D &a, const Transformation2D &b) + { + return equals_m3m3(a.matrix_, b.matrix_); + } +}; + +} // namespace blender diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 31e550379f1..2f4ba846cd2 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -303,6 +303,7 @@ set(SRC BLI_threads.h BLI_timecode.h BLI_timeit.hh + BLI_transformation_2d.hh BLI_timer.h BLI_user_counter.hh BLI_utildefines.h diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 69013660f23..924cf5a1c8f 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -313,6 +313,7 @@ set(GLSL_SRC shaders/compositor/compositor_convert_vector_to_color.glsl shaders/compositor/compositor_image.glsl shaders/compositor/compositor_image_alpha.glsl + shaders/compositor/compositor_realize_on_domain.glsl shaders/material/gpu_shader_material_add_shader.glsl shaders/material/gpu_shader_material_ambient_occlusion.glsl @@ -499,6 +500,7 @@ set(SHADER_CREATE_INFOS shaders/compositor/infos/compositor_convert_vector_to_color_info.hh shaders/compositor/infos/compositor_image_info.hh shaders/compositor/infos/compositor_image_alpha_info.hh + shaders/compositor/infos/compositor_realize_on_domain_info.hh ) set(SHADER_CREATE_INFOS_CONTENT "") diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 846bda07127..0b5f5fd8242 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -200,6 +200,7 @@ void GPU_shader_uniform_4f(GPUShader *sh, const char *name, float x, float y, fl void GPU_shader_uniform_2fv(GPUShader *sh, const char *name, const float data[2]); void GPU_shader_uniform_3fv(GPUShader *sh, const char *name, const float data[3]); void GPU_shader_uniform_4fv(GPUShader *sh, const char *name, const float data[4]); +void GPU_shader_uniform_mat3(GPUShader *sh, const char *name, const float data[3][3]); void GPU_shader_uniform_mat4(GPUShader *sh, const char *name, const float data[4][4]); void GPU_shader_uniform_2fv_array(GPUShader *sh, const char *name, int len, const float (*val)[2]); void GPU_shader_uniform_4fv_array(GPUShader *sh, const char *name, int len, const float (*val)[4]); diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc index b670b240a03..645c17a3b27 100644 --- a/source/blender/gpu/intern/gpu_shader.cc +++ b/source/blender/gpu/intern/gpu_shader.cc @@ -716,6 +716,12 @@ void GPU_shader_uniform_4fv(GPUShader *sh, const char *name, const float data[4] GPU_shader_uniform_vector(sh, loc, 4, 1, data); } +void GPU_shader_uniform_mat3(GPUShader *sh, const char *name, const float data[3][3]) +{ + const int loc = GPU_shader_get_uniform(sh, name); + GPU_shader_uniform_vector(sh, loc, 9, 1, (const float *)data); +} + void GPU_shader_uniform_mat4(GPUShader *sh, const char *name, const float data[4][4]) { const int loc = GPU_shader_get_uniform(sh, name); diff --git a/source/blender/gpu/shaders/compositor/compositor_realize_on_domain.glsl b/source/blender/gpu/shaders/compositor/compositor_realize_on_domain.glsl new file mode 100644 index 00000000000..89edd87f5fa --- /dev/null +++ b/source/blender/gpu/shaders/compositor/compositor_realize_on_domain.glsl @@ -0,0 +1,23 @@ +void main() +{ + ivec2 xy = ivec2(gl_GlobalInvocationID.xy); + + /* First, transform the input image by transforming the domain coordinates with the inverse of + * input image's transformation. The inverse transformation is an affine matrix and thus the + * coordinates should be in homogeneous coordinates. */ + vec2 coordinates = (inverse_transformation * vec3(xy, 1.0)).xy; + + /* Since an input image with an identity transformation is supposed to be centered in the domain, + * we subtract the offset between the lower left corners of the input image and the domain, which + * is half the difference between their sizes, because the difference in size is on both sides of + * the centered image. */ + ivec2 domain_size = imageSize(domain); + ivec2 input_size = textureSize(input_sampler, 0); + vec2 offset = (domain_size - input_size) / 2.0; + + /* Subtract the offset and divide by the input image size to get the relevant coordinates into + * the sampler's expected [0, 1] range. */ + vec2 normalized_coordinates = (coordinates - offset) / input_size; + + imageStore(domain, xy, texture(input_sampler, normalized_coordinates)); +} diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_realize_on_domain_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_realize_on_domain_info.hh new file mode 100644 index 00000000000..4701d0bc2f6 --- /dev/null +++ b/source/blender/gpu/shaders/compositor/infos/compositor_realize_on_domain_in @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs