[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59822] trunk/blender/source/blender/ compositor: Extend mode option for MemoryBuffer reading in compositor.

Lukas Toenne lukas.toenne at googlemail.com
Thu Sep 5 12:45:19 CEST 2013


Revision: 59822
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59822
Author:   lukastoenne
Date:     2013-09-05 10:45:19 +0000 (Thu, 05 Sep 2013)
Log Message:
-----------
Extend mode option for MemoryBuffer reading in compositor. This will allow proper interpolation of pixel values when using wrapping in the Translate node. Implemented in inline functions, so won't cause
overhead if constant values are passed (as happens with most calls using the default argument).

Modified Paths:
--------------
    trunk/blender/source/blender/compositor/intern/COM_MemoryBuffer.h
    trunk/blender/source/blender/compositor/operations/COM_GlareGhostOperation.cpp
    trunk/blender/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp
    trunk/blender/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp
    trunk/blender/source/blender/compositor/operations/COM_ReadBufferOperation.cpp
    trunk/blender/source/blender/compositor/operations/COM_ReadBufferOperation.h
    trunk/blender/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp

Modified: trunk/blender/source/blender/compositor/intern/COM_MemoryBuffer.h
===================================================================
--- trunk/blender/source/blender/compositor/intern/COM_MemoryBuffer.h	2013-09-05 10:12:00 UTC (rev 59821)
+++ trunk/blender/source/blender/compositor/intern/COM_MemoryBuffer.h	2013-09-05 10:45:19 UTC (rev 59822)
@@ -46,6 +46,12 @@
 	COM_MB_TEMPORARILY = 6
 } MemoryBufferState;
 
+typedef enum MemoryBufferExtend {
+	COM_MB_CLIP,
+	COM_MB_EXTEND,
+	COM_MB_REPEAT
+} MemoryBufferExtend;
+
 class MemoryProxy;
 
 /**
@@ -125,31 +131,67 @@
 		this->m_state = COM_MB_AVAILABLE;
 	}
 	
-	inline void read(float result[4], int x, int y)
+	inline void wrap_pixel(int &x, int &y, MemoryBufferExtend extend_x, MemoryBufferExtend extend_y)
 	{
-		if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
-		    y >= this->m_rect.ymin && y < this->m_rect.ymax)
-		{
-			const int dx = x - this->m_rect.xmin;
-			const int dy = y - this->m_rect.ymin;
-			const int offset = (this->m_chunkWidth * dy + dx) * COM_NUMBER_OF_CHANNELS;
-			copy_v4_v4(result, &this->m_buffer[offset]);
+		int w = m_rect.xmax - m_rect.xmin;
+		int h = m_rect.ymax - m_rect.ymin;
+		x = x - m_rect.xmin;
+		y = y - m_rect.ymin;
+		
+		switch (extend_x) {
+			case COM_MB_CLIP:
+				break;
+			case COM_MB_EXTEND:
+				if (x < 0) x = 0;
+				if (x >= w) x = w;
+				break;
+			case COM_MB_REPEAT:
+				x = (x >= 0.0f ? (x % w) : (x % w) + w);
+				break;
 		}
-		else {
+		
+		switch (extend_y) {
+			case COM_MB_CLIP:
+				break;
+			case COM_MB_EXTEND:
+				if (y < 0) y = 0;
+				if (y >= h) y = h;
+				break;
+			case COM_MB_REPEAT:
+				y = (y >= 0.0f ? (y % h) : (y % h) + h);
+				break;
+		}
+	}
+	
+	inline void read(float result[4], int x, int y,
+	                 MemoryBufferExtend extend_x = COM_MB_CLIP,
+	                 MemoryBufferExtend extend_y = COM_MB_CLIP)
+	{
+		bool clip_x = (extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax));
+		bool clip_y = (extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax));
+		if (clip_x || clip_y) {
+			/* clip result outside rect is zero */
 			zero_v4(result);
 		}
+		else {
+			wrap_pixel(x, y, extend_x, extend_y);
+			const int offset = (this->m_chunkWidth * y + x) * COM_NUMBER_OF_CHANNELS;
+			copy_v4_v4(result, &this->m_buffer[offset]);
+		}
 	}
 
