66 if (context.use_gpu()) {
67 this->compute_gpu(context, sides, rotation, roundness, catadioptric, lens_shift);
70 this->compute_cpu(sides, rotation, roundness, catadioptric, lens_shift);
92 return angle - offset;
95void BokehKernel::compute_gpu(Context &context,
98 const float roundness,
99 const float catadioptric,
100 const float lens_shift)
102 gpu::Shader *shader = context.get_shader(
"compositor_bokeh_image");
111 this->
result.bind_as_image(shader,
"output_img");
115 this->
result.unbind_as_image();
124 const float exterior_angle,
125 const float rotation)
127 float angle = exterior_angle * vertex_index - rotation;
137 float2 line_vector = line_end - line_start;
138 float2 point_vector = point - line_start;
139 float line_length_squared =
math::dot(line_vector, line_vector);
140 float parameter =
math::dot(point_vector, line_vector) / line_length_squared;
141 return line_start + line_vector * parameter;
159 const float circumradius,
160 const float exterior_angle,
161 const float rotation,
162 const float roundness,
163 const float catadioptric)
165 if (circumradius == 0.0f) {
174 int vertex_index = int(
angle / exterior_angle);
179 vertex_index, exterior_angle, rotation) *
182 vertex_index + 1, exterior_angle, rotation) *
189 float distance_to_edge_round =
math::interpolate(distance_to_edge, circumradius, roundness);
193 if (
distance > distance_to_edge_round) {
198 float catadioptric_distance = distance_to_edge_round * catadioptric;
199 if (
distance < catadioptric_distance) {
205 if (distance_to_edge_round -
distance < 1.0f) {
206 return distance_to_edge_round -
distance;
211 if (catadioptric != 0.0f &&
distance - catadioptric_distance < 1.0f) {
212 return distance - catadioptric_distance;
221 const float exterior_angle,
222 const float rotation,
223 const float roundness,
224 const float catadioptric,
225 const float lens_shift)
229 float circumradius =
float(
size.x) / 2.0f;
238 float min_shift =
math::abs(lens_shift * circumradius);
240 point, circumradius - min_shift, exterior_angle, rotation, roundness, catadioptric);
242 float median_shift = min_shift / 2.0f;
243 float median =
bokeh(
244 point, circumradius - median_shift, exterior_angle, rotation, roundness, catadioptric);
246 float max =
bokeh(point, circumradius, exterior_angle, rotation, roundness, catadioptric);
252 if (lens_shift < 0.0f) {
259void BokehKernel::compute_cpu(
const int sides,
260 const float rotation,
261 const float roundness,
262 const float catadioptric,
263 const float lens_shift)
271 texel,
size, exterior_angle, corrected_rotation, roundness, catadioptric, lens_shift);
272 this->
result.store_pixel(texel, bokeh_value);
283 map_.remove_if([](
auto item) {
return !item.value->needed; });
287 for (
auto &value : map_.values()) {
288 value->needed =
false;
302 auto &bokeh_kernel = *map_.lookup_or_add_cb(key, [&]() {
303 return std::make_unique<BokehKernel>(
304 context,
size, sides, rotation, roundness, catadioptric, lens_shift);
307 bokeh_kernel.needed =
true;
308 return bokeh_kernel.result;
void GPU_shader_uniform_1f(blender::gpu::Shader *sh, const char *name, float value)
void GPU_shader_bind(blender::gpu::Shader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
unsigned long long int uint64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Result & get(Context &context, int2 size, int sides, float rotation, float roundness, float catadioptric, float lens_shift)
BokehKernelKey(int2 size, int sides, float rotation, float roundness, float catadioptric, float lens_shift)
BokehKernel(Context &context, int2 size, int sides, float rotation, float roundness, float catadioptric, float lens_shift)
float distance(VecOp< float, D >, VecOp< float, D >) RET
void compute_dispatch_threads_at_least(gpu::Shader *shader, int2 threads_range, int2 local_size=int2(16))
static float4 spectral_bokeh(const int2 texel, const int2 size, const float exterior_angle, const float rotation, const float roundness, const float catadioptric, const float lens_shift)
bool operator==(const BokehKernelKey &a, const BokehKernelKey &b)
static float compute_exterior_angle(int sides)
static float2 get_regular_polygon_vertex_position(const int vertex_index, const float exterior_angle, const float rotation)
static float compute_rotation(float angle, int sides)
static float2 closest_point_on_line(const float2 point, const float2 line_start, const float2 line_end)
static float bokeh(const float2 point, const float circumradius, const float exterior_angle, const float rotation, const float roundness, const float catadioptric)
void parallel_for(const int2 range, const Function &function)
T cos(const AngleRadianBase< T > &a)
T length(const VecBase< T, Size > &a)
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
T interpolate(const T &a, const T &b, const FactorT &t)
T atan2(const T &y, const T &x)
T mod_periodic(const T &a, const T &b)
T sin(const AngleRadianBase< T > &a)
VecBase< float, 4 > float4
uint64_t get_default_hash(const T &v, const Args &...args)
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2