Blender V4.3
smaa.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_assert.h"
6
8
9#include "GPU_shader.hh"
10#include "GPU_texture.hh"
11
12#include "COM_context.hh"
13#include "COM_result.hh"
14#include "COM_utilities.hh"
15
16#include "COM_algorithm_smaa.hh"
17
19
21
23{
24 switch (type) {
25 case ResultType::Color: {
26 float luminance_coefficients[3];
28 GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
29 return;
30 }
31 case ResultType::Vector: {
32 float luminance_coefficients[3] = {1.0f, 1.0f, 1.0f};
33 GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
34 return;
35 }
36 case ResultType::Float: {
37 float luminance_coefficients[3] = {1.0f, 0.0f, 0.0f};
38 GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
39 return;
40 }
41 case ResultType::Float2: {
42 float luminance_coefficients[3] = {1.0f, 1.0f, 0.0f};
43 GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
44 return;
45 }
47 /* GPU module does not support float3 outputs. */
48 break;
50 /* SMAA does not support integer types. */
51 break;
52 }
53
55}
56
57static Result detect_edges(Context &context,
58 Result &input,
59 float threshold,
60 float local_contrast_adaptation_factor)
61{
62 GPUShader *shader = context.get_shader("compositor_smaa_edge_detection");
63 GPU_shader_bind(shader);
64
65 set_shader_luminance_coefficients(shader, input.type());
66 GPU_shader_uniform_1f(shader, "smaa_threshold", threshold);
68 shader, "smaa_local_contrast_adaptation_factor", local_contrast_adaptation_factor);
69
70 GPU_texture_filter_mode(input, true);
71 input.bind_as_texture(shader, "input_tx");
72
73 Result edges = context.create_result(ResultType::Color);
74 edges.allocate_texture(input.domain());
75 edges.bind_as_image(shader, "edges_img");
76
77 compute_dispatch_threads_at_least(shader, input.domain().size);
78
80 input.unbind_as_texture();
81 edges.unbind_as_image();
82
83 return edges;
84}
85
86static Result calculate_blending_weights(Context &context, Result &edges, int corner_rounding)
87{
88 GPUShader *shader = context.get_shader("compositor_smaa_blending_weight_calculation");
89 GPU_shader_bind(shader);
90
91 GPU_shader_uniform_1i(shader, "smaa_corner_rounding", corner_rounding);
92
93 GPU_texture_filter_mode(edges, true);
94 edges.bind_as_texture(shader, "edges_tx");
95
96 const SMAAPrecomputedTextures &smaa_precomputed_textures =
97 context.cache_manager().smaa_precomputed_textures.get();
98 smaa_precomputed_textures.bind_area_texture(shader, "area_tx");
99 smaa_precomputed_textures.bind_search_texture(shader, "search_tx");
100
101 Result weights = context.create_result(ResultType::Color);
102 weights.allocate_texture(edges.domain());
103 weights.bind_as_image(shader, "weights_img");
104
105 compute_dispatch_threads_at_least(shader, edges.domain().size);
106
108 edges.unbind_as_texture();
109 smaa_precomputed_textures.unbind_area_texture();
110 smaa_precomputed_textures.unbind_search_texture();
111 weights.unbind_as_image();
112
113 return weights;
114}
115
116static const char *get_blend_shader_name(ResultType type)
117{
118 switch (type) {
121 return "compositor_smaa_neighborhood_blending_float4";
123 return "compositor_smaa_neighborhood_blending_float2";
125 return "compositor_smaa_neighborhood_blending_float";
127 /* GPU module does not support float3 outputs. */
128 break;
129 case ResultType::Int2:
130 /* SMAA does not support integer types. */
131 break;
132 }
133
135 return "";
136}
137
138static void blend_neighborhood(Context &context, Result &input, Result &weights, Result &output)
139{
140 GPUShader *shader = context.get_shader(get_blend_shader_name(input.type()));
141 GPU_shader_bind(shader);
142
143 GPU_texture_filter_mode(input, true);
144 input.bind_as_texture(shader, "input_tx");
145
146 GPU_texture_filter_mode(weights, true);
147 weights.bind_as_texture(shader, "weights_tx");
148
149 output.allocate_texture(input.domain());
150 output.bind_as_image(shader, "output_img");
151
152 compute_dispatch_threads_at_least(shader, input.domain().size);
153
155 input.unbind_as_texture();
156 weights.unbind_as_texture();
157 output.unbind_as_image();
158}
159
160void smaa(Context &context,
161 Result &input,
162 Result &output,
163 float threshold,
164 float local_contrast_adaptation_factor,
165 int corner_rounding)
166{
167 Result edges = detect_edges(context, input, threshold, local_contrast_adaptation_factor);
168 Result weights = calculate_blending_weights(context, edges, corner_rounding);
169 edges.release();
170 blend_neighborhood(context, input, weights, output);
171 weights.release();
172}
173
174} // namespace blender::realtime_compositor
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
void GPU_shader_uniform_1i(GPUShader *sh, const char *name, int value)
void GPU_shader_uniform_1f(GPUShader *sh, const char *name, float value)
void GPU_shader_uniform_3fv(GPUShader *sh, const char *name, const float data[3])
void GPU_shader_bind(GPUShader *shader)
void GPU_shader_unbind()
void GPU_texture_filter_mode(GPUTexture *texture, bool use_filter)
BLI_INLINE void IMB_colormanagement_get_luminance_coefficients(float r_rgb[3])
struct GPUShader GPUShader
void bind_as_image(GPUShader *shader, const char *image_name, bool read=false) const
Definition result.cc:264
void allocate_texture(Domain domain, bool from_pool=true)
Definition result.cc:204
void bind_as_texture(GPUShader *shader, const char *texture_name) const
Definition result.cc:253
void bind_search_texture(GPUShader *shader, const char *sampler_name) const
void bind_area_texture(GPUShader *shader, const char *sampler_name) const
static Result detect_edges(Context &context, Result &input, float threshold, float local_contrast_adaptation_factor)
Definition smaa.cc:57
static Result calculate_blending_weights(Context &context, Result &edges, int corner_rounding)
Definition smaa.cc:86
void smaa(Context &context, Result &input, Result &output, float threshold=0.1f, float local_contrast_adaptation_factor=2.0f, int corner_rounding=25)
Definition smaa.cc:160
static void set_shader_luminance_coefficients(GPUShader *shader, ResultType type)
Definition smaa.cc:22
static void blend_neighborhood(Context &context, Result &input, Result &weights, Result &output)
Definition smaa.cc:138
void compute_dispatch_threads_at_least(GPUShader *shader, int2 threads_range, int2 local_size=int2(16))
Definition utilities.cc:131
static const char * get_blend_shader_name(ResultType type)
Definition smaa.cc:116