1
\$\begingroup\$

Copied from Computer Graphics SE.


I am implementing a post-processing effect in my DirectX 11 pet renderer. The post-processing pass is implemented by rendering a full-screen quad covered with texture containing original rendered image, which works as it should, but I have problems with downscaling the texture.

The non-processed testing scene looks like this (three very bright emmissive spheres):

enter image description here

I see no problem at this stage, but when I run the first post-processing pass, which just down-scales the image by the factor of 8 using the texture sampler, the result is very flickery (up-scaled for clarity):

enter image description here

I expected a mipmap would solve or at least reduce the flickering, but it didn't change a thing. What am I doing wrong?

RenderDoc Update

After investigating the issue using RenderDoc I found that the mipmap is being generated successfully and it's third level looks like this:

enter image description here

However, the output of the down-scaling pass looks like this:

enter image description here

As if the sampler didn't use the mipmap at all. Don't get distracted by coloured object instead almost white ones. I lowered the sphere brightness a bit while investigating the bug.

Even if I choose the mipmap level explicitly

float4 vColor = s0.SampleLevel(LinearSampler, Input.Tex, 3);

it changes nothing :-/

RenderDoc also says "LOD Clamp 0-0" for the used sampler. What is it? Couldn't this be the problem?

DirectX details

Samplers

D3D11_SAMPLER_DESC descSampler;
ZeroMemory(&descSampler, sizeof(descSampler));
descSampler.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
descSampler.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
descSampler.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;

descSampler.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
mDevice->CreateSamplerState(&descSampler, &mSamplerStateLinear);

descSampler.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
hr = mDevice->CreateSamplerState(&descSampler, &mSamplerStatePoint);

...are set right before rendering the screen quad

ID3D11SamplerState* aSamplers[] = { mSamplerStatePoint, mSamplerStateLinear };
mImmediateContext->PSSetSamplers(0, 2, aSamplers);

...and used within the down-scaling PS shader

SamplerState PointSampler  : register (s0);
SamplerState LinearSampler : register (s1);

Texture2D s0 : register(t0);

float4 Pass1PS(QUAD_VS_OUTPUT Input) : SV_TARGET
{
    return s0.Sample(LinearSampler, Input.Tex);
}

Texture

D3D11_TEXTURE2D_DESC descTex;
ZeroMemory(&descTex, sizeof(D3D11_TEXTURE2D_DESC));
descTex.ArraySize = 1;
descTex.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
descTex.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
descTex.Usage = D3D11_USAGE_DEFAULT;
descTex.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
descTex.Width  = width;
descTex.Height = height;
descTex.MipLevels = 0;
descTex.SampleDesc.Count = 1;
device->CreateTexture2D(&descTex, nullptr, &tex);

...it's render target view

D3D11_RENDER_TARGET_VIEW_DESC descRTV;
descRTV.Format = descTex.Format;
descRTV.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
descRTV.Texture2D.MipSlice = 0;
device->CreateRenderTargetView(tex, &descRTV, &rtv);

...it's shader resource view

D3D11_SHADER_RESOURCE_VIEW_DESC descSRV;
ZeroMemory(&descSRV, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
descSRV.Format = descTex.Format;
descSRV.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
descSRV.Texture2D.MipLevels = (UINT)-1;
descSRV.Texture2D.MostDetailedMip = 0;
device->CreateShaderResourceView(tex, &descSRV, &srv);

Explicit generation of mipmap is called after the scene was rendered into the texture and another texture was set as a render target.

ID3D11RenderTargetView* aRTViews[1] = { mPass1Buff.GetRTV() };
mImmediateContext->OMSetRenderTargets(1, aRTViews, nullptr);

mImmediateContext->GenerateMips(mPass0Buff.GetSRV());

ID3D11ShaderResourceView* aSRViews[1] = { mPass0Buff.GetSRV() };
mImmediateContext->PSSetShaderResources(0, 1, aSRViews);

The code is compiled in debug and the D3D device was created with D3D11_CREATE_DEVICE_DEBUG flag and I get no runtime errors on the console.

\$\endgroup\$
3
  • \$\begingroup\$ I'm voting to close this question because it is a cross-post from computergraphics. Cross-posting is not allowed on stack exchange sites, please select the one that will give you the most/best answers and ask only there. If you feel it's Game Development, then please delete the other and flag for mod or vote to reopen here. \$\endgroup\$
    – Vaillancourt
    Jul 22, 2019 at 14:37
  • \$\begingroup\$ Can you delete/close this one, please? I cannot. \$\endgroup\$
    – ivokabel
    Jul 22, 2019 at 17:31
  • \$\begingroup\$ Thanks for taking the time to reply. No worries: it's currently "on hold" and questions "on hold" are technically "closed", it's just that the label is "on hold" for the first ~5 days, then it becomes "closed". \$\endgroup\$
    – Vaillancourt
    Jul 22, 2019 at 17:38

1 Answer 1

2
\$\begingroup\$

Your problem is that you initialize your sampler description by setting all of it's members to 0, via ZeroMemory. See this related question and answer: How to fill/initialize D3D11_SAMPLER_DESC properly?

Also the documentation for D3D11_SAMPLER_DESC which explains the values you should use: https://docs.microsoft.com/en-us/windows/win32/api/d3d11/ns-d3d11-d3d11_sampler_desc

You shouldn't be surprised that your min and max LOD are both 0 (which will result in miplevel 0 always being selected irrespective of other options) because that is what you have explicitly asked for, via your ZeroMemory call. Again, refer to the documentation, linked above, for the values you should be using.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Yes, that's it. It set min/max LOD to 0, which practically lead to disabling the mipmap. Thank you! \$\endgroup\$
    – ivokabel
    Jul 21, 2019 at 18:05

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