Cycles: Fix difference in image Clip extension method between CPU and GPU
Our own implementation was behaving different comparing to OSL and GPU, namely on the border pixels OSL and CUDA was doing interpolation with black, but we were clamping coordinate. This partially fixes issue reported in T53452. Similar change should also be done for 3D interpolation perhaps, but this is to be investigated separately.
This commit is contained in:
parent
b90f3928a3
commit
a50c381fac
|
@ -156,6 +156,16 @@ template<typename T> struct texture_image {
|
|||
return make_float4(f, f, f, 1.0f);
|
||||
}
|
||||
|
||||
ccl_always_inline float4 read(const T *data,
|
||||
int x, int y,
|
||||
int width, int height)
|
||||
{
|
||||
if(x < 0 || y < 0 || x >= width || y >= height) {
|
||||
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
return read(data[y * width + x]);
|
||||
}
|
||||
|
||||
ccl_always_inline int wrap_periodic(int x, int width)
|
||||
{
|
||||
x %= width;
|
||||
|
@ -219,10 +229,9 @@ template<typename T> struct texture_image {
|
|||
niy = wrap_periodic(iy+1, height);
|
||||
break;
|
||||
case EXTENSION_CLIP:
|
||||
if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
|
||||
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
ATTR_FALLTHROUGH;
|
||||
nix = ix + 1;
|
||||
niy = iy + 1;
|
||||
break;
|
||||
case EXTENSION_EXTEND:
|
||||
nix = wrap_clamp(ix+1, width);
|
||||
niy = wrap_clamp(iy+1, height);
|
||||
|
@ -235,10 +244,10 @@ template<typename T> struct texture_image {
|
|||
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
float4 r = (1.0f - ty)*(1.0f - tx)*read(data[ix + iy*width]);
|
||||
r += (1.0f - ty)*tx*read(data[nix + iy*width]);
|
||||
r += ty*(1.0f - tx)*read(data[ix + niy*width]);
|
||||
r += ty*tx*read(data[nix + niy*width]);
|
||||
float4 r = (1.0f - ty) * (1.0f - tx) * read(data, ix, iy, width, height);
|
||||
r += (1.0f - ty) * tx * read(data, nix, iy, width, height);
|
||||
r += ty * (1.0f - tx) * read(data, ix, niy, width, height);
|
||||
r += ty * tx * read(data, nix, niy, width, height);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -262,10 +271,13 @@ template<typename T> struct texture_image {
|
|||
nniy = wrap_periodic(iy+2, height);
|
||||
break;
|
||||
case EXTENSION_CLIP:
|
||||
if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
|
||||
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
ATTR_FALLTHROUGH;
|
||||
pix = ix - 1;
|
||||
piy = iy - 1;
|
||||
nix = ix + 1;
|
||||
niy = iy + 1;
|
||||
nnix = ix + 2;
|
||||
nniy = iy + 2;
|
||||
break;
|
||||
case EXTENSION_EXTEND:
|
||||
pix = wrap_clamp(ix-1, width);
|
||||
piy = wrap_clamp(iy-1, height);
|
||||
|
@ -285,15 +297,13 @@ template<typename T> struct texture_image {
|
|||
}
|
||||
|
||||
const int xc[4] = {pix, ix, nix, nnix};
|
||||
const int yc[4] = {width * piy,
|
||||
width * iy,
|
||||
width * niy,
|
||||
width * nniy};
|
||||
const int yc[4] = {piy, iy, niy, 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) (read(data[xc[x] + yc[y]]))
|
||||
#define DATA(x, y) (read(data, xc[x], yc[y], width, height))
|
||||
#define TERM(col) \
|
||||
(v[col] * (u[0] * DATA(0, col) + \
|
||||
u[1] * DATA(1, col) + \
|
||||
|
|
Loading…
Reference in New Issue