Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Tönne <lukas.toenne@gmail.com>2014-12-04 14:43:07 +0300
committerLukas Tönne <lukas.toenne@gmail.com>2014-12-04 14:46:45 +0300
commit12e9ccb256a6afa36320b7853e9d949de1e3054b (patch)
treeb486f88e8ceff8d8487ccc56b7abd6980b17ce95
parentcf151470533466238b680de60ac04649d261fe92 (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).
-rw-r--r--source/blender/compositor/operations/COM_SunBeamsOperation.cpp92
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);
}
}
}