在DX10 / DX11中使用多个顶点缓冲区 [英] Using Multiple Vertex Buffers In DX10/DX11

查看:107
本文介绍了在DX10 / DX11中使用多个顶点缓冲区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个一直在编写的C ++ DirectX 11渲染器。

I have a C++ DirectX 11 renderer that I have been writing.

我编写了一个COLLADA 1.4.1加载程序,用于导入COLLADA数据以支持骨骼动画。

I have written a COLLADA 1.4.1 loader to import COLLADA data for use in supporting skeletal animations.

我现在正在验证加载程序(之前我在以前使用不同技术编写的另一个渲染器中已经支持COLLADA),并且正在运行出现了使COLLADA与DX10 / 11匹配的问题。

I'm validating the loader at this point (and I've supported COLLADA before in another renderer I've written previously using different technology) and I'm running into a problem matching up COLLADA with DX10/11.

我有3个单独的数据顶点缓冲区:

I have 3 separate vertex buffers of data:

唯一顶点位置的顶点缓冲区。
唯一法线的顶点缓冲区。
具有唯一纹理坐标的顶点缓冲区。

A vertex buffer of Unique vertex positions. A vertex buffer of Unique normals. A vertex buffer of Unique texture coordinates.

这些顶点缓冲区包含不同的数组长度(位置具有2910个元素,法线具有9000多个,纹理坐标具有大约3200。)

These vertex buffers contain different array length (positions has 2910 elements, normals has more than 9000, and texture coordinates has roughly 3200.)

