最近我决定压缩我的顶点数据以提高渲染效率,我遇到了一个解决方案 – 使用half(特别是half4和half2)而不是float来存储我的顶点数据.我的顶点结构如下:
[StructLayout(LayoutKind.Sequential)] public struct MyVertex { public Half4 Position; //8 bytes public Half4 normal; //8 bytes public Half2 UVW; //4 bytes public Half4 TextureID; //8 bytes public Half4 BlendFactor; //8 bytes public const int SizeInBytes = (2 * 4) * 4 + (2 * 2); }
这是我的顶点声明:
MyVertexDecl = new VertexDeclaration(device,new VertexElement[6] { new VertexElement(0,DeclarationType.HalfFour,DeclarationMethod.Default,DeclarationUsage.Position,0),new VertexElement(0,8,DeclarationUsage.normal,16,DeclarationType.HalfTwo,DeclarationUsage.TextureCoordinate,20,1),28,2),VertexElement.VertexDeclarationEnd });
当我将我的数据作为MyVertex数组直接发送到DrawUserPrimitives时,一切正常.
但是当我决定将所有数据放入VBO以避免过多的复制操作时,我的所有网格变成了像素混乱.我将我的值写为ushorts(SlimDX halfs为每个组件都有RawValue字段).
以下是PIX对我网格的看法:
在指定我的布局后,这里是缓冲区查看器中的相同部分(我只显示一列,因为它们很宽,希望你能得到这个想法):
正如你所看到的,我的半身被错误地威胁为花车.在着色器中将float4更改为half4也没有用,似乎问题出在其他地方.是否有另一种方法可以告诉我的GPU使用我的顶点缓冲区作为halfs的缓冲区而不是浮点缓冲区?
UPD:
这是我的绘图代码(缩写):
public void Render(GraphicsDevice device,ICamera camera,MyModel model) { //there are some SetValue calls model.Effect.CommitChanges(); foreach (D3D9.VertexBuffer buf in model.Meshes) { device.SetStreamSource(0,buf,MyVertex.SizeInBytes); device.DrawPrimitives(D3D9.PrimitiveType.TriangleList,mesh.VertexCount); } }
_eff.BeginPass(0); GraphicsDevice.VertexDeclaration = vDecl; renderer.Render(GraphicsDevice,camera,world); _eff.EndPass();
我正在使用D3D9到SlimDX和C#.