[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59013] branches/soc-2011-tomato/source/ blender/compositor/operations/COM_PlaneTrackWarpImageOperation.cpp: Anti-aliasing for plane track image warping

Sergey Sharybin sergey.vfx at gmail.com
Thu Aug 8 09:38:49 CEST 2013


Revision: 59013
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59013
Author:   nazgul
Date:     2013-08-08 07:38:49 +0000 (Thu, 08 Aug 2013)
Log Message:
-----------
Anti-aliasing for plane track image warping

Uses the same exact kernel size of 4x4 as for plane
track mask output.

Think this is not a bad way to go, difference in speed
using test file was only about 30% with much better
output result.

Modified Paths:
--------------
    branches/soc-2011-tomato/source/blender/compositor/operations/COM_PlaneTrackWarpImageOperation.cpp

Modified: branches/soc-2011-tomato/source/blender/compositor/operations/COM_PlaneTrackWarpImageOperation.cpp
===================================================================
--- branches/soc-2011-tomato/source/blender/compositor/operations/COM_PlaneTrackWarpImageOperation.cpp	2013-08-08 07:38:42 UTC (rev 59012)
+++ branches/soc-2011-tomato/source/blender/compositor/operations/COM_PlaneTrackWarpImageOperation.cpp	2013-08-08 07:38:49 UTC (rev 59013)
@@ -45,17 +45,81 @@
 	       isect_point_tri_v2(point, corners[0], corners[2], corners[3]);
 }
 
-BLI_INLINE void resolveUV(const float x, const float y, const float corners[4][2], float uv[2])
+BLI_INLINE bool resolveUV(const float x, const float y, const float corners[4][2], float uv[2])
 {
 	float point[2];
+	bool inside;
 
+	inside = isPointInsideQuad(x, y, corners);
+
 	point[0] = x;
 	point[1] = y;
 
 	/* Use reverse bilinear to get UV coordinates within original frame */
 	resolve_quad_uv(uv, point, corners[0], corners[1], corners[2], corners[3]);
+
+	return inside;
 }
 
+BLI_INLINE void resolveUVAndDxDy(const float x, const float y, const float corners[4][2],
+                                 float *u_r, float *v_r, float *dx_r, float *dy_r)
+{
+	float inputUV[2];
+	float uv_a[2], uv_b[2];
+
+	float dx, dy;
+	float uv_l, uv_r;
+	float uv_u, uv_d;
+
+	bool ok1, ok2;
+
+	resolveUV(x, y, corners, inputUV);
+
+	/* adaptive sampling, red (U) channel */
+	ok1 = resolveUV(x - 1, y, corners, uv_a);
+	ok2 = resolveUV(x + 1, y, corners, uv_b);
+	uv_l = ok1 ? fabsf(inputUV[0] - uv_a[0]) : 0.0f;
+	uv_r = ok2 ? fabsf(inputUV[0] - uv_b[0]) : 0.0f;
+
+	dx = 0.5f * (uv_l + uv_r);
+
+	/* adaptive sampling, green (V) channel */
+	ok1 = resolveUV(x, y - 1, corners, uv_a);
+	ok2 = resolveUV(x, y + 1, corners, uv_b);
+	uv_u = ok1 ? fabsf(inputUV[1] - uv_a[1]) : 0.f;
+	uv_d = ok2 ? fabsf(inputUV[1] - uv_b[1]) : 0.f;
+
+	dy = 0.5f * (uv_u + uv_d);
+
+	/* more adaptive sampling, red and green (UV) channels */
+	ok1 = resolveUV(x - 1, y - 1, corners, uv_a);
+	ok2 = resolveUV(x - 1, y + 1, corners, uv_b);
+	uv_l = ok1 ? fabsf(inputUV[0] - uv_a[0]) : 0.f;
+	uv_r = ok2 ? fabsf(inputUV[0] - uv_b[0]) : 0.f;
+	uv_u = ok1 ? fabsf(inputUV[1] - uv_a[1]) : 0.f;
+	uv_d = ok2 ? fabsf(inputUV[1] - uv_b[1]) : 0.f;
+
+	dx += 0.25f * (uv_l + uv_r);
+	dy += 0.25f * (uv_u + uv_d);
+
+	ok1 = resolveUV(x + 1, y - 1, corners, uv_a);
+	ok2 = resolveUV(x + 1, y + 1, corners, uv_b);
+	uv_l = ok1 ? fabsf(inputUV[0] - uv_a[0]) : 0.f;
+	uv_r = ok2 ? fabsf(inputUV[0] - uv_b[0]) : 0.f;
+	uv_u = ok1 ? fabsf(inputUV[1] - uv_a[1]) : 0.f;
+	uv_d = ok2 ? fabsf(inputUV[1] - uv_b[1]) : 0.f;
+
+	dx += 0.25f * (uv_l + uv_r);
+	dy += 0.25f * (uv_u + uv_d);
+
+	/* should use mipmap */
+	*dx_r = min(dx, 0.2f);
+	*dy_r = min(dy, 0.2f);
+
+	*u_r = inputUV[0];
+	*v_r = inputUV[1];
+}
+
 PlaneTrackWarpImageOperation::PlaneTrackWarpImageOperation() : PlaneTrackCommonOperation()
 {
 	this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE);
