2
$\begingroup$

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$
  • $\begingroup$ descTex.MipLevels = 0; Does that have anything to do with it ? $\endgroup$ – PaulHK Jul 10 at 5:47
  • $\begingroup$ The doc. says: "The maximum number of mipmap levels in the texture. See the remarks in D3D11_TEX1D_SRV. Use 1 for a multisampled texture; or 0 to generate a full set of subtextures." I guess I may an explicit number to see whether it changes anything... $\endgroup$ – ivokabel Jul 10 at 9:28
1
$\begingroup$

I found the problem. By zeroing the sampler description I implicitly set LOD bounds to 0. After adding

descSampler.MinLOD = 0;
descSampler.MaxLOD = D3D11_FLOAT32_MAX;

the mipmap works as expected. Thank you for your attention :-)

$\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.