Blender V4.3
COM_GlareGhostOperation.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
7
8namespace blender::compositor {
9
10static float smooth_mask(float x, float y)
11{
12 float t;
13 x = 2.0f * x - 1.0f;
14 y = 2.0f * y - 1.0f;
15 if ((t = 1.0f - sqrtf(x * x + y * y)) > 0.0f) {
16 return t;
17 }
18
19 return 0.0f;
20}
21
23 MemoryBuffer *input_tile,
24 const NodeGlare *settings)
25{
26 const int qt = 1 << settings->quality;
27 const float s1 = 4.0f / float(qt), s2 = 2.0f * s1;
28 int x, y, n, p, np;
29 fRGB c, tc, cm[64];
30 float sc, isc, u, v, sm, s, t, ofs, scalef[64];
31 const float cmo = 1.0f - settings->colmod;
32
33 MemoryBuffer gbuf(*input_tile);
34 MemoryBuffer tbuf1(*input_tile);
35
36 bool breaked = false;
37
39 if (!breaked) {
41 }
42 if (is_braked()) {
43 breaked = true;
44 }
45 if (!breaked) {
47 }
48
49 MemoryBuffer tbuf2(tbuf1);
50
51 if (is_braked()) {
52 breaked = true;
53 }
54 if (!breaked) {
56 }
57 if (is_braked()) {
58 breaked = true;
59 }
60 if (!breaked) {
62 }
63 if (is_braked()) {
64 breaked = true;
65 }
66 if (!breaked) {
68 }
69
70 ofs = (settings->iter & 1) ? 0.5f : 0.0f;
71 for (x = 0; x < (settings->iter * 4); x++) {
72 y = x & 3;
73 cm[x][0] = cm[x][1] = cm[x][2] = 1;
74 if (y == 1) {
75 fRGB_rgbmult(cm[x], 1.0f, cmo, cmo);
76 }
77 if (y == 2) {
78 fRGB_rgbmult(cm[x], cmo, cmo, 1.0f);
79 }
80 if (y == 3) {
81 fRGB_rgbmult(cm[x], cmo, 1.0f, cmo);
82 }
83 scalef[x] = 2.1f * (1.0f - (x + ofs) / float(settings->iter * 4));
84 if (x & 1) {
85 scalef[x] = -0.99f / scalef[x];
86 }
87 }
88
89 sc = 2.13;
90 isc = -0.97;
91 for (y = 0; y < gbuf.get_height() && (!breaked); y++) {
92 v = (float(y) + 0.5f) / float(gbuf.get_height());
93 for (x = 0; x < gbuf.get_width(); x++) {
94 u = (float(x) + 0.5f) / float(gbuf.get_width());
95 s = (u - 0.5f) * sc + 0.5f;
96 t = (v - 0.5f) * sc + 0.5f;
97 tbuf1.read_bilinear(c, s * gbuf.get_width(), t * gbuf.get_height());
98 sm = smooth_mask(s, t);
99 mul_v3_fl(c, sm);
100 s = (u - 0.5f) * isc + 0.5f;
101 t = (v - 0.5f) * isc + 0.5f;
102 tbuf2.read_bilinear(tc, s * gbuf.get_width() - 0.5f, t * gbuf.get_height() - 0.5f);
103 sm = smooth_mask(s, t);
104 madd_v3_v3fl(c, tc, sm);
105
106 gbuf.write_pixel(x, y, c);
107 }
108 if (is_braked()) {
109 breaked = true;
110 }
111 }
112
113 memset(tbuf1.get_buffer(),
114 0,
115 tbuf1.get_width() * tbuf1.get_height() * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float));
116 for (n = 1; n < settings->iter && (!breaked); n++) {
117 for (y = 0; y < gbuf.get_height() && (!breaked); y++) {
118 v = (float(y) + 0.5f) / float(gbuf.get_height());
119 for (x = 0; x < gbuf.get_width(); x++) {
120 u = (float(x) + 0.5f) / float(gbuf.get_width());
121 tc[0] = tc[1] = tc[2] = 0.0f;
122 for (p = 0; p < 4; p++) {
123 np = (n << 2) + p;
124 s = (u - 0.5f) * scalef[np] + 0.5f;
125 t = (v - 0.5f) * scalef[np] + 0.5f;
126 gbuf.read_bilinear(c, s * gbuf.get_width() - 0.5f, t * gbuf.get_height() - 0.5f);
127 mul_v3_v3(c, cm[np]);
128 sm = smooth_mask(s, t) * 0.25f;
129 madd_v3_v3fl(tc, c, sm);
130 }
131 tbuf1.add_pixel(x, y, tc);
132 }
133 if (is_braked()) {
134 breaked = true;
135 }
136 }
137 memcpy(gbuf.get_buffer(),
138 tbuf1.get_buffer(),
139 tbuf1.get_width() * tbuf1.get_height() * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float));
140 }
141 memcpy(data,
142 gbuf.get_buffer(),
143 gbuf.get_width() * gbuf.get_height() * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float));
144}
145
146} // namespace blender::compositor
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void mul_v3_v3(float r[3], const float a[3])
MINLINE void mul_v3_fl(float r[3], float f)
#define fRGB_rgbmult(c, r, g, b)
ATTR_WARN_UNUSED_RESULT const BMVert * v
static void IIR_gauss(MemoryBuffer *src, float sigma, unsigned int channel, unsigned int xy)
void generate_glare(float *data, MemoryBuffer *input_tile, const NodeGlare *settings) override
a MemoryBuffer contains access to the data
const int get_width() const
get the width of this MemoryBuffer
const int get_height() const
get the height of this MemoryBuffer
void write_pixel(int x, int y, const float color[4])
float * get_buffer()
get the data of this MemoryBuffer
void read_bilinear(float *result, float x, float y, MemoryBufferExtend extend_x=MemoryBufferExtend::Clip, MemoryBufferExtend extend_y=MemoryBufferExtend::Clip) const
void add_pixel(int x, int y, const float color[4])
#define sqrtf(x)
draw_view in_light_buf[] float
constexpr int COM_DATA_TYPE_COLOR_CHANNELS
Definition COM_defines.h:58
static float smooth_mask(float x, float y)