@@ -78,73 +142,38 @@
 
 void PlaneTrackWarpImageOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
 {
+	const int kernel_size = 4;
 	float frame_space_corners[4][2];
+	float color_accum[4];
 
 	for (int i = 0; i < 4; i++) {
-		frame_space_corners[i][0] = this->m_corners[i][0] * this->getWidth();
-		frame_space_corners[i][1] = this->m_corners[i][1] * this->getHeight();
+		frame_space_corners[i][0] = this->m_corners[i][0] * this->getWidth() * kernel_size;
+		frame_space_corners[i][1] = this->m_corners[i][1] * this->getHeight() * kernel_size;
 	}
 
-	if (isPointInsideQuad(x, y, frame_space_corners)) {
-		float inputUV[2];
-		float uv_a[2], uv_b[2];
-		float u, v;
+	zero_v4(color_accum);
+	for (int sample_dx = 0; sample_dx < kernel_size; sample_dx++) {
+		for (int sample_dy = 0; sample_dy < kernel_size; sample_dy++) {
+			float current_x = x * kernel_size + sample_dx,
+			      current_y = y * kernel_size + sample_dy;
+			if (isPointInsideQuad(current_x, current_y, frame_space_corners)) {
+				float current_color[4];
+				float u, v, dx, dy;
 
-		float dx, dy;
-		float uv_l, uv_r;
-		float uv_u, uv_d;
+				resolveUVAndDxDy(current_x, current_y, frame_space_corners, &u, &v, &dx, &dy);
 
-		resolveUV(x, y, frame_space_corners, inputUV);
+				u *= this->m_pixelReader->getWidth();
+				v *= this->m_pixelReader->getHeight();
 
-		/* adaptive sampling, red (U) channel */
-		resolveUV(x - 1, y, frame_space_corners, uv_a);
-		resolveUV(x + 1, y, frame_space_corners, uv_b);
-		uv_l = fabsf(inputUV[0] - uv_a[0]);
-		uv_r = fabsf(inputUV[0] - uv_b[0]);
+				this->m_pixelReader->read(current_color, u, v, dx, dy, COM_PS_BICUBIC);
+				premul_to_straight_v4(current_color);
+				add_v4_v4(color_accum, current_color);
+			}
+		}
+	}
 
-		dx = 0.5f * (uv_l + uv_r);
-
-		/* adaptive sampling, green (V) channel */
-		resolveUV(x, y - 1, frame_space_corners, uv_a);
-		resolveUV(x, y + 1, frame_space_corners, uv_b);
-		uv_u = fabsf(inputUV[1] - uv_a[1]);
-		uv_d = fabsf(inputUV[1] - uv_b[1]);
-
-		dy = 0.5f * (uv_u + uv_d);
-
-		/* more adaptive sampling, red and green (UV) channels */
-		resolveUV(x - 1, y - 1, frame_space_corners, uv_a);
-		resolveUV(x - 1, y + 1, frame_space_corners, uv_b);
-		uv_l = fabsf(inputUV[0] - uv_a[0]);
-		uv_r = fabsf(inputUV[0] - uv_b[0]);
-		uv_u = fabsf(inputUV[1] - uv_a[1]);
-		uv_d = fabsf(inputUV[1] - uv_b[1]);
-
-		dx += 0.25f * (uv_l + uv_r);
-		dy += 0.25f * (uv_u + uv_d);
-
-		resolveUV(x + 1, y - 1, frame_space_corners, uv_a);
-		resolveUV(x + 1, y + 1, frame_space_corners, uv_b);
-		uv_l = fabsf(inputUV[0] - uv_a[0]);
-		uv_r = fabsf(inputUV[0] - uv_b[0]);
-		uv_u = fabsf(inputUV[1] - uv_a[1]);
-		uv_d = fabsf(inputUV[1] - uv_b[1]);
-
-		dx += 0.25f * (uv_l + uv_r);
-		dy += 0.25f * (uv_u + uv_d);
-
-		/* should use mipmap */
-		dx = min(dx, 0.2f);
-		dy = min(dy, 0.2f);
-
-		u = inputUV[0] * this->m_pixelReader->getWidth();
-		v = inputUV[1] * this->m_pixelReader->getHeight();
-
-		this->m_pixelReader->read(output, u, v, dx, dy, COM_PS_BICUBIC);
-	}
-	else {
-		zero_v4(output);
-	}
+	mul_v4_v4fl(output, color_accum, 1.0f / (kernel_size * kernel_size));
+	straight_to_premul_v4(output);
 }
 
 bool PlaneTrackWarpImageOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)




More information about the Bf-blender-cvs mailing list