-	inline void readNoCheck(float result[4], int x, int y)
+	inline void readNoCheck(float result[4], int x, int y,
+	                        MemoryBufferExtend extend_x = COM_MB_CLIP,
+	                        MemoryBufferExtend extend_y = COM_MB_CLIP)
 	{
-		const int dx = x - this->m_rect.xmin;
-		const int dy = y - this->m_rect.ymin;
-		const int offset = (this->m_chunkWidth * dy + dx) * COM_NUMBER_OF_CHANNELS;
+		wrap_pixel(x, y, extend_x, extend_y);
+		const int offset = (this->m_chunkWidth * y + x) * COM_NUMBER_OF_CHANNELS;
 
 		BLI_assert(offset >= 0);
 		BLI_assert(offset < this->determineBufferSize() * COM_NUMBER_OF_CHANNELS);
-		BLI_assert(x >= this->m_rect.xmin && x < this->m_rect.xmax &&
-		           y >= this->m_rect.ymin && y < this->m_rect.ymax);
+		bool clip_x = (extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax));
+		bool clip_y = (extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax));
+		BLI_assert(!clip_x && !clip_y);
 
 #if 0
 		/* always true */
@@ -162,12 +204,16 @@
 	
 	void writePixel(int x, int y, const float color[4]);
 	void addPixel(int x, int y, const float color[4]);
-	inline void readCubic(float result[4], float x, float y)
+	inline void readBilinear(float result[4], float x, float y,
+	                         MemoryBufferExtend extend_x = COM_MB_CLIP,
+	                         MemoryBufferExtend extend_y = COM_MB_CLIP)
 	{
 		int x1 = floor(x);
+		int y1 = floor(y);
 		int x2 = x1 + 1;
-		int y1 = floor(y);
 		int y2 = y1 + 1;
+		wrap_pixel(x1, y1, extend_x, extend_y);
+		wrap_pixel(x2, y2, extend_x, extend_y);
 
 		float valuex = x - x1;
 		float valuey = y - y1;
@@ -199,9 +245,7 @@
 		result[2] = color1[2] * mvaluex + color3[2] * valuex;
 		result[3] = color1[3] * mvaluex + color3[3] * valuex;
 	}
-		
 
