Quantcast
Channel: GameDev.net
Viewing all articles
Browse latest Browse all 17560

Linear Sampler for Texture3D

$
0
0

Hey Guys,

 

Does anyone know how linear sampler works behind the scene? especially when sampling a Texture3D object. Is it fetching 8 texels and interpolate the result? MSDN only says D3D12_FILTER_TYPE_LINEAR will return "the weighter average of a 2x2 area of texels surrounding the desired pixel" which is not super clear to me.

 

I tried to render a surface by raycasting through a TSDF volume (Texture3D), point sampler and my own linear 'sampler' (point sample 8 nearest voxels then interpolate) gives expected result without artifacts, while LinearSampler and AnisotropicSampler runs faster but generate artifacts(see attachments PointSampler, ManualSampler(trilinear interpolation), LinearSampler).

PointSample.PNG ManualLinearSample.PNG LinearSample.PNG

 

also here is the most obvious one:

artifactPattern.PNG

 

It looks clearly that this artifact related to raycast step size, but why point sampler and manual interpolation don't have this artifact? In fact I double checked, even if I make my ray cast step 10x smaller, the artifact still exist (even worse). 

Also another MSDN page at the bottom part states:

 

 

During texture sampling, one or more texels are read and combined (this is calling filtering) to produce a single value. Point sampling reads a single texel while linear sampling reads two texels (endpoints) and linearly interpolates a third value between the endpoints.

So it seems samplers will never do 8 texels fetches for correct trilinear interpolation on Texture3D? (anyone?)

 

in case there are any problems in my manual interpolation I pasted it here:

// f3Idx range (0,0,0) - (resolution.x, resolution.y, resolution.z)
float readVolume(float3 f3Idx)
{
    int3 i3Idx000;
    float3 f3d = modf(f3Idx, i3Idx000) - 0.5f;
#if FILTER_READ == 1
    float fV000 = tex_srvTSDFVol[BUFFER_INDEX(i3Idx000)];
    float fV001 = tex_srvTSDFVol[BUFFER_INDEX(i3Idx000 + uint3(0, 0, 1))];
    float fV010 = tex_srvTSDFVol[BUFFER_INDEX(i3Idx000 + uint3(0, 1, 0))];
    float fV011 = tex_srvTSDFVol[BUFFER_INDEX(i3Idx000 + uint3(0, 1, 1))];
    float fV100 = tex_srvTSDFVol[BUFFER_INDEX(i3Idx000 + uint3(1, 0, 0))];
    float fV101 = tex_srvTSDFVol[BUFFER_INDEX(i3Idx000 + uint3(1, 0, 1))];
    float fV110 = tex_srvTSDFVol[BUFFER_INDEX(i3Idx000 + uint3(1, 1, 0))];
    float fV111 = tex_srvTSDFVol[BUFFER_INDEX(i3Idx000 + uint3(1, 1, 1))];
    return fV000 * (1.f - f3d.x) * (1.f - f3d.y) * (1.f - f3d.z) +
        fV100 * f3d.x * (1.f - f3d.y) * (1.f - f3d.z) +
        fV010 * (1.f - f3d.x) * f3d.y * (1.f - f3d.z) +
        fV001 * (1.f - f3d.x) * (1.f - f3d.y) * f3d.z +
        fV101 * f3d.x * (1.f - f3d.y) * f3d.z +
        fV011 * (1.f - f3d.x) * f3d.y * f3d.z +
        fV110 * f3d.x * f3d.y * (1.f - f3d.z) +
        fV111 * f3d.x * f3d.y * f3d.z;
#elif TEX3D_UAV && FILTER_READ == 2
    return tex_srvTSDFVol.SampleLevel(
        samp_Linear, f3Idx / vParam.u3VoxelReso, 0);
#elif TEX3D_UAV && FILTER_READ == 3
    return tex_srvTSDFVol.SampleLevel(
        samp_Aniso, f3Idx / vParam.u3VoxelReso, 0);
#else
    return tex_srvTSDFVol[BUFFER_INDEX(i3Idx000)];
#endif // !FILTER_READ
} 

So I think I probably need more information to dig into it. Also if anyone knows there exist better ways to do Volume interpolated read, please yell at me.

 

Thanks


Viewing all articles
Browse latest Browse all 17560

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>