0
\$\begingroup\$

I want to implement a mipmap filter in my 3D game, so that textures which are located far away are using a lower resolution than the original. For the shader I'm using hlsl version 4_0_level_9_1 or 4_0 depends on which one I will get this running. I have tried this:

texture Texture;
sampler diffuseSampler = sampler_state
{
    Texture = (Texture);
    MAGFILTER = ANISOTROPIC;
    MINFILTER = ANISOTROPIC;
    MIPFILTER = ANISOTROPIC;
    AddressU = Wrap;
    AddressV = Wrap;
};
[...]
Color PixelShaderFunctionTex(VertexShaderOutputTex input)
{
    return tex2Dlod(diffuseSampler, float4(input.TexCoord, 0.0, 0.0));
}

in vs_4_0 it still uses the full-res texture. And in vs_4_0_level_9_1 it won't even compile: "texlod not supported on this target"

I could manually generate the downscaled textures, but there must be a way to only input one texture and let hlsl do the rest.

In short: How to apply the mipmap filter in hlsl?

\$\endgroup\$
  • \$\begingroup\$ tex2dlod is for accessing a specific level of the mipmap chain. You just use standard tex2d with the correct texture state objects set and you'll get mipmap filtering. As noted below, the sampler state you define in HLSL is not relevant to the vs profiles only fx. \$\endgroup\$ – Chuck Walbourn Oct 31 '16 at 7:07
2
\$\begingroup\$

You don't.

Unfortunately some online resources don't make this explicit, but the code you've given is actually not HLSL; instead it's part of the old (and deprecated) effects framework. What actually happens if you use the effects framework (which is nothing more than a wrapper around the D3D API) is that a shader object and a state object will be created and set for the current draw call.

In the absence of the effects framework (which I assume because you actually have to intentionally set out to use it these days) you need to create your own sampler state object and set it.

\$\endgroup\$
  • 1
    \$\begingroup\$ See this post for some more background here. \$\endgroup\$ – Chuck Walbourn Oct 31 '16 at 7:06
1
\$\begingroup\$

That there is DX9 HLSL

You want something like this:

Texture2D Texture : register(t0);;
sampler diffuseSampler : register(s0);

struct VertexShaderOutput
{
float4 Position : SV_Position;
float2 TexCoord : TEXCOORD0;

};
// outputs a full screen triangle with screen-space coordinates
// input: three empty vertices
VertexShaderOutput VSQuad( uint vertexID : SV_VertexID )
{
VertexShaderOutput result;
result.TexCoord = float2((vertexID << 1) & 2, vertexID & 2);
result.Position  = float4(result.TexCoord  * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);
return result;
}

float4 PixelShaderFunctionTex(VertexShaderOutput input) :SV_Target0
{
// float3(UV,Mip)
float4 color = Texture.SampleLevel(diffuseSampler, float3(input.TexCoord, 0.0f));

return color;
}

then like Le Comte du Merde-fou said, set all state by hand.

like this:

  _Context.XXXXShader.SetSampler(0, yourSampler)
  _Context.XXXXShader.SetShaderResource(0, yourSRV)

ps. that's sm 5.0 but I think sm 4.0- m 5.0 is close if not the same and you wont need the vertex shader, that's just a bonus incase u want a cool way of doing full screen quads too.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.