我试图以最有效的方式在DirectX 11中渲染方块。每个方块都有一个颜色(float3)和一个位置(float3)。典型的平方数约为5百万。
我尝试了3种方式:
原始数据意味着每个方块在顶点缓冲区中表示为4个顶点,在索引缓冲区中表示为两个三角形。
几何着色器和实例渲染意味着每个方块在顶点缓冲区中只有一个顶点。
我对5M方块的结果(在nvidia GTX960M上)是:
我预计几何着色器不是最有效的方法。另一方面,我很惊讶Instanced渲染比原始数据慢。顶点着色器中的计算完全相同。它只是与存储在常量缓冲区中的变换矩阵相乘+加上Shift变量。
struct VSInput{
float3 Position : POSITION0;
float3 Colot : COLOR0;
float2 Shift : TEXCOORD0;// This is xy deviation from square center
};
struct VSInputPerVertex{
float2 Shift : TEXCOORD0;
};
struct VSInputPerInstance{
float3 Position : POSITION0;
float3 Colot : COLOR0;
};
对于较大的模型(20M方格),实例渲染效率更高(显然是因为内存流量)。
为什么实例渲染比原始数据渲染更慢(在5M方格的情况下)?是否有另一种有效的方法来完成此渲染任务?我错过了什么吗?
可能的解决方案之一是使用StructuredBuffer
作为@ galop1n建议(有关详细信息,请参阅他的回答)。
我的结果(在nvidia GTX960M上)为5M正方形
答案 0 :(得分:2)
每个实例的小顶点数通常是未充分利用硬件的好方法。我建议你这个变种,它应该为每个供应商提供良好的性能。
VSSetShaderResourceViews(0,1,&quadData);
SetPrimitiveTopology(TRIANGLE);
Draw( 6 * quadCount, 0);
在顶点着色器中,您有
struct Quad {
float3 pos;
float3 color;
};
StructuredBuffer<Quad> quads : register(t0);
要在顶点着色器中重建四边形:
// shift for each vertex
static const float2 shifts[6] = { float2(-1,-1), ..., float2(1,1) };
void main( uint vtx : SV_VertexID, out YourStuff yourStuff) {
Quad quad = quads[vtx/6];
float2 offs = shifts[vtx%6];
}
然后像往常一样重建顶点并进行变换。您必须注意,因为您绕过输入装配阶段,如果要将颜色发送为rgba8,则需要使用uint并手动解压缩。如果要绘制数百万个四边形,则带宽使用率会降低。