3

我有一个难题,简直把我难住了。假设我有几个着色器,它们都具有不同的顶点类型,如下所示:

// light shader
struct vertexInputType
{
    float4 position : POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : NORMAL;
};

// color shader
struct vertexInputType
{
    float4 position : POSITION;
    float4 color : COLOR;
};

// bump mapping shader
struct vertexInputType
{
    float4 position : POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : NORMAL;
    float3 binormal : BINORMAL;
    float3 tangent : TANGENT;
};

现在假设我有一个包含所有这些数据的模型。我不能完全将它们全部放在同一个缓冲区中并按照我选择的所有 3 个进行渲染,因为数据没有为所有这些缓冲区正确布局。我只看到两个选项可以使这成为可能,它们都一样痛苦。

1)我可以在 ram 中有一个大缓冲区来保存所有数据,然后每次绘制调用,我从着色器对象中获取顶点类型并创建一个具有正确信息的新顶点缓冲区。如您所见,这将非常缓慢。

或者...

2) 我可以在模型初始化时创建多个 ID3D11Buffers,其中一个缓冲区具有位置和颜色,一个具有位置、texcoord 和法线,一个具有位置、texcoord、法线、副法线和切线,以及所需的尽可能多的缓冲区对于模型具有信息的任何其他顶点类型。相比之下,这会抹杀您可用的 vram,也使其成为 nog​​o。

我看不出有任何其他方法可以做到这一点。你们其他 d3d 人是如何做到这一点的?

4

2 回答 2

2

您在 DX11 上下文中询问此问题是一件好事 - ID3D11InputLayout与以前的版本相比,大大简化了这个概念。您可以使用CreateInputLayout创建顶点数据的多个布局(一个用于您上面提供的每个结构),并在您希望以不同方式解释相同顶点缓冲区的点处使用正确的布局调用IASetInputLayout 。

编辑:在此处查看创建 Input-Layout 对象的示例。

希望这可以帮助!

于 2012-07-16T16:00:22.783 回答
1

诀窍是将数据分成流:P、T、A。

流 P 包含位置和法线。需要此数据来渲染带有光照的顶点。您还可以包括副法线和顶点颜色数据。

流 T 包含纹理信息,因此最多可以是 8 个 TU 通道。应注意存储在此流中编码的通道数,以确保不会浪费内存带宽在 GPU 总线上复制空通道。

流 A 包含动画信息、骨骼权重等。

根据渲染管道的架构,您可以拥有更多或更少的通道。这里的诀窍是使用 FVF 动态定义您的数据布局。这种架构的一个优点是优化内存带宽使用。当需要多个渲染通道但并非每个通道都需要所有数据时,这尤其重要。

于 2012-07-16T15:58:42.550 回答