【发布时间】:2014-01-26 05:53:34
【问题描述】:
调用CreateInputLayout 会创建一个输入布局,该布局仅适用于具有完全相同语义位置的着色器,使用单个顶点数据缓冲区。
例如:
VSInput1
{
float3 Position : POSITION;
float2 TexCoord0 : TEXCOORD0;
float3 Normal : NORMAL;
};
无法正确转换为:
VSInput2
{
float3 Position : POSITION;
float3 Normal : NORMAL;
};
即,当使用附加到VSInput2 的着色器和来自VSInput1 的输入布局时,来自VSInput1 的TEXCOORD0 将用于代替来自VSInput2 的NORMAL,尽管使用来自@ 的输入布局987654331@ 说明NORMAL 在TEXCOORD0 之后。
此行为表明CreateInputLayout 仅使用语义来确定着色器是否拥有它们,否则忽略内存中的变量位置。
这太可怕了,因为它需要以下两个选项之一:
1) 使用 VSInput2 着色器的编译着色器代码创建一个新的输入布局。
这将需要更多内存来为需要使用多个着色器的每个缓冲区创建新的输入布局(考虑到阴影)。 OpenGL 通过确定数据应该驻留在缓冲区中的位置来轻松处理不连续的内存位置。显然,DX11 没有。
2) 将顶点数据分解为单独的缓冲区。
这会比按顺序存储内存要慢,即跳转到一个位置只是为了返回上一个缓冲区中的下一个位置。
来自 MSwebsite:
从寄存器读取数据时可能会重新解释数据
有没有办法确保寄存器以上述要求的方式解释,而不必在 asm 中编写着色器?
如果需要 asm,那么如何创建 Input Layout?
【问题讨论】:
-
DX10 和 DX11 使用该机制在初始化时准备一切,并在渲染帧时防止不必要的复杂和昂贵的过程。现代 GPU 不再有硬件可以轻松地从缓冲区中获取。这意味着顶点着色器需要为每个不同的缓冲区布局重新编译。 OpenGL 继续坚持 DX9 懒惰的方式,在每次绘制时,由于未预料到的渲染上下文,事情会在没有控制的情况下触发。
-
您提出的解决方案 1 和 2 是相同的,因为在 GPU 旁边的较低层中无论如何都需要不同的着色器。 OpenGL 只是对你隐藏了更多东西,并且错过了提前准备东西的机会,因为 API 更关心遗留兼容性,并且不像过去那样靠近 GPU 硬件。
标签: hlsl directx-11