Commit: f61c340bc15ef1573dc48f65fc7c71fce0a47a07
Author: Brecht Van Lommel
Date:   Sun Oct 8 02:36:05 2017 +0200
Branches: master
https://developer.blender.org/rBf61c340bc15ef1573dc48f65fc7c71fce0a47a07

Cycles: OpenCL bicubic and tricubic texture interpolation support.

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

M       intern/cycles/blender/addon/ui.py
M       intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h
M       intern/cycles/util/util_texture.h
M       source/blender/makesrna/intern/rna_nodetree.c

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

diff --git a/intern/cycles/blender/addon/ui.py 
b/intern/cycles/blender/addon/ui.py
index baf1b9c31ee..7d19bccae4e 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -1208,9 +1208,7 @@ class CYCLES_WORLD_PT_settings(CyclesButtonsPanel, Panel):
         sub = col.column()
         sub.active = use_cpu(context)
         sub.prop(cworld, "volume_sampling", text="")
-        sub = col.column()
-        sub.active = not use_opencl(context)
-        sub.prop(cworld, "volume_interpolation", text="")
+        col.prop(cworld, "volume_interpolation", text="")
         col.prop(cworld, "homogeneous_volume", text="Homogeneous")
 
 
@@ -1309,9 +1307,7 @@ class CYCLES_MATERIAL_PT_settings(CyclesButtonsPanel, 
Panel):
         sub = col.column()
         sub.active = use_cpu(context)
         sub.prop(cmat, "volume_sampling", text="")
-        sub = col.column()
-        sub.active = not use_opencl(context)
-        sub.prop(cmat, "volume_interpolation", text="")
+        col.prop(cmat, "volume_interpolation", text="")
         col.prop(cmat, "homogeneous_volume", text="Homogeneous")
 
         layout.separator()
diff --git a/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h 
b/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h
index 20ec36aa9eb..d908af78c7a 100644
--- a/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h
+++ b/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h
@@ -75,20 +75,26 @@ ccl_device_inline float svm_image_texture_frac(float x, int 
*ix)
        return x - (float)i;
 }
 
