HLSL - How can I set sampler Min/Mag/Mip filters to disable all filtering/anti-aliasing?

StackOverflow https://stackoverflow.com/questions/2700041

  •  01-10-2019
  •  | 
  •  

문제

I have a tex2D sampler I want to only return precisely those colours that are present on my texture. I am using Shader Model 3, so cannot use load.

In the event of a texel overlapping multiple colours, I want it to pick one and have the whole texel be that colour.

I think to do this I want to disable mipmapping, or at least trilinear filtering of mips.

sampler2D gColourmapSampler : register(s0) = sampler_state {
    Texture = <gColourmapTexture>; //Defined above
    MinFilter = None; //Controls sampling. None, Linear, or Point.
    MagFilter = None; //Controls sampling. None, Linear, or Point.
    MipFilter = None; //Controls how the mips are generated. None, Linear, or Point.
    //...
};

My problem is I don't really understand Min/Mag/Mip filtering, so am not sure what combination I need to set these in, or if this is even what I am after.

What a portion of my source texture looks like;
http://img689.imageshack.us/img689/6171/sourcev.png

Screenshot of what the relevant area looks like after the full texture is mapped to my sphere;
http://img717.imageshack.us/img717/9202/resultc.png
The anti-aliasing/blending/filtering artefacts are clearly visible; I don't want these.


MSDN has this to say;

D3DSAMP_MAGFILTER: Magnification filter of type D3DTEXTUREFILTERTYPE

D3DSAMP_MINFILTER: Minification filter of type D3DTEXTUREFILTERTYPE.

D3DSAMP_MIPFILTER: Mipmap filter to use during minification. See D3DTEXTUREFILTERTYPE.

D3DTEXF_NONE: When used with D3DSAMP_MIPFILTER, disables mipmapping.

Another good link on understanding hlsl intrinsics.


RESOLVED

Not an HLSL issue at all! Sorry all. I seem to ask a lot of questions that are impossible to answer. Ogre was over-riding the above settings. This was fixed with;

Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(Ogre::FO_NONE , Ogre::FO_NONE, Ogre::FO_NONE);
도움이 되었습니까?

해결책

What it looks to me is that you're getting the values from a lower level mip-map (unfiltered) than the highest detail you're showing.

MipFilter = None 

should prevent that, unless something in the code overrides it. So look for calls to SetSamplerState.

다른 팁

What you have done should turn off filtering. There are 2 potential issues, that I can think of, though

1) The driver just ignores you and filters anyway (If this is happening there is nothing you can do) 2) You have some form of edge anti-aliasing enabled.

Looking at your resulting image that doesn't look much like bilinear filtering to me so I'd think you are suffering from having antialiasing turned on somewhere. Have you set the antialiasing flag when you create the device/render-texture?

If you want to have really just one texel, use load instead of sample. load takes (as far as i know) an int2as an argument, that specifies the actual array coordinates in the texture. load looks then up the entry in your texture at the given array coordinates.

So, just scale your float2, e.g. by using ceil(float2(texCoord.x*textureWidth, texCoord.y*textureHeight)).

MSDN for load: http://msdn.microsoft.com/en-us/library/bb509694(VS.85).aspx

When using just shader model 3, you could a little hack to achieve this: Again, let's assume that you know textureWidth and textureHeight.

// compute floating point stride for texture
float step_x = 1./textureWidth;
float step_y = 1./textureHeight;

// compute texel array coordinates
int target_x = texCoord.x * textureWidth;
int target_y = texCoord.y * textureHeight;

// round to values, such that they're multiples of step_x and step_y
float2 texCoordNew;
texCoordNew.x = target_x * step_x;
texCoordNew.y = target_y * step_y;

I did not test it, but I think it could work.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top