   [HLSL] [DX11] 3D texture trilinear interpolation
  Hi all, I'm playing with a compute-shader-implemented raycaster right now and have some questions on trilinear interpolation. First, I know a lot of hardware supports trilinear interpolation, and I'm using a sampler state which includes D3D11_FILTER_MIN_MAG_MIP_LINEAR in the sampler desc. The result, however, does not look very interpolated. Zoomed out, you can't really tell:But you get closer and can see very stark edges, which are usually the product of no interpolation.So i tried to do manual trilinear interpolation in hlsl, and ended up with an even worse result:The code i'm using is:float TrilinearInterpolatedSample( float3 SampleUVW ){// find closest actual voxels (g_vDim is the size of the volume, delta is 1/g_vDim)float3 negdelta = floor(SampleUVW*g_vDim)*delta;float3 posdelta = ceil(SampleUVW*g_vDim)*delta;// get the cornersfloat3 c000 = SampleUVW + float3(negdelta.x,negdelta.y,negdelta.z);float3 c001 = SampleUVW + float3(negdelta.x,negdelta.y,posdelta.z);float3 c010 = SampleUVW + float3(negdelta.x,posdelta.y,negdelta.z);float3 c011 = SampleUVW + float3(negdelta.x,posdelta.y,posdelta.z);float3 c100 = SampleUVW + float3(posdelta.x,negdelta.y,negdelta.z);float3 c101 = SampleUVW + float3(posdelta.x,negdelta.y,posdelta.z);float3 c110 = SampleUVW + float3(posdelta.x,posdelta.y,negdelta.z);float3 c111 = SampleUVW + float3(posdelta.x,posdelta.y,posdelta.z);float3 weights = frac(SampleUVW*g_vDim);float trilinearTaps[] = {t3dVolume.SampleLevel(samLinear,c000,0),t3dVolume.SampleLevel(samLinear,c001,0),t3dVolume.SampleLevel(samLinear,c010,0),t3dVolume.SampleLevel(samLinear,c011,0),t3dVolume.SampleLevel(samLinear,c100,0),t3dVolume.SampleLevel(samLinear,c101,0),t3dVolume.SampleLevel(samLinear,c110,0),t3dVolume.SampleLevel(samLinear,c111,0)};float result =lerp(lerp(lerp(trilinearTaps[0],trilinearTaps[1],weights.z),lerp(trilinearTaps[2],trilinearTaps[3],weights.z),weights.y),lerp(lerp(trilinearTaps[4],trilinearTaps[5],weights.z),lerp(trilinearTaps[6],trilinearTaps[7],weights.z),weights.y),weights.x);return result;}So my questions are:Am I correctly using hardware interpolation in the first screenshots? If so, why am i still getting these artifacts?Can anyone tell me why I'm getting such a bad result with the manual interpolation? What am i doing wrong here? Thanks!   
  Basically linear filtering works is it un-normalizes your texture coordinate (converts to the range [0, TexSize]) and uses the fractional portion of X and Y to determine how much to lerp with between the texel and the next texel over. So if you pick your coordinates such that they always hit exactly on a texel, your results are going to look exactly like point filtering. Same goes for mip interpolation...using a mip level of 0 means you're always going to sample only the largest mip level.   ;  The errors in your second image look to me more like precision problems.  My guess is depth precision areas.  You may have to tighten up your frustum, or make some change to maintain higher precision values.  There are a number of resource available on how to improve this.  There's one on shadows from a GameDev magazine a few months back.  Your picture has artifacts almost exactly like theirs.   ;Quote:Original post by MJPBasically linear filtering works is it un-normalizes your texture coordinate (converts to the range [0, TexSize]) and uses the fractional portion of X and Y to determine how much to lerp with between the texel and the next texel over. So if you pick your coordinates such that they always hit exactly on a texel, your results are going to look exactly like point filtering. Yea that's what I was trying to implement with the manual function. I pick the texel and use frac() to find the fractional portions, an interpolate with those weights.If hardware already does interpolation this way, then why am I getting those edges? Shouldn't the interpolation guarantee a smooth sample and not these slices in between?;Quote:Original post by DieterVWThe errors in your second image look to me more like precision problems.  My guess is depth precision areas.  You may have to tighten up your frustum, or make some change to maintain higher precision values.  There are a number of resource available on how to improve this.  There's one on shadows from a GameDev magazine a few months back.  Your picture has artifacts almost exactly like theirs.I'll try to find that resource, thanks!   ;  Found the article you mentioned, DieterVW. "Rendering geometries at the near clip plane is analogous to rolling a coin along a razor's edge; the coin can drop down both sides easily." This makes sense, interpolation precision can only go so far.Tried upping the precision by using doubles, but that made things go EXTREMELY slow (ATI 5870 here) and didn't even improve the result. Texture3D::SampleLevel takes as input a float, so in passing the higher-precision sample location, it gets casted to a float. I suppose this is as good as it will get, which isn't bad at all (unless i get the manual trilinear interpolation working with doubles, in which case I'd be glad to share the code for anyone in need of high-precision interpolation).Any ideas as far as why the manual trilinear interpolation function is giving me such wrong results?   ;  The fix won't be converting to doubles.  Though doubles do provide more precision, they still have the same problem and as you've noted, it's pretty damn slow.  Also, most graphics hardware flushes float32 denorms to zero, though I doubt that is the problem here.Read: A Matter of PrecisionOne of the Game Programming Gems books has a solution.  I don't have my books on me but it should be one or more of the following.  You can probably modify their solution for your needs if it comes to that.GameGems4 : Solving Accuracy Problems in Large World CoordinatesGameGems6 : Geographic Grid Registration of Game ObjectsGameGems7 : Using Projective Space to Improve Precision of Geometric Computations   