【问题标题】:What is the significance of a semantics and vertex layouts in D3D11?D3D11 中的语义和顶点布局有什么意义?
【发布时间】:2013-05-27 12:57:05
【问题描述】:

语义的目的是什么?

如果我有这样的顶点布局:

struct VS_Input
{
    float4 position : COLOR;
    float4 color : POSITION;
};

我颠倒两个成员的语义真的有关系吗?

如果我必须向 Direct3D 发送每个顶点的结构,为什么它不能按原样复制我的数据?

如果我为 direct3D 提供的顶点布局与着色器的布局不匹配,会发生什么情况?例如,如果我将以下顶点传递给上述着色器?

struct MyVertex
{
    Vec4 pos;
    Vec2 tex;
    Vec4 col;
};

在 D3D 文档中,它说会产生警告,并且我的数据将被“重新解释”

这是否意味着像 reinterpret_cast 中那样“重新解释”?比如,我的着色器会尝试使用纹理坐标和一半颜色作为着色器中的颜色?还是它会在我的顶点布局中搜索与每个语义匹配的元素并将输入打乱到正确的位置以使着色器工作?

如果上述情况不成立,那么为什么 D3D 需要显式的顶点布局?

【问题讨论】:

    标签: c++ shader direct3d direct3d11


    【解决方案1】:

    语义用于将顶点缓冲区绑定到着色器输入。在 D3D11 中,缓冲区只是用于存储数据的内存块,着色器具有输入签名,描述了他们期望的输入,输入布局表示缓冲区和着色器之间的绑定,并描述如何解释缓冲区中的数据.语义的作用只是将缓冲区布局描述中的元素与相应的着色器输入进行匹配,名称并不重要,只要它们匹配即可。

    在创建输入布局对象时,您可以正确指定顶点数据的布局。如果您的输入布局与数据内存中的实际布局不匹配,那么它实际上就像使用 reinterpret_cast 一样,您将呈现垃圾。提供输入元素和着色器输入之间的语义正确匹配,但是它们将被正确绑定,并且元素顺序之类的事情无关紧要。它是描述如何将顶点缓冲区中的数据元素传递给着色器输入的语义。

    【讨论】:

    • 谢谢。我假设顶点布局和着色器结构必须对应 1 到 1。此外,您必须为变量和语义提供名称这一事实似乎有点多余,但当我想到它时,我想使用“pos”而不是我的着色器代码中的“位置”更舒服。
    • 解耦顶点布局和着色器输入布局的原因是您可能希望将相同的顶点数据与需要不同输入的不同着色器一起使用。一个常见的例子是深度预通道或阴影渲染通道,您只需要访问着色器中的位置。通过将位置存储在其自己的缓冲区中,您可以避免在仅深度着色器中获取其他顶点组件时浪费内存带宽。当您稍后在光照/着色通道中渲染对象时,您可能需要其他顶点组件,例如纹理坐标、法线等。
    • @albundy 您可能会发现编译一个简单的着色器以进行组装并查看生成的 ASM 文件(通过使用 /Fc 开关调用 fxc.exe)很有启发性。当您这样做时,编译器将编写一个长注释部分,其中包含有关它如何链接各种缓冲区的有趣信息。然后您可以开始使用输入和格式规范以及它们如何交互。
    猜你喜欢
    • 1970-01-01
    • 2010-09-15
    • 2018-12-18
    • 1970-01-01
    • 1970-01-01
    • 2018-04-11
    • 2011-02-20
    • 1970-01-01
    • 2011-02-22
    相关资源
    最近更新 更多