diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2014-12-04 14:43:07 +0300 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2014-12-04 14:46:45 +0300 |
commit | 12e9ccb256a6afa36320b7853e9d949de1e3054b (patch) | |
tree | b486f88e8ceff8d8487ccc56b7abd6980b17ce95 /source/blender/compositor/operations/COM_SunBeamsOperation.cpp | |
parent | cf151470533466238b680de60ac04649d261fe92 (diff) |
Cleanup and fix for uninitialized output buffer of the sunbeams node.
Buffers should actually be cleared before running operations on them,
but this doesn't work for some reason.
Note also that the sunbeams node can show some creases and hard aliasing
when the source point is close to a bright area with strong gradient.
To fix this a better filtering algorithm, dithering or ray sampling
would need to be implemented. In the meantime simply blurring the
sunbeams result a bit should help (or simply avoid putting the source on
a bright spot).
Diffstat (limited to 'source/blender/compositor/operations/COM_SunBeamsOperation.cpp')
-rw-r--r-- | source/blender/compositor/operations/COM_SunBeamsOperation.cpp | 92 |
1 files changed, 55 insertions, 37 deletions
diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp index bcef652a8b5..12b04c386f2 100644 --- a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp +++ b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp @@ -50,34 +50,52 @@ void SunBeamsOperation::initExecution() * For a target point (x,y) the sector should be chosen such that * ``u >= v >= 0`` * This removes the need to handle all sorts of special cases. + * + * Template parameters: + * fxu : buffer increment in x for sector u+1 + * fxv : buffer increment in x for sector v+1 + * fyu : buffer increment in y for sector u+1 + * fyv : buffer increment in y for sector v+1 */ -template <int fxx, int fxy, int fyx, int fyy> +template <int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator { /* utility functions implementing the matrix transform to/from sector space */ - - static inline void buffer_to_sector(int x, int y, int &u, int &v) + + static inline void buffer_to_sector(const float source[2], int x, int y, int &u, int &v) { - u = x * fxx + y * fyx; - v = x * fxy + y * fyy; + int x0 = (int)source[0]; + int y0 = (int)source[1]; + x -= x0; + y -= y0; + u = x * fxu + y * fyu; + v = x * fxv + y * fyv; } - static inline void buffer_to_sector(float x, float y, float &u, float &v) + static inline void buffer_to_sector(const float source[2], float x, float y, float &u, float &v) { - u = x * fxx + y * fyx; - v = x * fxy + y * fyy; + int x0 = (int)source[0]; + int y0 = (int)source[1]; + x -= (float)x0; + y -= (float)y0; + u = x * fxu + y * fyu; + v = x * fxv + y * fyv; } - static inline void sector_to_buffer(int u, int v, int &x, int &y) + static inline void sector_to_buffer(const float source[2], int u, int v, int &x, int &y) { - x = u * fxx + v * fxy; - y = u * fyx + v * fyy; + int x0 = (int)source[0]; + int y0 = (int)source[1]; + x = x0 + u * fxu + v * fxv; + y = y0 + u * fyu + v * fyv; } - static inline void sector_to_buffer(float u, float v, float &x, float &y) + static inline void sector_to_buffer(const float source[2], float u, float v, float &x, float &y) { - x = u * fxx + v * fxy; - y = u * fyx + v * fyy; + int x0 = (int)source[0]; + int y0 = (int)source[1]; + x = (float)x0 + u * fxu + v * fxv; + y = (float)y0 + u * fyu + v * fyv; } /** @@ -91,12 +109,12 @@ struct BufferLineAccumulator { * \param num Total steps in the loop * \param v, dv Vertical offset in sector space, for line offset perpendicular to the loop axis */ - static float *init_buffer_iterator(MemoryBuffer *input, const float source[2], const float pt_ofs[2], + static float *init_buffer_iterator(MemoryBuffer *input, const float source[2], const float co[2], float dist_min, float dist_max, int &x, int &y, int &num, float &v, float &dv, float &falloff_factor) { float pu, pv; - buffer_to_sector(pt_ofs[0], pt_ofs[1], pu, pv); + buffer_to_sector(source, co[0], co[1], pu, pv); /* line angle */ float tan_phi = pv / pu; @@ -113,9 +131,7 @@ struct BufferLineAccumulator { int end = (int)ceilf(umin); num = end - start; - sector_to_buffer(end, (int)ceilf(v), x, y); - x += (int)source[0]; - y += (int)source[1]; + sector_to_buffer(source, end, (int)ceilf(v), x, y); falloff_factor = dist_max > dist_min ? dr / (float)(dist_max - dist_min) : 0.0f; @@ -130,7 +146,7 @@ struct BufferLineAccumulator { * The loop runs backwards(!) over the primary sector space axis u, i.e. increasing distance to pt. * After each step it decrements v by dv < 1, adding a buffer shift when necessary. */ - static void eval(MemoryBuffer *input, float output[4], const float pt_ofs[2], const float source[2], + static void eval(MemoryBuffer *input, float output[4], const float co[2], const float source[2], float dist_min, float dist_max) { rcti rect = *input->getRect(); @@ -139,14 +155,16 @@ struct BufferLineAccumulator { float v, dv; float falloff_factor; float border[4]; - - if ((int)pt_ofs[0] == 0 && (int)pt_ofs[1] == 0) { + + zero_v4(output); + + if ((int)(co[0] - source[0]) == 0 && (int)(co[1] - source[1]) == 0) { copy_v4_v4(output, input->getBuffer() + COM_NUMBER_OF_CHANNELS * ((int)source[0] + input->getWidth() * (int)source[1])); return; } /* initialise the iteration variables */ - float *buffer = init_buffer_iterator(input, source, pt_ofs, dist_min, dist_max, x, y, num, v, dv, falloff_factor); + float *buffer = init_buffer_iterator(input, source, co, dist_min, dist_max, x, y, num, v, dv, falloff_factor); zero_v3(border); border[3] = 1.0f; @@ -178,18 +196,18 @@ struct BufferLineAccumulator { */ /* decrement u */ - x -= fxx; - y -= fyx; - buffer -= (fxx + fyx * buffer_width) * COM_NUMBER_OF_CHANNELS; + x -= fxu; + y -= fyu; + buffer -= (fxu + fyu * buffer_width) * COM_NUMBER_OF_CHANNELS; /* decrement v (in steps of dv < 1) */ v_local -= dv; if (v_local < 0.0f) { v_local += 1.0f; - x -= fxy; - y -= fyy; - buffer -= (fxy + fyy * buffer_width) * COM_NUMBER_OF_CHANNELS; + x -= fxv; + y -= fyv; + buffer -= (fxv + fyv * buffer_width) * COM_NUMBER_OF_CHANNELS; } } @@ -233,21 +251,21 @@ static void accumulate_line(MemoryBuffer *input, float output[4], const float co if (pt_ofs[0] > 0.0f) { if (pt_ofs[1] > 0.0f) { /* 2 */ - BufferLineAccumulator<0, 1, 1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator<0, 1, 1, 0>::eval(input, output, co, source, dist_min, dist_max); } else { /* 7 */ - BufferLineAccumulator<0, 1, -1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator<0, 1, -1, 0>::eval(input, output, co, source, dist_min, dist_max); } } else { if (pt_ofs[1] > 0.0f) { /* 3 */ - BufferLineAccumulator<0, -1, 1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator<0, -1, 1, 0>::eval(input, output, co, source, dist_min, dist_max); } else { /* 6 */ - BufferLineAccumulator<0, -1, -1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator<0, -1, -1, 0>::eval(input, output, co, source, dist_min, dist_max); } } } @@ -255,21 +273,21 @@ static void accumulate_line(MemoryBuffer *input, float output[4], const float co if (pt_ofs[0] > 0.0f) { if (pt_ofs[1] > 0.0f) { /* 1 */ - BufferLineAccumulator< 1, 0, 0, 1>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator< 1, 0, 0, 1>::eval(input, output, co, source, dist_min, dist_max); } else { /* 8 */ - BufferLineAccumulator< 1, 0, 0, -1>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator< 1, 0, 0, -1>::eval(input, output, co, source, dist_min, dist_max); } } else { if (pt_ofs[1] > 0.0f) { /* 4 */ - BufferLineAccumulator<-1, 0, 0, 1>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator<-1, 0, 0, 1>::eval(input, output, co, source, dist_min, dist_max); } else { /* 5 */ - BufferLineAccumulator<-1, 0, 0, -1>::eval(input, output, pt_ofs, source, dist_min, dist_max); + BufferLineAccumulator<-1, 0, 0, -1>::eval(input, output, co, source, dist_min, dist_max); } } } |