How to enable/disable mipmapping with each SpriteBatch call?

I’m working on a 2D game where I’d like to use mipmapping while drawing textures in the game world, but turn off mipmapping while drawing the same textures in other places. Is there a way to force SpriteBatch to not use mipmapping at certain times?

Run two variations of the batch?

1 Like

I can’t find anything in the batch to enable/disable mipmapping. The only solution I’ve come up with is to have two copies of the texture in my content manager: one that has mipmapping enabled and another that doesn’t. It seems SpriteBatch automatically uses mipmapping if it’s enabled via the content manager.

1 Like

Not sure if it works or is what will help here but I leave it here so you can check if this is a solution:

You could use the texture with mipmaps and in the case when you don‘t want mipmaping or a specific mip level you could use a custom effect which samples the texture using the hlsl tex2Dlod function.

2 Likes

afaik MipMapping is configured by the TextureSampler used in the shader - never did that tho and no idea if you can achieve that by setting samplerstates outside of shader for SpriteBatch.

But you could also add them twice to content and enable mipmap for the one but not the other. Wont matter for performance I guess, as it’s a statechange either way

1 Like

Any modern api can set min/max mipmap level for sampler state, setting minLod = maxLod will force given level being used. Whether MG exposes it, that’s other question, simply create own SamplerState and you will know right away. Alternatively as mentioned above, you can specify mipmap in shader.

Two texture copies is generally worst as it will have by far worst memory footprint from all proposed solutions.

3 Likes

Hey everyone, thanks to your replies I ended up trying this:

SamplerState linearClampNoMipMap = SamplerState.LinearClamp;
linearClampNoMipMap.MaxMipLevel = -1;

spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, linearClampNoMipMap, DepthStencilState.Default);

It seems the MaxMipLevel defaults to 0… which I thought was the min value for this? Anyway, I tried -1 and it still didn’t turn it off. What value should I be using for this?

1 Like

Ok, unless someone sees an issue with this I think I’ve found a solution.

Unfortunately, SamplerState only provides access to MaxMipLevel, and like @Ravendarke said, I need to set the MinMipLevel to MaxMipLevel. However, SamplerState does provide access to another variable called MipMapLevelOfDetailBias.

From what I understand, an LOD of 0 means the shader will use the texture’s highest resolution. The MipMapLevelOfDetailBias will be applied to whatever LOD the shader uses, so if we have a large enough negative value it will force the shader to always use LOD 0.

Here’s my final code:

    class CustomSamplerStates
    {
        public static SamplerState LinearClampNoMipmap { get; private set; }
        public static SamplerState LinearWrapNoMipmap { get; private set; }

        static CustomSamplerStates()
	    {
            LinearClampNoMipmap = new SamplerState();
            LinearClampNoMipmap.AddressU = TextureAddressMode.Clamp;
            LinearClampNoMipmap.AddressV = TextureAddressMode.Clamp;
            LinearClampNoMipmap.AddressW = TextureAddressMode.Clamp;
            LinearClampNoMipmap.Filter = TextureFilter.Linear;
            LinearClampNoMipmap.MipMapLevelOfDetailBias = -16;

            LinearWrapNoMipmap = new SamplerState();
            LinearWrapNoMipmap.AddressU = TextureAddressMode.Wrap;
            LinearWrapNoMipmap.AddressV = TextureAddressMode.Wrap;
            LinearWrapNoMipmap.AddressW = TextureAddressMode.Wrap;
            LinearWrapNoMipmap.Filter = TextureFilter.Linear;
            LinearWrapNoMipmap.MipMapLevelOfDetailBias = -16;
        }
    }

spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, CustomSamplerStates.LinearClampNoMipmap, DepthStencilState.Default);

The only thing I don’t understand is why -16 is the lowest value. I guess the LOD goes from 0 - 16?

Also, here’s a post that helped me learn about the bias: https://www.3dgep.com/learning-directx-12-4/#Mipmap_LOD_Levels

2 Likes

I don‘t know where the limit exactly comes from but using -16 as bias will probably be enough to sample the largest possible textures at level 0. Maybe this is where the limit comes from since smaller bias values are not necessary?

1 Like