Fix cycles texture interpolation mode closest constant offset on some devices

This commit is contained in:
Martijn Berger
2014-03-13 20:08:10 +01:00
parent 4080673ea7
commit a8039d99f8
2 changed files with 60 additions and 37 deletions

View File

@@ -99,28 +99,38 @@ template<typename T> struct texture_image {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
int ix, iy, nix, niy;
float tx = frac(x*width - 0.5f, &ix);
float ty = frac(y*height - 0.5f, &iy);
if(periodic) {
ix = wrap_periodic(ix, width);
iy = wrap_periodic(iy, height);
nix = wrap_periodic(ix+1, width);
niy = wrap_periodic(iy+1, height);
}
else {
ix = wrap_clamp(ix, width);
iy = wrap_clamp(iy, height);
nix = wrap_clamp(ix+1, width);
niy = wrap_clamp(iy+1, height);
}
if(interpolation == INTERPOLATION_CLOSEST) {
frac(x*width, &ix);
frac(y*height, &iy);
if(periodic) {
ix = wrap_periodic(ix, width);
iy = wrap_periodic(iy, height);
}
else {
ix = wrap_clamp(ix, width);
iy = wrap_clamp(iy, height);
}
return read(data[ix + iy*width]);
}
else {
float tx = frac(x*width - 0.5f, &ix);
float ty = frac(y*height - 0.5f, &iy);
if(periodic) {
ix = wrap_periodic(ix, width);
iy = wrap_periodic(iy, height);
nix = wrap_periodic(ix+1, width);
niy = wrap_periodic(iy+1, height);
}
else {
ix = wrap_clamp(ix, width);
iy = wrap_clamp(iy, height);
nix = wrap_clamp(ix+1, width);
niy = wrap_clamp(iy+1, height);
}
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]);

View File

@@ -63,30 +63,43 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y,
uint periodic = (info.w & 0x1);
uint interpolation = info.w >> 1;
int ix, iy, nix, niy;
float tx = svm_image_texture_frac(x*width, &ix);
float ty = svm_image_texture_frac(y*height, &iy);
if(periodic) {
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);
}
else {
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);
}
float4 r;
int ix, iy, nix, niy;
if (interpolation == INTERPOLATION_CLOSEST){
svm_image_texture_frac(x*width, &ix);
svm_image_texture_frac(y*height, &iy);
if(periodic) {
ix = svm_image_texture_wrap_periodic(ix, width);
iy = svm_image_texture_wrap_periodic(iy, height);
}
else {
ix = svm_image_texture_wrap_clamp(ix, width);
iy = svm_image_texture_wrap_clamp(iy, height);
}
r = svm_image_texture_read(kg, offset + ix + iy*width);
}
else { /* We default to linear interpolation if it is not closest */
float tx = svm_image_texture_frac(x*width, &ix);
float ty = svm_image_texture_frac(y*height, &iy);
if(periodic) {
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);
}
else {
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, offset + ix + iy*width);
r += (1.0f - ty)*tx*svm_image_texture_read(kg, offset + nix + iy*width);
r += ty*(1.0f - tx)*svm_image_texture_read(kg, offset + ix + niy*width);