Search code examples
shaderhlslpixel-shader

Tex2D returns interpolated values when off pixel center in HLSL


The Tex2D function returns interpolated values when off pixel center ((0.5, 0.5) for instance), this is really a problem when you have a large texture like 1920x1080.

I have an HLSL pixel shader that first samples a small image, then calculates the corresponding pixel in a large lookup table (1920x1080) and samples it. The problem is that the floating point precision errors makes it impossible to hit a pixel dead center, so it returns a color that is interpolated with the neighboring pixels.

How can I overcome this issue? Can I set it to not interpolate in the sampler?

Edit:

Apparently I can use the intrinsic function tex2Dproj where I divide my x and y coordinates by 1.92 and 1.08 beforehand and then pass in 1000 as the t.w argument to avoid any significant floating point precision errors. But it seems weird that I should have to do that.


Solution

  • The default value for a sampler filter is LINEAR making it interpolate. To make a texture sample without interpolating you need to do this:

    texture2D ColorMap;
    sampler2D ColorMapSampler = sampler_state
    {
        texture = <ShadowMap>;
        AddressU = clamp;
        AddressV = clamp;
        magfilter = POINT;
        minfilter = POINT;
        mipfilter = POINT;
    };
    

    What tripped me up was that I only had this problem with this texture. I'm using MonoGame and was setting the SamplerState to PointClamp outside the shader, but only for the first texture GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;. If you have multiple textures it's a better idea to declare it explicitly for each texture in the shader.