COLLADA提供了一个三角形列表,该列表为我提供了给定三角形的每个数组的索引(冗长且一开始很奇怪,但最终它变成了

COLLADA provides a triangle list which gives me the indices into each of these arrays for a given triangle (verbose and oddly done at first, but ultimately it becomes simple once you've worked with it.)

知道DX10 / 11支持多个顶点缓冲区,我想我会在DX10 / 11索引缓冲区中填充索引在这些缓冲区 *和* (这很重要)中,对于给定的三角形点,这些索引可能会有所不同。

Knowing that DX10/11 support multiple vertex buffer I figured I would be filling the DX10/11 index buffer with indices into each of these buffers * and * (this is the important part), these indices could be different for a given point of a triangle.

换句话说,我可以设置三个顶点缓冲区,设置正确的输入布局,然后在索引缓冲区中输入以下内容:

In other words, I could set the three vertex buffers, set the correct input layout, and then in the index buffer I would put the equivalent of:

l_aIndexBuffer[ NumberOfTriangles * 3 ]

for( i = 0; i < NumberOfTriangles; i++ )
{
    l_aIndexBufferData.add( triangle[i].Point1.PositionIndex )
    l_aIndexBufferData.add( triangle[i].Point1.NormalIndex )
    l_aIndexBufferData.add( triangle[i].Point1.TextureCoordinateIndex )
}

有关在中使用多个顶点缓冲区的文档DirectX似乎没有提供任何有关它如何影响索引缓冲区的信息(稍后会对此进行更多介绍。)

The documentation regarding using multiple vertex buffers in DirectX doesn't seem to give any information about how this affects the index buffer (more on this later.)

运行代码以产生奇怪的渲染结果的方式看到我间歇性地正确绘制了网格(奇怪的多边形,但是大约三分之一的点在正确的位置-提示-提示)

Running the code that way yield strange rendering results where I could see the mesh I had being drawn intermittently correctly (strange polygons but about a third of the points were in the correct place - hint - hint)

我认为我已经拧紧了在这一点(昨天)更新我的数据或索引,因此我认真地进行了验证,因此我发现自己在搞砸我的输入或其他内容。我通过使用普通缓冲区和纹理缓冲区中的值来替代设置像素着色器使用的颜色值来消除这种情况,颜色是正确的,因此我不会遇到填充问题。

I figured I'd screwed up my data or my indices at this point (yesterday) so I painstakingly validated it all, and so I figured I was screwing upon my input or something else. I eliminated this by using the values from the normal and texture buffers to alternatively set the color value used by the pixel shader, the colors were correct so I wasn't suffering a padding issue.

最终我得出的结论是,DX10 / 11必须期望以不同的方式订购数据,因此我尝试以这种方式存储索引:

Ultimately I came to the conclusion that DX10/11 must be expect the data ordered in a different fashion, so I tried storing the indices in this fashion:

indices.add( Point1Position index )
indices.add( Point2Position index )
indices.add( Point3Position index )
indices.add( Point1Normal index )
indices.add( Point2Normal index )
indices.add( Point3Normal index )
indices.add( Point1TexCoord index )
indices.add( Point2TexCoord index )
indices.add( Point3TexCoord index )

奇怪的是,这产生了一个看起来正确1/3的渲染网格-提示-

Oddly enough, this yielded a rendered mesh that looked 1/3 correct - hint - hint.

然后我推测DX10 / DX11希望通过顶点缓冲区存储索引,这意味着我将添加所有首先是所有三角形的位置索引,然后是所有三角形的所有正态索引,然后是所有三角形的所有纹理坐标索引。

I then surmised that maybe DX10/DX11 wanted the indices stored 'by vertex buffer' meaning that I would add all the position indices for all the triangles first, then all the normal indices for all the triangles, then all the texture coordinate indices for all the triangles.

这又产生了1 / 3个正确的(看起来)网格。

This yielded another 1/3 correct (looking) mesh.

这使我想到-好的,肯定是DX10 / 11不能为您提供从多个顶点缓冲区进行流式处理的能力,然后实际上期望每个三角形点只有一个索引?

This made me think - well, surely DX10/11 wouldn't provide you with the ability to stream from multiple vertex buffers and then actually expect only one index per triangle point?

仅在位置的顶点缓冲区中包含索引会产生正确渲染的网格,不幸的是使用了错误的法线和纹理坐标。

Only including indices into the vertex buffer of positions yields a properly rendered mesh that unfortunately uses the wrong normals and texture coordinates.

似乎将法线和纹理坐标索引放入索引缓冲区会导致在正确渲染的网格上绘制错误。

It appears that putting the normal and texture coordinate indices into the index buffer caused erroneous drawing over the properly rendered mesh.

这是预期的行为吗?

多个顶点缓冲区-一个索引缓冲区,而索引缓冲区只能为三角形的一个点具有单个索引?

Multiple Vertex Buffers - One Index Buffer and the index buffer can only have a single index for a point of a triangle?

那真的不是

帮助!

推荐答案

我脑海中浮现的东西:

所有支持计算着色器的硬件(几乎等于所有DirectX 10和更高版本)也支持 ByteAddressBuffer s,并且大多数支持 StructuredBuffer s。因此,您可以将数组绑定为 SRV s,并可以随机访问着色器中的任何元素。

All hardware that supports compute shaders (equal to almost all DirectX 10 and higher) also supports ByteAddressBuffers and most of it supports StructuredBuffers. So you can bind your arrays as SRVs and have random access to any of its elements in shaders.

像这样(未经测试,只是伪代码):

Something like this (not tested, just pseudocode):

// Indices passed as vertex buffer to shader
// Think of them as of "references" to real data
struct VS_INPUT
{
    uint posidx;
    uint noridx;
    uint texidx;
}

// The real vertex data 
// You pass it as structured buffers (similar to textures)
StructuredBuffer<float3> pos : register (t0);
StructuredBuffer<float3> nor : register (t1);
StructuredBuffer<float2> tex : register (t2);


VS_OUTPUT main(VS_INPUT indices)
{
    // in shader you read data for current vertex
    float3 pos = pos[indices.posidx];
    float3 nor = nor[indices.noridx];
    float2 tex = tex[indices.texidx];

    // here you do something
}

让我们打电话即计算着色器方法。您必须使用DirectX 11 API。

Let's call that "compute shader approach". You must use DirectX 11 API.

此外,您可以以相同的方式绑定索引,并在着色器中做一些魔术。在这种情况下,您需要找出当前的索引ID。

Also you can bind your indices in same fashion and do some magic in shaders. In this case you need to find out current index id. Probably you can take it from SV_VertexId.

也许您可以解决这些缓冲区并以其他方式绑定数据(DirectX 9兼容纹理采样!O_o)。

And probably you can workaround these buffers and bind data somehow else ( DirectX 9 compatible texture sampling! O_o ).

希望有帮助!

这篇关于在DX10 / DX11中使用多个顶点缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