[Bf-blender-cvs] [3b9d455] master: Cycles: Implement cubit image interpolation on CPU

Sergey Sharybin noreply at git.blender.org
Sun Feb 1 22:02:29 CET 2015


Commit: 3b9d455a90b3e57874db820ca873cefcd50b2205
Author: Sergey Sharybin
Date:   Mon Feb 2 01:40:01 2015 +0500
Branches: master
https://developer.blender.org/rB3b9d455a90b3e57874db820ca873cefcd50b2205

Cycles: Implement cubit image interpolation on CPU

Basically title says it all. Could be not totally optimized but the code is there now.

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

M	intern/cycles/kernel/kernel_compat_cpu.h
M	source/blender/makesrna/intern/rna_nodetree.c

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

diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h
index a7a2fb8..76167d0 100644
--- a/intern/cycles/kernel/kernel_compat_cpu.h
+++ b/intern/cycles/kernel/kernel_compat_cpu.h
@@ -71,6 +71,14 @@ template<typename T> struct texture  {
 };
 
 template<typename T> struct texture_image  {
+#define SET_CUBIC_SPLINE_WEIGHTS(u, t) \
+			{ \
+				u[0] = (((-1.0f/6.0f)* t + 0.5f) * t - 0.5f) * t + (1.0f/6.0f); \
+				u[1] =  ((      0.5f * t - 1.0f) * t       ) * t + (2.0f/3.0f); \
+				u[2] =  ((     -0.5f * t + 0.5f) * t + 0.5f) * t + (1.0f/6.0f); \
+				u[3] = (1.0f / 6.0f) * t * t * t; \
+			} (void)0
+
 	ccl_always_inline float4 read(float4 r)
 	{
 		return r;
@@ -123,7 +131,7 @@ template<typename T> struct texture_image  {
 			}
 			return read(data[ix + iy*width]);
 		}
-		else {
+		else if(interpolation == INTERPOLATION_LINEAR) {
 			float tx = frac(x*(float)width - 0.5f, &ix);
 			float ty = frac(y*(float)height - 0.5f, &iy);
 
@@ -149,6 +157,63 @@ template<typename T> struct texture_image  {
 
 			return r;
 		}
+		else {
+			/* Tricubic b-spline interpolation. */
+			const float tx = frac(x*(float)width - 0.5f, &ix);
+			const float ty = frac(y*(float)height - 0.5f, &iy);
+			int pix, piy, nnix, nniy;
+			if(periodic) {
+				ix = wrap_periodic(ix, width);
+				iy = wrap_periodic(iy, height);
+
+				pix = wrap_periodic(ix-1, width);
+				piy = wrap_periodic(iy-1, height);
+
+				nix = wrap_periodic(ix+1, width);
+				niy = wrap_periodic(iy+1, height);
+
+				nnix = wrap_periodic(ix+2, width);
+				nniy = wrap_periodic(iy+2, height);
+			}
+			else {
+				ix = wrap_clamp(ix, width);
+				iy = wrap_clamp(iy, height);
+
+				pix = wrap_clamp(ix-1, width);
+				piy = wrap_clamp(iy-1, height);
+
+				nix = wrap_clamp(ix+1, width);
+				niy = wrap_clamp(iy+1, height);
+
+				nnix = wrap_clamp(ix+2, width);
+				nniy = wrap_clamp(iy+2, height);
+			}
+			const int xc[4] = {pix, ix, nix, nnix};
+			const int yc[4] = {width * piy,
+			                   width * iy,
+			                   width * niy,
+			                   width * nniy};
+			float u[4], v[4], w[4];
+			/* Some helper macro to keep code reasonable size,
+			 * let compiler to inline all the matrix multiplications.
+			 */
+#define DATA(x, y) (read(data[xc[x] + yc[y]]))
+#define TERM(col) \
+			(v[col] * (u[0] * DATA(0, col) + \
+			           u[1] * DATA(1, col) + \
+			           u[2] * DATA(2, col) + \
+			           u[3] * DATA(3, col)))
+
+			SET_CUBIC_SPLINE_WEIGHTS(u, tx);
+			SET_CUBIC_SPLINE_WEIGHTS(v, ty);
+			SET_CUBIC_SPLINE_WEIGHTS(w, 0.0f);
+
+			/* Actual interpolation. */
+			return TERM(0) + TERM(1) + TERM(2) + TERM(3);
+
+#undef TERM
+#undef DATA
+		}
 	}
 
 	ccl_always_inline float4 interp_3d(float x, float y, float z, bool periodic = false)
@@ -277,13 +342,6 @@ template<typename T> struct texture_image  {
 			/* Some helper macro to keep code reasonable size,
 			 * let compiler to inline all the matrix multiplications.
 			 */
-#define SET_SPLINE_WEIGHTS(u, t) \
-			{ \
-				u[0] = (((-1.0f/6.0f)* t + 0.5f) * t - 0.5f) * t + (1.0f/6.0f); \
-				u[1] =  ((      0.5f * t - 1.0f) * t       ) * t + (2.0f/3.0f); \
-				u[2] =  ((     -0.5f * t + 0.5f) * t + 0.5f) * t + (1.0f/6.0f); \
-				u[3] = (1.0f / 6.0f) * t * t * t; \
-			} (void)0
 #define DATA(x, y, z) (read(data[xc[x] + yc[y] + zc[z]]))
 #define COL_TERM(col, row) \
 			(v[col] * (u[0] * DATA(0, col, row) + \
@@ -296,9 +354,9 @@ template<typename T> struct texture_image  {
 			           COL_TERM(2, row) + \
 			           COL_TERM(3, row)))
 
-			SET_SPLINE_WEIGHTS(u, tx);
-			SET_SPLINE_WEIGHTS(v, ty);
-			SET_SPLINE_WEIGHTS(w, tz);
+			SET_CUBIC_SPLINE_WEIGHTS(u, tx);
+			SET_CUBIC_SPLINE_WEIGHTS(v, ty);
+			SET_CUBIC_SPLINE_WEIGHTS(w, tz);
 
 			/* Actual interpolation. */
 			return ROW_TERM(0) + ROW_TERM(1) + ROW_TERM(2) + ROW_TERM(3);
@@ -306,7 +364,6 @@ template<typename T> struct texture_image  {
 #undef COL_TERM
 #undef ROW_TERM
 #undef DATA
-#undef SET_SPLINE_WEIGHTS
 		}
 	}
 
@@ -320,6 +377,7 @@ template<typename T> struct texture_image  {
 	T *data;
 	int interpolation;
 	int width, height, depth;
+#undef SET_CUBIC_SPLINE_WEIGHTS
 };
 
 typedef texture<float4> texture_float4;
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 3710c4c..7f574c4 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -3455,7 +3455,7 @@ static void def_sh_tex_image(StructRNA *srna)
 		{SHD_INTERP_CLOSEST, "Closest", 0, "Closest",
 		                     "No interpolation (sample closest texel)"},
 		{SHD_INTERP_CUBIC,   "Cubic", 0, "Cubic",
-		                     "Cubic interpolation (OSL only)"},
+		                     "Cubic interpolation (CPU only)"},
 		{SHD_INTERP_SMART,   "Smart", 0, "Smart",
 		                     "Bicubic when magnifying, else bilinear (OSL only)"},
 		{0, NULL, 0, NULL, NULL}




More information about the Bf-blender-cvs mailing list