Cycles: Add implementation of clip extension mode

For now there's no OpenCL support, it'll come later.
This commit is contained in:
Sergey Sharybin 2015-07-28 14:36:08 +02:00
parent 3fba620858
commit 4690281b17
4 changed files with 160 additions and 104 deletions

@ -513,13 +513,19 @@ public:
cuda_assert(cuTexRefSetFlags(texref, CU_TRSF_READ_AS_INTEGER));
}
if(extension == EXTENSION_REPEAT) {
switch(extension) {
case EXTENSION_REPEAT:
cuda_assert(cuTexRefSetAddressMode(texref, 0, CU_TR_ADDRESS_MODE_WRAP));
cuda_assert(cuTexRefSetAddressMode(texref, 1, CU_TR_ADDRESS_MODE_WRAP));
}
else {
break;
case EXTENSION_EXTEND:
cuda_assert(cuTexRefSetAddressMode(texref, 0, CU_TR_ADDRESS_MODE_CLAMP));
cuda_assert(cuTexRefSetAddressMode(texref, 1, CU_TR_ADDRESS_MODE_CLAMP));
break;
case EXTENSION_CLIP:
cuda_assert(cuTexRefSetAddressMode(texref, 0, CU_TR_ADDRESS_MODE_BORDER));
cuda_assert(cuTexRefSetAddressMode(texref, 1, CU_TR_ADDRESS_MODE_BORDER));
break;
}
cuda_assert(cuTexRefSetFormat(texref, format, mem.data_elements));

@ -138,14 +138,20 @@ template<typename T> struct texture_image {
if(interpolation == INTERPOLATION_CLOSEST) {
frac(x*(float)width, &ix);
frac(y*(float)height, &iy);
if(extension == EXTENSION_REPEAT) {
switch(extension) {
case EXTENSION_REPEAT:
ix = wrap_periodic(ix, width);
iy = wrap_periodic(iy, height);
break;
case EXTENSION_CLIP:
if (ix < 0 || iy < 0 || ix >= width || iy >= height) {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
else {
/* Fall through. */
case EXTENSION_EXTEND:
ix = wrap_clamp(ix, width);
iy = wrap_clamp(iy, height);
break;
}
return read(data[ix + iy*width]);
}
@ -153,19 +159,26 @@ template<typename T> struct texture_image {
float tx = frac(x*(float)width - 0.5f, &ix);
float ty = frac(y*(float)height - 0.5f, &iy);
if(extension == EXTENSION_REPEAT) {
switch(extension) {
case EXTENSION_REPEAT:
ix = wrap_periodic(ix, width);
iy = wrap_periodic(iy, height);
nix = wrap_periodic(ix+1, width);
niy = wrap_periodic(iy+1, height);
break;
case EXTENSION_CLIP:
if (ix < 0 || iy < 0 || ix >= width || iy >= height) {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
else {
/* Fall through. */
case EXTENSION_EXTEND:
ix = wrap_clamp(ix, width);
iy = wrap_clamp(iy, height);
nix = wrap_clamp(ix+1, width);
niy = wrap_clamp(iy+1, height);
break;
}
float4 r = (1.0f - ty)*(1.0f - tx)*read(data[ix + iy*width]);
@ -176,11 +189,12 @@ template<typename T> struct texture_image {
return r;
}
else {
/* Tricubic b-spline interpolation. */
/* Bicubic 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(extension == EXTENSION_REPEAT) {
switch(extension) {
case EXTENSION_REPEAT:
ix = wrap_periodic(ix, width);
iy = wrap_periodic(iy, height);
@ -192,8 +206,13 @@ template<typename T> struct texture_image {
nnix = wrap_periodic(ix+2, width);
nniy = wrap_periodic(iy+2, height);
break;
case EXTENSION_CLIP:
if (ix < 0 || iy < 0 || ix >= width || iy >= height) {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
else {
/* Fall through. */
case EXTENSION_EXTEND:
ix = wrap_clamp(ix, width);
iy = wrap_clamp(iy, height);
@ -205,7 +224,9 @@ template<typename T> struct texture_image {
nnix = wrap_clamp(ix+2, width);
nniy = wrap_clamp(iy+2, height);
break;
}
const int xc[4] = {pix, ix, nix, nnix};
const int yc[4] = {width * piy,
width * iy,
@ -251,15 +272,22 @@ template<typename T> struct texture_image {
frac(y*(float)height, &iy);
frac(z*(float)depth, &iz);
if(extension == EXTENSION_REPEAT) {
switch(extension) {
case EXTENSION_REPEAT:
ix = wrap_periodic(ix, width);
iy = wrap_periodic(iy, height);
iz = wrap_periodic(iz, depth);
break;
case EXTENSION_CLIP:
if (ix < 0 || iy < 0 || ix >= width || iy >= height) {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
else {
/* Fall through. */
case EXTENSION_EXTEND:
ix = wrap_clamp(ix, width);
iy = wrap_clamp(iy, height);
iz = wrap_clamp(iz, depth);
break;
}
return read(data[ix + iy*width + iz*width*height]);
@ -269,7 +297,8 @@ template<typename T> struct texture_image {
float ty = frac(y*(float)height - 0.5f, &iy);
float tz = frac(z*(float)depth - 0.5f, &iz);
if(extension == EXTENSION_REPEAT) {
switch(extension) {
case EXTENSION_REPEAT:
ix = wrap_periodic(ix, width);
iy = wrap_periodic(iy, height);
iz = wrap_periodic(iz, depth);
@ -277,8 +306,13 @@ template<typename T> struct texture_image {
nix = wrap_periodic(ix+1, width);
niy = wrap_periodic(iy+1, height);
niz = wrap_periodic(iz+1, depth);
break;
case EXTENSION_CLIP:
if (ix < 0 || iy < 0 || ix >= width || iy >= height) {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
else {
/* Fall through. */
case EXTENSION_EXTEND:
ix = wrap_clamp(ix, width);
iy = wrap_clamp(iy, height);
iz = wrap_clamp(iz, depth);
@ -286,6 +320,7 @@ template<typename T> struct texture_image {
nix = wrap_clamp(ix+1, width);
niy = wrap_clamp(iy+1, height);
niz = wrap_clamp(iz+1, depth);
break;
}
float4 r;
@ -309,7 +344,8 @@ template<typename T> struct texture_image {
const float tz = frac(z*(float)depth - 0.5f, &iz);
int pix, piy, piz, nnix, nniy, nniz;
if(extension == EXTENSION_REPEAT) {
switch(extension) {
case EXTENSION_REPEAT:
ix = wrap_periodic(ix, width);
iy = wrap_periodic(iy, height);
iz = wrap_periodic(iz, depth);
@ -325,8 +361,13 @@ template<typename T> struct texture_image {
nnix = wrap_periodic(ix+2, width);
nniy = wrap_periodic(iy+2, height);
nniz = wrap_periodic(iz+2, depth);
break;
case EXTENSION_CLIP:
if (ix < 0 || iy < 0 || ix >= width || iy >= height) {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
else {
/* Fall through. */
case EXTENSION_EXTEND:
ix = wrap_clamp(ix, width);
iy = wrap_clamp(iy, height);
iz = wrap_clamp(iz, depth);
@ -342,6 +383,7 @@ template<typename T> struct texture_image {
nnix = wrap_clamp(ix+2, width);
nniy = wrap_clamp(iy+2, height);
nniz = wrap_clamp(iz+2, depth);
break;
}
const int xc[4] = {pix, ix, nix, nnix};

@ -379,11 +379,17 @@ void ImageTextureNode::compile(OSLCompiler& compiler)
break;
}
if (extension == EXTENSION_REPEAT) {
compiler.parameter("wrap", "periodic");
}
else {
switch(extension) {
case EXTENSION_EXTEND:
compiler.parameter("wrap", "clamp");
break;
case EXTENSION_CLIP:
compiler.parameter("wrap", "black");
break;
case EXTENSION_REPEAT:
default:
compiler.parameter("wrap", "periodic");
break;
}
compiler.add(this, "node_image_texture");

@ -479,6 +479,8 @@ enum ExtensionType {
EXTENSION_REPEAT = 0,
/* Extend by repeating edge pixels of the image. */
EXTENSION_EXTEND = 1,
/* Clip to image size and set exterior pixels as transparent. */
EXTENSION_CLIP = 2,
};
/* macros */