Cycles: Add implementation of clip extension mode
For now there's no OpenCL support, it'll come later.
This commit is contained in:
@@ -513,13 +513,19 @@ public:
|
|||||||
cuda_assert(cuTexRefSetFlags(texref, CU_TRSF_READ_AS_INTEGER));
|
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, 0, CU_TR_ADDRESS_MODE_WRAP));
|
||||||
cuda_assert(cuTexRefSetAddressMode(texref, 1, CU_TR_ADDRESS_MODE_WRAP));
|
cuda_assert(cuTexRefSetAddressMode(texref, 1, CU_TR_ADDRESS_MODE_WRAP));
|
||||||
}
|
break;
|
||||||
else {
|
case EXTENSION_EXTEND:
|
||||||
cuda_assert(cuTexRefSetAddressMode(texref, 0, CU_TR_ADDRESS_MODE_CLAMP));
|
cuda_assert(cuTexRefSetAddressMode(texref, 0, CU_TR_ADDRESS_MODE_CLAMP));
|
||||||
cuda_assert(cuTexRefSetAddressMode(texref, 1, 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));
|
cuda_assert(cuTexRefSetFormat(texref, format, mem.data_elements));
|
||||||
|
|
||||||
|
@@ -138,14 +138,20 @@ template<typename T> struct texture_image {
|
|||||||
if(interpolation == INTERPOLATION_CLOSEST) {
|
if(interpolation == INTERPOLATION_CLOSEST) {
|
||||||
frac(x*(float)width, &ix);
|
frac(x*(float)width, &ix);
|
||||||
frac(y*(float)height, &iy);
|
frac(y*(float)height, &iy);
|
||||||
if(extension == EXTENSION_REPEAT) {
|
switch(extension) {
|
||||||
|
case EXTENSION_REPEAT:
|
||||||
ix = wrap_periodic(ix, width);
|
ix = wrap_periodic(ix, width);
|
||||||
iy = wrap_periodic(iy, height);
|
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);
|
ix = wrap_clamp(ix, width);
|
||||||
iy = wrap_clamp(iy, height);
|
iy = wrap_clamp(iy, height);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return read(data[ix + iy*width]);
|
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 tx = frac(x*(float)width - 0.5f, &ix);
|
||||||
float ty = frac(y*(float)height - 0.5f, &iy);
|
float ty = frac(y*(float)height - 0.5f, &iy);
|
||||||
|
|
||||||
if(extension == EXTENSION_REPEAT) {
|
switch(extension) {
|
||||||
|
case EXTENSION_REPEAT:
|
||||||
ix = wrap_periodic(ix, width);
|
ix = wrap_periodic(ix, width);
|
||||||
iy = wrap_periodic(iy, height);
|
iy = wrap_periodic(iy, height);
|
||||||
|
|
||||||
nix = wrap_periodic(ix+1, width);
|
nix = wrap_periodic(ix+1, width);
|
||||||
niy = wrap_periodic(iy+1, height);
|
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);
|
ix = wrap_clamp(ix, width);
|
||||||
iy = wrap_clamp(iy, height);
|
iy = wrap_clamp(iy, height);
|
||||||
|
|
||||||
nix = wrap_clamp(ix+1, width);
|
nix = wrap_clamp(ix+1, width);
|
||||||
niy = wrap_clamp(iy+1, height);
|
niy = wrap_clamp(iy+1, height);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 r = (1.0f - ty)*(1.0f - tx)*read(data[ix + iy*width]);
|
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;
|
return r;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Tricubic b-spline interpolation. */
|
/* Bicubic b-spline interpolation. */
|
||||||
const float tx = frac(x*(float)width - 0.5f, &ix);
|
const float tx = frac(x*(float)width - 0.5f, &ix);
|
||||||
const float ty = frac(y*(float)height - 0.5f, &iy);
|
const float ty = frac(y*(float)height - 0.5f, &iy);
|
||||||
int pix, piy, nnix, nniy;
|
int pix, piy, nnix, nniy;
|
||||||
if(extension == EXTENSION_REPEAT) {
|
switch(extension) {
|
||||||
|
case EXTENSION_REPEAT:
|
||||||
ix = wrap_periodic(ix, width);
|
ix = wrap_periodic(ix, width);
|
||||||
iy = wrap_periodic(iy, height);
|
iy = wrap_periodic(iy, height);
|
||||||
|
|
||||||
@@ -192,8 +206,13 @@ template<typename T> struct texture_image {
|
|||||||
|
|
||||||
nnix = wrap_periodic(ix+2, width);
|
nnix = wrap_periodic(ix+2, width);
|
||||||
nniy = wrap_periodic(iy+2, height);
|
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);
|
ix = wrap_clamp(ix, width);
|
||||||
iy = wrap_clamp(iy, height);
|
iy = wrap_clamp(iy, height);
|
||||||
|
|
||||||
@@ -205,7 +224,9 @@ template<typename T> struct texture_image {
|
|||||||
|
|
||||||
nnix = wrap_clamp(ix+2, width);
|
nnix = wrap_clamp(ix+2, width);
|
||||||
nniy = wrap_clamp(iy+2, height);
|
nniy = wrap_clamp(iy+2, height);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int xc[4] = {pix, ix, nix, nnix};
|
const int xc[4] = {pix, ix, nix, nnix};
|
||||||
const int yc[4] = {width * piy,
|
const int yc[4] = {width * piy,
|
||||||
width * iy,
|
width * iy,
|
||||||
@@ -251,15 +272,22 @@ template<typename T> struct texture_image {
|
|||||||
frac(y*(float)height, &iy);
|
frac(y*(float)height, &iy);
|
||||||
frac(z*(float)depth, &iz);
|
frac(z*(float)depth, &iz);
|
||||||
|
|
||||||
if(extension == EXTENSION_REPEAT) {
|
switch(extension) {
|
||||||
|
case EXTENSION_REPEAT:
|
||||||
ix = wrap_periodic(ix, width);
|
ix = wrap_periodic(ix, width);
|
||||||
iy = wrap_periodic(iy, height);
|
iy = wrap_periodic(iy, height);
|
||||||
iz = wrap_periodic(iz, depth);
|
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);
|
ix = wrap_clamp(ix, width);
|
||||||
iy = wrap_clamp(iy, height);
|
iy = wrap_clamp(iy, height);
|
||||||
iz = wrap_clamp(iz, depth);
|
iz = wrap_clamp(iz, depth);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return read(data[ix + iy*width + iz*width*height]);
|
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 ty = frac(y*(float)height - 0.5f, &iy);
|
||||||
float tz = frac(z*(float)depth - 0.5f, &iz);
|
float tz = frac(z*(float)depth - 0.5f, &iz);
|
||||||
|
|
||||||
if(extension == EXTENSION_REPEAT) {
|
switch(extension) {
|
||||||
|
case EXTENSION_REPEAT:
|
||||||
ix = wrap_periodic(ix, width);
|
ix = wrap_periodic(ix, width);
|
||||||
iy = wrap_periodic(iy, height);
|
iy = wrap_periodic(iy, height);
|
||||||
iz = wrap_periodic(iz, depth);
|
iz = wrap_periodic(iz, depth);
|
||||||
@@ -277,8 +306,13 @@ template<typename T> struct texture_image {
|
|||||||
nix = wrap_periodic(ix+1, width);
|
nix = wrap_periodic(ix+1, width);
|
||||||
niy = wrap_periodic(iy+1, height);
|
niy = wrap_periodic(iy+1, height);
|
||||||
niz = wrap_periodic(iz+1, depth);
|
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);
|
ix = wrap_clamp(ix, width);
|
||||||
iy = wrap_clamp(iy, height);
|
iy = wrap_clamp(iy, height);
|
||||||
iz = wrap_clamp(iz, depth);
|
iz = wrap_clamp(iz, depth);
|
||||||
@@ -286,6 +320,7 @@ template<typename T> struct texture_image {
|
|||||||
nix = wrap_clamp(ix+1, width);
|
nix = wrap_clamp(ix+1, width);
|
||||||
niy = wrap_clamp(iy+1, height);
|
niy = wrap_clamp(iy+1, height);
|
||||||
niz = wrap_clamp(iz+1, depth);
|
niz = wrap_clamp(iz+1, depth);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 r;
|
float4 r;
|
||||||
@@ -309,7 +344,8 @@ template<typename T> struct texture_image {
|
|||||||
const float tz = frac(z*(float)depth - 0.5f, &iz);
|
const float tz = frac(z*(float)depth - 0.5f, &iz);
|
||||||
int pix, piy, piz, nnix, nniy, nniz;
|
int pix, piy, piz, nnix, nniy, nniz;
|
||||||
|
|
||||||
if(extension == EXTENSION_REPEAT) {
|
switch(extension) {
|
||||||
|
case EXTENSION_REPEAT:
|
||||||
ix = wrap_periodic(ix, width);
|
ix = wrap_periodic(ix, width);
|
||||||
iy = wrap_periodic(iy, height);
|
iy = wrap_periodic(iy, height);
|
||||||
iz = wrap_periodic(iz, depth);
|
iz = wrap_periodic(iz, depth);
|
||||||
@@ -325,8 +361,13 @@ template<typename T> struct texture_image {
|
|||||||
nnix = wrap_periodic(ix+2, width);
|
nnix = wrap_periodic(ix+2, width);
|
||||||
nniy = wrap_periodic(iy+2, height);
|
nniy = wrap_periodic(iy+2, height);
|
||||||
nniz = wrap_periodic(iz+2, depth);
|
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);
|
ix = wrap_clamp(ix, width);
|
||||||
iy = wrap_clamp(iy, height);
|
iy = wrap_clamp(iy, height);
|
||||||
iz = wrap_clamp(iz, depth);
|
iz = wrap_clamp(iz, depth);
|
||||||
@@ -342,6 +383,7 @@ template<typename T> struct texture_image {
|
|||||||
nnix = wrap_clamp(ix+2, width);
|
nnix = wrap_clamp(ix+2, width);
|
||||||
nniy = wrap_clamp(iy+2, height);
|
nniy = wrap_clamp(iy+2, height);
|
||||||
nniz = wrap_clamp(iz+2, depth);
|
nniz = wrap_clamp(iz+2, depth);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int xc[4] = {pix, ix, nix, nnix};
|
const int xc[4] = {pix, ix, nix, nnix};
|
||||||
|
@@ -379,11 +379,17 @@ void ImageTextureNode::compile(OSLCompiler& compiler)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extension == EXTENSION_REPEAT) {
|
switch(extension) {
|
||||||
compiler.parameter("wrap", "periodic");
|
case EXTENSION_EXTEND:
|
||||||
}
|
|
||||||
else {
|
|
||||||
compiler.parameter("wrap", "clamp");
|
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");
|
compiler.add(this, "node_image_texture");
|
||||||
|
@@ -479,6 +479,8 @@ enum ExtensionType {
|
|||||||
EXTENSION_REPEAT = 0,
|
EXTENSION_REPEAT = 0,
|
||||||
/* Extend by repeating edge pixels of the image. */
|
/* Extend by repeating edge pixels of the image. */
|
||||||
EXTENSION_EXTEND = 1,
|
EXTENSION_EXTEND = 1,
|
||||||
|
/* Clip to image size and set exterior pixels as transparent. */
|
||||||
|
EXTENSION_CLIP = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* macros */
|
/* macros */
|
||||||
|
Reference in New Issue
Block a user