我正在尝试将后期着色器(像素着色器)实现为测试。我有一个纹理,所有东西都被渲染,后期着色器只是将这个纹理复制到后面的缓冲区。
如果此纹理大于后缓冲区,则后着色处理会导致变暗:
但是,如果此纹理与后台缓冲区的大小相同(或更小),则后期着色过程将以精确副本结束:
帖子着色器非常简单:
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;
}
前面的顶点着色器只是一个全屏三角形:
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;
}
我尝试更改后期着色器中的滤镜,但这似乎不会影响颜色。为什么会发生这种情况?
编辑:根据请求,渲染纹理创建代码:
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);
答案 0 :(得分:3)
通过设置D3D11_TEXTURE2D_DESC::MipLevels=0
,您可以使用一整套mipmap创建渲染纹理。请参阅文档here。
渲染到纹理时,大概是,您只渲染到顶级mipmap。其他mipmap级别虽然技术上未定义(来自CreateTexture2D上的文档),但通常都是黑色。
在着色器中,您可以对渲染纹理进行采样。如果它是屏幕的确切大小或更小,则始终采样最高的miplevel,其中包含渲染结果。如果纹理较大,则某些像素将来自较低级别的mipmap,并且未定义(但可能是黑色,如前所述)。这会产生抖动类型效果,并使结果变暗。
有很多解决方案。最简单的方法是只使用一个级别创建渲染目标,可能其他级别是不必要的。您还可以在着色器中偏置采样,以始终在HLSL中使用SampleLevel的顶级值。或者,您可以在渲染目标中为较低级别生成mip链。或者,您可以始终将纹理设置为屏幕大小或更小。