microsoft / DirectXTK

The DirectX Tool Kit (aka DirectXTK) is a collection of helper classes for writing DirectX 11.x code in C++
https://walbourn.github.io/directxtk/
MIT License
2.57k stars 510 forks source link

Automatic mip map selection with SpriteBatch and Default Vertex/Pixel Shader #196

Closed BenBaron1985 closed 4 years ago

BenBaron1985 commented 4 years ago

Hi guys,

I am trying to work my way towards understanding the rendering pipeline with the help of DirectXTK...quite a long and rocky way, to be honest. I came so far as to being able to render different sprites from a spritesheet into a texture using SpriteBatch. But then, I came to notice that the sprites start to flicker as soon as the view moves away a certain distance from the object where the texture is rendered to. The spritesheet is created as ID3D11ShaderResourceView from a .dds file and it has 12 mip levels. But it seems they simply aren't being used, yet. At least, I created different colors for the different mip levels for testing and it is definitely only displaying level 0 regardless of the view's position to the object. I had the, maybe naive, impression this should work without employing a custom shader? But, maybe I do have to use one, if I want to use the correct mip levels? I've also already experimented by passing in a custom pixel shader but whatever I do it always comes down to either only mip level 0 being used employing the Texture.Sample() method or me setting a specific mip level directly via Texture.SampleLevel(). I am under the impression something crucial is missing for automatic mip map selection to work, but I really don't know what.

Maybe someone would be so kind to enlighten the mind of quite a novice in the jungle of rendering what might be the missing piece here. Would be highly appreciated.

Thanks very much in advance and all the best,

Benny

walbourn commented 4 years ago

The default sampler for SpriteBatch is the LinearClamp sampler from CommonStates. This does use D3D11_FILTER_MIN_MAG_MIP_LINEAR so technically it could use mips if present.

That said, the SpriteBatch class is optimized for 2D rendering, so mips are typically unused. Mips select is based on the depth. Are you providing a layerDepth?

BenBaron1985 commented 4 years ago

Thanks for the quick reply...no, I am not suppling any layerDepth, yet. But I was also wondering how the PixelShader normally selects the suitable mip level without any former handling by vertex shader or something to have some information about view distances, depth etc. You think supplying depth values might help? The thing is that I am rendering the sprites onto a texture which is provided by an external application. For this, from this application I am querying for a ID3D11RenderTargetView* that I can then use to clear and draw into so the final texture is being displayed on an object in the application. But this means I only have kind of limited access to the whole render pipeline.

walbourn commented 4 years ago

If you render using a traditional 3D pipeline (like say GeometricPrimitive or Model, then mips are automatically selected based on view depth. Again, this is done by the sampler being set to a mipmap filter mode and the texture resource itself having defined mip levels.