0

在着色器模型 5.1 中,我们可以对纹理使用动态索引,如下所示:

Texture2D textures[5] : register(t0)
PixelShader(Input p) : SV_TARGET
{
     float4 color = textures[0].Sample(someSampler, p.UV);
     return color;
}

这里假设所有纹理都有 4 个通道 (rgba)。但是,当我的纹理数组混合了 BC3(rgba)、BC4(单通道 R)、BC5(双通道 RG)等不同格式时,我不知道如何采样。例如,在 BC4 的情况下,我可以尝试

float R = textures[0].Sample(someSampler, p.UV).r;

但这不会跳过三个纹素吗?

4

2 回答 2

1

这不是“纹理数组”。这只是一种声明 5 个单独绑定的纹理的方法,语法允许您使用索引来选择t0通过t1. “纹理数组”声明如下:

Texture2DArray textures : register(t0);

纹理数组中的每个纹理必须具有相同的格式(它是单个资源),并且您使用 afloat3对其进行索引以进行采样。

float4 color = textures.Sample(someSampler, float3(p.UV,0) );

您在上面所做的基本上与以下内容相同:

Texture2D texture0 : register(t0);
Texture2D texture1 : register(t1);
Texture2D texture2 : register(t2);
Texture2D texture3 : register(t3);
Texture2D texture4 : register(t4);

因此,每个纹理的格式是完全独立的,这里的代码:

float R = textures[0].Sample(someSampler, p.UV).r;

这只是像平常一样对纹理进行采样t0,只返回红色通道。对于 BC4,这将导致硬件解压缩正确的 4x4 块(或块取决于 UV 和采样器模式),并从重建中返回红色通道。

如果您是 DirectX 和 HLSL 的新手,我强烈建议您不要使用 DirectX 12 开始。这是一个为图形专家设计的相当无情的 API,因此您应该考虑从 DirectX 11 开始。API 都驱动相同的硬件,只是使用不同的程序员抽象来实现。DirectX 12 文档通常还假设您已经是 DirectX 11 的专家,并且 HLSL 的使用基本相同(添加了对根签名的编程控制)。请参阅DirectX 11DirectX 12DirectX 工具包

于 2017-07-07T18:38:47.163 回答
1

HSLS Shader 模型 5.1 非常令人困惑,因为“纹理数组”和“纹理数组”之间存在区别......

第一个含义是与DX10一起出现的,一个纹理资源由几个切片组成,一个shader可以在切片中进行索引。主要限制是每个切片必须共享大小和格式。

DX12 或 Vulkan 等 API 引入的第二个含义更接近于“纹理数组”。您现在可以将多个资源对象分组到一个描述符数组中。着色器可以通过动态索引自由地使用它们中的任何一个。纹理数组的约束被解除。一个限制是使用NonUniformIndex内在函数让驱动程序修复 GPU 可能具有的索引限制。

至于你原来的问题,那么你要知道什么纹理在哪里,如果你用 BC4 和 BC7 等格式对纹理进行分组,可能是因为一个是反照率,另一个可能是光泽图。您的着色器将为它读取的内容提供语义。但是如果你想要一个 BC4 纹理扩展为RRRR而不是默认的R001,你可以在着色器资源视图中使用组件映射。

于 2017-07-23T01:36:47.570 回答