I am doing tricubic interpolation of a volume texture. The result is much smoother than nearest neighbor interpolation, but there are artifacts along gradients in the image. I'm in Direct3D 9 and SlimDX, with Shader Model 3. I am pretty sure I am taking into account the half pixel shift between pixel coordinates and texel coordinates. Any ideas? I've posted the code as well. You can assume the pixel shader calls tricubic_naive and returns the result.
EDIT: I Should have mentioned also that the dimensions of the volume are not the same. The volume is 512x512x87. This is a slice in the y-z plane, and similar artifacts occur in the x-z plane. However, the x-y plane is fine.

float cubic_interpolate_onedim(float4 p, float i)
{
//Bezier cubic interpolation
float om = 1.0-i;
return om*om*om*p.x + 3*om*om*i*p.y + 3*om*i*i*p.z + i*i*i*p.w;
}
float4 cubic_interpolate(float4x4 pixels, float interpolant) {
pixels = transpose(pixels);
float grayVal = cubic_interpolate_onedim(pixels[0],interpolant);
return float4(grayVal,//r
grayVal,//g
grayVal,//b
1);//a
}
float4 xInt(sampler3D tex, float x, float y, float z, float3 incs,float3 interpolants)
{
float dx = incs.x;
float4x4 row = float4x4(tex3D(tex, float3(x, y,z)),
tex3D(tex, float3(x+dx, y,z)),
tex3D(tex, float3(x+dx+dx, y,z)),
tex3D(tex, float3(x+dx+dx+dx, y,z)));
return cubic_interpolate(row, interpolants.x);
}
float4 yInt(sampler3D tex, float x, float y, float z, float3 incs,float3 interpolants)
{
float dy = incs.y;
float4 r0 = xInt(tex,x,y ,z,incs,interpolants);
float4 r1 = xInt(tex,x,y+dy ,z,incs,interpolants);
float4 r2 = xInt(tex,x,y+dy+dy ,z,incs,interpolants);
float4 r3 = xInt(tex,x,y+dy+dy+dy ,z,incs,interpolants);
return cubic_interpolate(float4x4(r0,r1,r2,r3),interpolants.y);
}
float4 zInt(sampler3D tex, float x, float y, float z, float3 incs,float3 interpolants)
{
float dz = incs.z;
float4 r0 = yInt(tex,x,y,z ,incs,interpolants);
float4 r1 = yInt(tex,x,y,z+dz ,incs,interpolants);
float4 r2 = yInt(tex,x,y,z+dz+dz ,incs,interpolants);
float4 r3 = yInt(tex,x,y,z+dz+dz+dz ,incs,interpolants);
return cubic_interpolate(float4x4(r0,r1,r2,r3),interpolants.z);
}
float4 tricubic_naive(sampler3D tex, float3 coord_grid, float3 size_grid)
{
float3 index = floor(coord_grid);
index -= float3(0.5,0.5,0.5);
float3 fraction = frac(coord_grid);
//interpolants should be [0..1]
float3 interpolants = (float3(1.0,1.0,1.0) + fraction)/3;
//bc = bottom corner
float3 bc = index/size_grid;
float3 incs = float3(1.0/size_grid.x,
1.0/size_grid.y,
1.0/size_grid.z);
return zInt(tex,bc.x,bc.y,bc.z,incs,interpolants);
}
Edited by rtclawson, 01 March 2013 - 10:33 AM.






