Moires patterns despite using mipmaps

I am working on Silverlight app. I am trying to render floor covered with tiles. Although I am using mip maps I am still getting awful Moire patterns, when trying to render big area.

What I am doing is creating cuboid and then cover it with single tile:

In my pixel shader I am multiplying texture coordinates in order to create tiled floor (otherwise I would get one tile stretched over my cuboid). Pixel shader code:

float Width                 : register(c3);                  //Width of cuboid
float Height                : register(c4);                  //Height of cuboid

texture texTexture;
sampler textureSampler  : register(s0) = sampler_state {
Texture = (texTexture);
};

struct VsOutput
{
float4 position : POSITION;
float3 dirLightPosition : COLOR;
float2 texCoord : TEXCOORD0;
float3 normal   : TEXCOORD1;
float3 view : TEXCOORD2;
};

float4 main(VsOutput IN) : COLOR
{
float2 texCoord = float2(IN.texCoord.x * Width / 4.0f,
IN.texCoord.y * Height / 4.0f); //multiplying texture coordinates

float4 texColor = tex2D(textureSampler, texCoord);

return float4(color.r, color.g, color.b, 1.0f);
}


My output is:

What else can I do to prevent from creating Moires patterns on texture?

• Have you verified that mipmaps are actually used? The screenshot looks like bilinear filtering, instead of trilinear, – Julien Guertault Oct 7 '15 at 13:47
• @JulienGuertault It may just be my poor eyesight but I can't see any distinct discontinuities that'd be indicative of just bilinear + nearest MIP map. – Simon F Oct 7 '15 at 13:57
• Actually my sampler state is set to AnisotropicWrap, which, I believe, is the best. Also I am 100% sure, that I use mipmaps. – bartosz.baczek Oct 7 '15 at 14:04
• @SimonF: sorry for the confusion, I meant linear. But anyway, apparently the problem would be elsewhere. – Julien Guertault Oct 7 '15 at 14:06
• @Nero I did so :) – bartosz.baczek Oct 9 '15 at 15:56

Two things come to mind:

1. When generating your smaller mip map levels try to avoid using a simple 2x2 box filter because, though cheap and cheerful, they do a really poor job of removing high frequency information (that exceeds the Nyquist limit) as well as over filtering some of the lower frequency information you need to keep. (Also, as an aside, you need to perform the MIP map generation in linear space. If your source data is sRGB, you thus need to map to and from linear). FWIW, In Williams' original paper on MIP mapping, he said he used a "box (Fourier) window" to generate the prefiltered levels, which would be a sinc function in image space.

2. Standard Trilinear filtering will also over- and under-filter parts of the texture. If you don't like the aliasing you may have to a) adjust the bias to increase the filtering (which will increase blurring) and/or b) try using anisotropic filtering.

• Sorry for maybe stupid question, but what is '2x2 box filter'? Does it have any other name? – bartosz.baczek Oct 7 '15 at 14:18
• I just meant the naive method of generating the next lower, X*Y MIP map level from the 2X * 2Y level above it. I.e. that of averaging 2x2 texels in the upper level to produce the corresponding texel in the lower one. It's cheap, but it's not great. Even a simple 4x4 tent filter should produce a far better result. – Simon F Oct 7 '15 at 14:25
• Just to make sure I fully understand you - now I am creating my mip maps like this: pastebin.com/nX1MVvEp . Instead of that i should generate mipmaps from my original texture with original size yes? – bartosz.baczek Oct 7 '15 at 14:34
• Well, I don't know what is inside the "resize" function so it's a little difficult to answer. The chaining, ie. 1024 generates 512, 512 generates 256, etc is not going to be a huge problem, as long as what's going on inside "resize" is ok. As an experiment, could you create a 1024^2 texture that's all 0xFFFFFF except for the top left pixel which you set to pure red, (0x0000FF). What do you get in the 512^2 result? – Simon F Oct 7 '15 at 14:47
• My result: postimg.org/image/atd8nc4j3/3636ad65 – bartosz.baczek Oct 7 '15 at 14:55

SOLUTION

I managed to solve my problem by increacing size of texture 2048x2048px so there would be generated more mipmaps. Also it seems like changing my SamplerState form anisotropic to something like that helped:

SamplerState MirrorTexCoord = new SamplerState()
{