+#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_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, 
float y)
 {
        const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
 
        uint width = info->width;
        uint height = info->height;
-       uint offset = 0;
        uint interpolation = info->interpolation;
        uint extension = info->extension;
 
        /* Actual sampling. */
-       float4 r;
-       int ix, iy, nix, niy;
        if(interpolation == INTERPOLATION_CLOSEST) {
+               int ix, iy;
                svm_image_texture_frac(x*width, &ix);
                svm_image_texture_frac(y*height, &iy);
 
@@ -108,16 +114,17 @@ ccl_device float4 kernel_tex_image_interp(KernelGlobals 
*kg, int id, float x, fl
                        iy = svm_image_texture_wrap_clamp(iy, height);
                }
 
-               r = svm_image_texture_read(kg, id, offset + ix + iy*width);
+               return svm_image_texture_read(kg, id, ix + iy*width);
        }
-       else { /* INTERPOLATION_LINEAR */
+       else {
+               /* Bilinear or bicubic interpolation. */
+               int ix, iy, nix, niy;
                float tx = svm_image_texture_frac(x*width - 0.5f, &ix);
                float ty = svm_image_texture_frac(y*height - 0.5f, &iy);
 
                if(extension == EXTENSION_REPEAT) {
                        ix = svm_image_texture_wrap_periodic(ix, width);
                        iy = svm_image_texture_wrap_periodic(iy, height);
-
                        nix = svm_image_texture_wrap_periodic(ix+1, width);
                        niy = svm_image_texture_wrap_periodic(iy+1, height);
                }
@@ -127,18 +134,61 @@ ccl_device float4 kernel_tex_image_interp(KernelGlobals 
*kg, int id, float x, fl
                                        return make_float4(0.0f, 0.0f, 0.0f, 
0.0f);
                                }
                        }
-                       nix = svm_image_texture_wrap_clamp(ix+1, width);
-                       niy = svm_image_texture_wrap_clamp(iy+1, height);
                        ix = svm_image_texture_wrap_clamp(ix, width);
                        iy = svm_image_texture_wrap_clamp(iy, height);
+                       nix = svm_image_texture_wrap_clamp(ix+1, width);
+                       niy = svm_image_texture_wrap_clamp(iy+1, height);
                }
 
-               r = (1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, id, 
offset + ix + iy*width);
-               r += (1.0f - ty)*tx*svm_image_texture_read(kg, id, offset + nix 
+ iy*width);
-               r += ty*(1.0f - tx)*svm_image_texture_read(kg, id, offset + ix 
+ niy*width);
-               r += ty*tx*svm_image_texture_read(kg, id, offset + nix + 
niy*width);
+               if(interpolation == INTERPOLATION_LINEAR) {
+                       /* Bilinear interpolation. */
+                       float4 r;
+                       r = (1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, 
id, ix + iy*width);
+                       r += (1.0f - ty)*tx*svm_image_texture_read(kg, id, nix 
+ iy*width);
+                       r += ty*(1.0f - tx)*svm_image_texture_read(kg, id, ix + 
niy*width);
+                       r += ty*tx*svm_image_texture_read(kg, id, nix + 
niy*width);
+                       return r;
+               }
+
+               /* Bicubic interpolation. */
+               int pix, piy, nnix, nniy;
+               if(extension == EXTENSION_REPEAT) {
+                       pix = svm_image_texture_wrap_periodic(ix-1, width);
+                       piy = svm_image_texture_wrap_periodic(iy-1, height);
+                       nnix = svm_image_texture_wrap_periodic(ix+2, width);
+                       nniy = svm_image_texture_wrap_periodic(iy+2, height);
+               }
+               else {
+                       pix = svm_image_texture_wrap_clamp(ix-1, width);
+                       piy = svm_image_texture_wrap_clamp(iy-1, height);
+                       nnix = svm_image_texture_wrap_clamp(ix+2, width);
+                       nniy = svm_image_texture_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];
+               /* Some helper macro to keep code reasonable size,
+                * let compiler to inline all the matrix multiplications.
+                */
+#define DATA(x, y) (svm_image_texture_read(kg, id, 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);
+
+               /* Actual interpolation. */
+               return TERM(0) + TERM(1) + TERM(2) + TERM(3);
+#undef TERM
+#undef DATA
        }
-       return r;
 }
 
 
@@ -148,15 +198,13 @@ ccl_device float4 
kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x,
 
        uint width = info->width;
        uint height = info->height;
-       uint offset = 0;
        uint depth = info->depth;
        uint interpolation = (interp == INTERPOLATION_NONE)? 
info->interpolation: interp;
        uint extension = info->extension;
 
        /* Actual sampling. */
-       float4 r;
-       int ix, iy, iz, nix, niy, niz;
        if(interpolation == INTERPOLATION_CLOSEST) {
+               int ix, iy, iz;
                svm_image_texture_frac(x*width, &ix);
                svm_image_texture_frac(y*height, &iy);
                svm_image_texture_frac(z*depth, &iz);
@@ -180,9 +228,11 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals 
*kg, int id, float x,
                        iy = svm_image_texture_wrap_clamp(iy, height);
                        iz = svm_image_texture_wrap_clamp(iz, depth);
                }
-               r = svm_image_texture_read(kg, id, offset + ix + iy*width + 
iz*width*height);
+               return svm_image_texture_read(kg, id, ix + iy*width + 
iz*width*height);
        }
