shader - 在像素着色器 (DirectX11) 中无法正确访问纹理
问题描述
像素着色器未正确使用纹理。我在我的像素着色器中加载了两个单独的纹理。然而,大多数时候,我只能显示 Texture1,即使我试图显示 Texture2。
Texture2D Texture1;
Texture2D Texture2;
SamplerState ss;
float4 main(float4 position: SV_POSITION, float4 color: COLOR, float2 texCoord: TEXCOORD) : SV_TARGET
{
float4 color1 = Texture1.Sample(ss, texCoord);
float4 color2 = Texture2.Sample(ss, texCoord);
// even though color2 is specified here, color1 ie Texture1 is still displayed
float4 finalColor = color2;
return finalColor;
}
上面的代码总是显示纹理 1(砖): 纹理 1
奇怪的是,我可以显示第二个纹理,但前提是我将像素着色器修改为如下所示:
float4 main(float4 position: SV_POSITION, float4 color: COLOR, float2 texCoord: TEXCOORD) : SV_TARGET
{
float4 color1 = Texture1.Sample(ss, texCoord);
float4 color2 = Texture2.Sample(ss, texCoord);
float4 finalColor = {0,0,0,0};
if (color1.z != color2.z) {
// no idea why, but setting finalColor to color2 outside of this if statement
// doesn't work.
finalColor = color2;
}
return finalColor;
}
这将显示第二个纹理(木材):纹理 2
这是加载纹理的代码:
// load the texture
HRESULT hr = CreateWICTextureFromFile(m_dev.Get(), nullptr, L"bricks.png", nullptr, &m_texture1, 0);
hr = CreateWICTextureFromFile(m_dev.Get(), nullptr, L"wood.png", nullptr, &m_texture2, 0);
...
m_devCon->PSSetShaderResources(0, 1, m_texture1.GetAddressOf());
m_devCon->PSSetShaderResources(1, 1, m_texture2.GetAddressOf());
这里发生了什么?我知道这两个纹理都加载到像素着色器中,因为如果我使用这个奇怪的技巧,我可以获得第二个纹理来显示。
解决方案
HLSL 中的这些声明声明了两个纹理槽和一个采样器槽,但它们没有指明它们的绑定位置。正如声明的那样,您必须使用着色器反射来确定这一点,例如通过旧的效果系统。
Texture2D Texture1;
Texture2D Texture2;
SamplerState ss;
为了使用显式绑定,您需要指出每个项目绑定到哪个插槽。在纹理中显式声明预期的通道数也是一种很好的形式(在这种情况下,我假设有 4 个通道):
Texture2D<float4> Texture1 : register(t0);
Texture2D<float4> Texture2 : register(t1);
SamplerState ss : register(s0);
由于您的代码实际上并未显示为使用创建采样器CreateSamplerState
并将其绑定到 0 插槽PSSetSamplers
,因此您依赖于Microsoft Docs中说明的“默认”采样器状态D3D11_FILTER_MIN_MAG_MIP_LINEAR
with D3D11_TEXTURE_ADDRESS_CLAMP
。
推荐阅读
- tensorflow - 将两个 tensorflow 数据集连接成一个数据集元素,如示例所示
- c++ - 无法弄清楚如何使用 SDL2 正确格式化 Makefile。未定义参考
- java - 我的代码一直在打印“ [Ljava.lang.String;@4e50df2e”,不太确定该放在哪里以及如何放置 toString()
- java - 需要使用 java 的 lamda 表达式打印字符串的最后一位
- java - 调试:合并排序
- selenium - 使用 goroutine 意外关闭 selenium
- c - C 编程中的蛮力搜索,在 C 编程中读取 .fna 文件
- go - 将 int 切片转换为十六进制值的更好方法
- java - 使用 Spring clound contract 为云合约端点编写生产者测试
- c# - 如何在 C# 中使用 LINQ 应用右外连接?