34 morph_type_ = morph_type;
37 std::optional<Entity> DirectionalMorphologyFilterContents::RenderFilter(
41 const Matrix& effect_transform,
43 const std::optional<Rect>& coverage_hint)
const {
55 auto input_snapshot = inputs[0]->GetSnapshot(
"Morphology", renderer, entity);
56 if (!input_snapshot.has_value()) {
65 auto maybe_input_uvs = input_snapshot->GetCoverageUVs(coverage);
66 if (!maybe_input_uvs.has_value()) {
69 auto input_uvs = maybe_input_uvs.value();
77 auto& host_buffer = pass.GetTransientsBuffer();
79 VertexBufferBuilder<VS::PerVertexData> vtx_builder;
80 vtx_builder.AddVertices({
81 {
Point(0, 0), input_uvs[0]},
82 {
Point(1, 0), input_uvs[1]},
83 {
Point(1, 1), input_uvs[3]},
84 {
Point(0, 0), input_uvs[0]},
85 {
Point(1, 1), input_uvs[3]},
86 {
Point(0, 1), input_uvs[2]},
89 auto vtx_buffer = vtx_builder.CreateVertexBuffer(host_buffer);
91 VS::FrameInfo frame_info;
93 frame_info.texture_sampler_y_coord_scale =
94 input_snapshot->texture->GetYCoordScale();
97 auto transformed_radius =
99 auto transformed_texture_vertices =
100 Rect(
Size(input_snapshot->texture->GetSize()))
102 auto transformed_texture_width =
103 transformed_texture_vertices[0].GetDistance(
104 transformed_texture_vertices[1]);
105 auto transformed_texture_height =
106 transformed_texture_vertices[0].GetDistance(
107 transformed_texture_vertices[2]);
109 FS::FragInfo frag_info;
110 frag_info.radius = std::round(transformed_radius.GetLength());
111 frag_info.morph_type =
static_cast<Scalar>(morph_type_);
112 frag_info.uv_offset =
113 input_snapshot->transform.Invert()
114 .TransformDirection(transformed_radius)
116 Point(transformed_texture_width, transformed_texture_height);
122 cmd.pipeline = renderer.GetMorphologyFilterPipeline(options);
123 cmd.BindVertices(vtx_buffer);
125 auto sampler_descriptor = input_snapshot->sampler_descriptor;
126 if (renderer.GetDeviceCapabilities().SupportsDecalSamplerAddressMode()) {
131 FS::BindTextureSampler(
132 cmd, input_snapshot->texture,
133 renderer.GetContext()->GetSamplerLibrary()->GetSampler(
134 sampler_descriptor));
135 VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info));
136 FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info));
138 return pass.AddCommand(std::move(cmd));
141 auto out_texture = renderer.MakeSubpass(
"Directional Morphology Filter",
147 SamplerDescriptor sampler_desc;
152 Snapshot{.texture = out_texture,
154 .sampler_descriptor = sampler_desc,
155 .opacity = input_snapshot->opacity},
162 const Matrix& effect_transform)
const {
163 if (inputs.empty()) {
167 auto coverage = inputs[0]->GetCoverage(entity);
168 if (!coverage.has_value()) {
171 auto transform = inputs[0]->GetTransform(entity) * effect_transform.
Basis();
172 auto transformed_vector =
175 auto origin = coverage->
origin;
177 switch (morph_type_) {
179 origin -= transformed_vector;
180 size += transformed_vector * 2;
183 origin += transformed_vector;
184 size -= transformed_vector * 2;
187 if (size.x < 0 || size.y < 0) {
190 return Rect(origin,
Size(size.x, size.y));