-       else { /* INTERPOLATION_LINEAR */
+       else {
+               /* Bilinear or bicubic interpolation. */
+               int ix, iy, iz, nix, niy, niz;
                float tx = svm_image_texture_frac(x*(float)width - 0.5f, &ix);
                float ty = svm_image_texture_frac(y*(float)height - 0.5f, &iy);
                float tz = svm_image_texture_frac(z*(float)depth - 0.5f, &iz);
@@ -215,15 +265,77 @@ ccl_device float4 
kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x,
                        iz = svm_image_texture_wrap_clamp(iz, depth);
                }
 
-               r  = (1.0f - tz)*(1.0f - ty)*(1.0f - 
tx)*svm_image_texture_read(kg, id, offset + ix + iy*width + iz*width*height);
-               r += (1.0f - tz)*(1.0f - ty)*tx*svm_image_texture_read(kg, id, 
offset + nix + iy*width + iz*width*height);
-               r += (1.0f - tz)*ty*(1.0f - tx)*svm_image_texture_read(kg, id, 
offset + ix + niy*width + iz*width*height);
-               r += (1.0f - tz)*ty*tx*svm_image_texture_read(kg, id, offset + 
nix + niy*width + iz*width*height);
+               if(interpolation == INTERPOLATION_LINEAR) {
+                       /* Bilinear interpolation. */
+                       float4 r;
+                       r  = (1.0f - tz)*(1.0f - ty)*(1.0f - 
tx)*svm_image_texture_read(kg, id, ix + iy*width + iz*width*height);
+                       r += (1.0f - tz)*(1.0f - 
ty)*tx*svm_image_texture_read(kg, id, nix + iy*width + iz*width*height);
+                       r += (1.0f - tz)*ty*(1.0f - 
tx)*svm_image_texture_read(kg, id, ix + niy*width + iz*width*height);
+                       r += (1.0f - tz)*ty*tx*svm_image_texture_read(kg, id, 
nix + niy*width + iz*width*height);
+
+                       r += tz*(1.0f - ty)*(1.0f - 
tx)*svm_image_texture_read(kg, id, ix + iy*width + niz*width*height);
+                       r += tz*(1.0f - ty)*tx*svm_image_texture_read(kg, id, 
nix + iy*width + niz*width*height);
+                       r += tz*ty*(1.0f - tx)*svm_image_texture_read(kg, id, 
ix + niy*width + niz*width*height);
+                       r += tz*ty*tx*svm_image_texture_read(kg, id, nix + 
niy*width + niz*width*height);
+                       return r;
+               }
+
+               /* Bicubic interpolation. */
+               int pix, piy, piz, nnix, nniy, nniz;
+               if(extension == EXTENSION_REPEAT) {
+                       pix = svm_image_texture_wrap_periodic(ix-1, width);
+                       piy = svm_image_texture_wrap_periodic(iy-1, height);
+                       piz = svm_image_texture_wrap_periodic(iz-1, depth);
+                       nnix = svm_image_texture_wrap_periodic(ix+2, width);
+                       nniy = svm_image_texture_wrap_periodic(iy+2, height);
+                       nniz = svm_image_texture_wrap_periodic(iz+2, depth);
+               }
+               else {
+                       pix = svm_image_texture_wrap_clamp(ix-1, width);
+                       piy = svm_image_texture_wrap_clamp(iy-1, height);
+                       piz = svm_image_texture_wrap_clamp(iz-1, depth);
+                       nnix = svm_image_texture_wrap_clamp(ix+2, width);
+                       nniy = svm_image_texture_wrap_clamp(iy+2, height);
+                       nniz = svm_image_texture_wrap_clamp(iz+2, depth);
+               }
+
+               const int xc[4] = {pix, ix, nix, nnix};
+               const int yc[4] = {width * piy,
+                                  width * iy,
+                                  width * niy,
+                                  width * nniy};
+               const int zc[4] = {width * height * piz,
+                                  width * height * iz,
+                                  width * height * niz,
+                                  width * height * nniz};
+               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, z) (svm_image_texture_read(kg, id, xc[x] + yc[y] + zc[z]))
+#define COL_TERM(col, row) \
+               (v[col] * (u[0] * DATA(0, col, row) + \
+                          u[1] * DATA(1, col, row) + \
+                          u[2] * DATA(2, col, row) + \
+                          u[3] * DATA(3, col, row)))
+#define ROW_TERM(row) \
+               (w[row] * (COL_TERM(0, row) + \
+                          COL_TERM(1, row) + \
+                          COL_TERM(2, row) + \
+                     

@@ Diff output truncated at 10240 characters. @@

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

Reply via email to