D3D11 Post Shader Results in Dark Image

416 views Asked by At

I'm trying to implement post shaders (pixel shaders) as a test. I have a texture to which all stuff is rendered, and the post shader simply copies this texture to the back buffer.

If this texture is larger than the back buffer, the post shading process results in dimming:

enter image description here

However, if this texture is the same size (or smaller) as the back buffer, the post shading process ends in an exact copy:

enter image description here

The post shader is very simple:

struct VSOut {
    float4 position : SV_Position;
    float2 uv : TexCoord;
};

float time;

Texture2D inTex;

SamplerState textureSampler = sampler_state {
    Texture = inTex;
    MagFilter = point;
    MinFiler = point;
    AddressU = clamp;
    AddressV = clamp;
};

float4 main(VSOut vs) : SV_TARGET {
    float4 color = inTex.Sample(textureSampler, vs.uv);

    return color;
}

And the vertex shader that comes before it is just a fullscreen triangle:

struct VSOut {
    float4 position : SV_Position;
    float2 uv : TexCoord;
};

VSOut main(uint vertexID : SV_VertexID) {
    VSOut result;

    result.uv = float2((vertexID << 1) & 2, vertexID & 2);
    result.position = float4(result.uv * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);

    return result;
}

I've tried changing the filters in the post shader, but that doesn't seem to affect the color. Why might this be happening?

EDIT: By request, the render texture creation code:

D3D11_TEXTURE2D_DESC Desc2D;

Desc2D.Width = 1280; //Window is 720p - this produces a bright image
Desc2D.Height = 720;
Desc2D.MipLevels = 0;
Desc2D.ArraySize = 1;
Desc2D.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
Desc2D.SampleDesc.Count = 1;
Desc2D.SampleDesc.Quality = 0;
Desc2D.Usage = D3D11_USAGE_DEFAULT;
Desc2D.CPUAccessFlags = NULL;
Desc2D.MiscFlags = NULL;
Desc2D.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;

hr = Device->CreateTexture2D(&Desc2D, nullptr, &PreRenderTexture);
1

There are 1 answers

0
MuertoExcobito On BEST ANSWER

You are creating your render texture with a full set of mipmaps, by setting D3D11_TEXTURE2D_DESC::MipLevels=0. See documentation here.

When you render to the texture, presumably, you are only rendering to the top level mipmap. The other mipmap levels, although technically undefined (from the documention on CreateTexture2D), generally start out black.

In your shader, you sample the render texture. When it is the exact size of the screen or smaller, you always sample the highest miplevel, which contains your render result. If the texture is larger, some pixels will come from a lower level mipmap, and be undefined (but likely black, as previously stated). This creates a dithering type effect, and darkens the result.

There are many solutions. The easiest is to create the render target with only one level, likely the others are unnecessary. You could also bias the sampling in your shader to always use the top level with SampleLevel in HLSL. Or, you could generate the mip chain for lower levels in your render target. Or, you could always have the texture be the size of the screen or smaller.