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}

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to