2
\$\begingroup\$

When we sample a texture resource through an SSO in HLSL, how is the mip level selected for sampling; assuming the texture resource contains mips?

The SSO has parameters that seem to be concerned with the sampling method, but I can't find any documentation anywhere that states how to actually select a mip level.

Or is it done automatically as a function of the NDC depth value?

Thanks.

\$\endgroup\$

3 Answers 3

4
\$\begingroup\$

When using the standard Sample method, the automatic MIP level selection is actually quite complex. Assuming standard tri-linear sampling of a 2D texture, two MIP levels are actually sampled. The hardware determines which ones by looking at the texture coordinate arguments of four adjacent pixel shader invocations (referred to as a "quad"), and calculates the difference in u and v coordinates. The two MIP levels that are selected are the ones such that the average delta in u and v equate to just over one texel (the coarser level), and the one that the delta equates to just under one texel (the finer level). Using the uv coordinates at those two MIP levels, the hardware interpolates between the 8 texels to produce the final output color.

This works well for most cases, but if you have a surface that is nearly parallel to the direction of the camera, the difference between the u and v deltas is actually quite large, so tri-linear sampling can make things look blurry. This is where anisotropic filtering comes in, which uses a much more complicated formula for choosing the MIP levels.

\$\endgroup\$
1
\$\begingroup\$

You can use SampleLevel to manually select the mip level. The 3rd parameter specifies the mip level.

Documentation here.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Yes, SampleLevel allows you to pick the MIP level manually, but that doesn't answer the original question, which seems to be asking how automatic MIP level selection works. Also, SampleLevel is usually a bad idea unless you know what you're doing. \$\endgroup\$
    – MooseBoys
    Oct 3, 2014 at 0:25
0
\$\begingroup\$

This answer is for selecting a mip level in Direct3D 9 and beyond.

Direct3D 11 has a lot to offer in selecting the mip level.

However, in Direct3D9, which a lot of us still use due to the wide range of platforms it is supported, the trick was to use the

SetSamplerState(Index, D3DSAMP_MIPMAPLODBIAS, PCardinal(@Value)^);

and

SetSamplerState(Index, D3DSAMP_MAXMIPLEVEL, PCardinal(@Value)^); 

(the above is in Delphi/Object Pascal notation, but is easy to see how it would be in C++)

Say for example you want to use only the 3rd mip level. You should execute:

SetSamplerState(Index, D3DSAMP_MAXMIPLEVEL, 3); 

SetSamplerState(Index, D3DSAMP_MIPMAPLODBIAS, -1000);

The above forces the max mip level to 3 (instead of 0), and then forces the bias to -1000 so that level 3 is always selected.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .