[Bf-blender-cvs] [12e9ccb] master: Cleanup and fix for uninitialized output buffer of the sunbeams node.

Lukas Tönne noreply at git.blender.org
Thu Dec 4 12:46:54 CET 2014


Commit: 12e9ccb256a6afa36320b7853e9d949de1e3054b
Author: Lukas Tönne
Date:   Thu Dec 4 12:43:07 2014 +0100
Branches: master
https://developer.blender.org/rB12e9ccb256a6afa36320b7853e9d949de1e3054b

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).

===================================================================

M	source/blender/compositor/operations/COM_SunBeamsOperation.cpp

===================================================================

diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp
index bcef652..12b04c3 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);
 			}
 		}
 	}




More information about the Bf-blender-cvs mailing list