-
 	void readEWA(float result[4], float fx, float fy, float dx, float dy, PixelSampler sampler);
 	
 	/**

Modified: trunk/blender/source/blender/compositor/operations/COM_GlareGhostOperation.cpp
===================================================================
--- trunk/blender/source/blender/compositor/operations/COM_GlareGhostOperation.cpp	2013-09-05 10:12:00 UTC (rev 59821)
+++ trunk/blender/source/blender/compositor/operations/COM_GlareGhostOperation.cpp	2013-09-05 10:45:19 UTC (rev 59822)
@@ -83,11 +83,11 @@
 		for (x = 0; x < gbuf->getWidth(); x++) {
 			u = ((float)x + 0.5f) / (float)gbuf->getWidth();
 			s = (u - 0.5f) * sc + 0.5f, t = (v - 0.5f) * sc + 0.5f;
-			tbuf1->readCubic(c, s * gbuf->getWidth(), t * gbuf->getHeight());
+			tbuf1->readBilinear(c, s * gbuf->getWidth(), t * gbuf->getHeight());
 			sm = smoothMask(s, t);
 			mul_v3_fl(c, sm);
 			s = (u - 0.5f) * isc + 0.5f, t = (v - 0.5f) * isc + 0.5f;
-			tbuf2->readCubic(tc, s * gbuf->getWidth() - 0.5f, t * gbuf->getHeight() - 0.5f);
+			tbuf2->readBilinear(tc, s * gbuf->getWidth() - 0.5f, t * gbuf->getHeight() - 0.5f);
 			sm = smoothMask(s, t);
 			madd_v3_v3fl(c, tc, sm);
 
@@ -108,7 +108,7 @@
 					np = (n << 2) + p;
 					s = (u - 0.5f) * scalef[np] + 0.5f;
 					t = (v - 0.5f) * scalef[np] + 0.5f;
-					gbuf->readCubic(c, s * gbuf->getWidth() - 0.5f, t * gbuf->getHeight() - 0.5f);
+					gbuf->readBilinear(c, s * gbuf->getWidth() - 0.5f, t * gbuf->getHeight() - 0.5f);
 					mul_v3_v3(c, cm[np]);
 					sm = smoothMask(s, t) * 0.25f;
 					madd_v3_v3fl(tc, c, sm);

Modified: trunk/blender/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp
===================================================================
--- trunk/blender/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp	2013-09-05 10:12:00 UTC (rev 59821)
+++ trunk/blender/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp	2013-09-05 10:45:19 UTC (rev 59822)
@@ -54,9 +54,9 @@
 					// first pass no offset, always same for every pass, exact copy,
 					// otherwise results in uneven brightness, only need once
 					if (n == 0) tsrc->read(c1, x, y); else c1[0] = c1[1] = c1[2] = 0;
-					tsrc->readCubic(c2, x + vxp, y + vyp);
-					tsrc->readCubic(c3, x + vxp * 2.f, y + vyp * 2.f);
-					tsrc->readCubic(c4, x + vxp * 3.f, y + vyp * 3.f);
+					tsrc->readBilinear(c2, x + vxp, y + vyp);
+					tsrc->readBilinear(c3, x + vxp * 2.f, y + vyp * 2.f);
+					tsrc->readBilinear(c4, x + vxp * 3.f, y + vyp * 3.f);
 					// modulate color to look vaguely similar to a color spectrum
 					c2[1] *= cmo;
 					c2[2] *= cmo;

Modified: trunk/blender/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp
===================================================================
--- trunk/blender/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp	2013-09-05 10:12:00 UTC (rev 59821)
+++ trunk/blender/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp	2013-09-05 10:45:19 UTC (rev 59822)
@@ -55,11 +55,11 @@
 	const float v = (y + 0.5f) / height;
 	const float u = (x + 0.5f) / width;
 	MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
-	inputBuffer->readCubic(inputValue, (u * width + this->m_kr2) - 0.5f, v * height - 0.5f);
+	inputBuffer->readBilinear(inputValue, (u * width + this->m_kr2) - 0.5f, v * height - 0.5f);
 	output[0] = inputValue[0];
 	inputBuffer->read(inputValue, x, y);
 	output[1] = inputValue[1];
-	inputBuffer->readCubic(inputValue, (u * width - this->m_kr2) - 0.5f, v * height - 0.5f);
+	inputBuffer->readBilinear(inputValue, (u * width - this->m_kr2) - 0.5f, v * height - 0.5f);
 	output[2] = inputValue[2];
 	output[3] = 1.0f;
 }

Modified: trunk/blender/source/blender/compositor/operations/COM_ReadBufferOperation.cpp
===================================================================
--- trunk/blender/source/blender/compositor/operations/COM_ReadBufferOperation.cpp	2013-09-05 10:12:00 UTC (rev 59821)
+++ trunk/blender/source/blender/compositor/operations/COM_ReadBufferOperation.cpp	2013-09-05 10:45:19 UTC (rev 59822)
@@ -62,7 +62,7 @@
 		m_buffer->read(output, x, y);
 	}
 	else {
-		m_buffer->readCubic(output, x, y);
+		m_buffer->readBilinear(output, x, y);
 	}
 }
 

Modified: trunk/blender/source/blender/compositor/operations/COM_ReadBufferOperation.h
===================================================================
--- trunk/blender/source/blender/compositor/operations/COM_ReadBufferOperation.h	2013-09-05 10:12:00 UTC (rev 59821)
+++ trunk/blender/source/blender/compositor/operations/COM_ReadBufferOperation.h	2013-09-05 10:45:19 UTC (rev 59822)
@@ -44,7 +44,7 @@
 	void executePixel(float output[4], float x, float y, float dx, float dy, PixelSampler sampler);
 	const bool isReadBufferOperation() const { return true; }
 	void setOffset(unsigned int offset) { this->m_offset = offset; }
-	unsigned int getOffset() { return this->m_offset; }
+	unsigned int getOffset() const { return this->m_offset; }
 	bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
 	MemoryBuffer *getInputMemoryBuffer(MemoryBuffer **memoryBuffers) { return memoryBuffers[this->m_offset]; }
 	void readResolutionFromWriteBuffer();

Modified: trunk/blender/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp
===================================================================
--- trunk/blender/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp	2013-09-05 10:12:00 UTC (rev 59821)
+++ trunk/blender/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp	2013-09-05 10:45:19 UTC (rev 59822)
@@ -103,7 +103,7 @@
 				d = 1.0f / (1.0f + sqrtf(t));
 				const float nx = (u * d + 0.5f) * width - 0.5f;
 				const float ny = (v * d + 0.5f) * height - 0.5f;
-				buffer->readCubic(color, nx, ny);
+				buffer->readBilinear(color, nx, ny);
 				tc[0] += (1.0f - tz) * color[0], tc[1] += tz * color[1];
 				dr++, dg++;
 			}
@@ -121,7 +121,7 @@
 				d = 1.0f / (1.0f + sqrtf(t));
 				const float nx = (u * d + 0.5f) * width - 0.5f;
 				const float ny = (v * d + 0.5f) * height - 0.5f;
-				buffer->readCubic(color, nx, ny);
+				buffer->readBilinear(color, nx, ny);
 				tc[1] += (1.0f - tz) * color[1], tc[2] += tz * color[2];

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list