通过DirectX 11渲染方块

时间:2016-05-12 15:20:56

标签: rendering shader directx-11

简介

我试图以最有效的方式在DirectX 11中渲染方块。每个方块都有一个颜色(float3)和一个位置(float3)。典型的平方数约为5百万。

我尝试了3种方式:

  1. 渲染原始数据
  2. 使用几何着色器
  3. 使用实例渲染
  4. 原始数据意味着每个方块在顶点缓冲区中表示为4个顶点,在索引缓冲区中表示为两个三角形。

    几何着色器和实例渲染意味着每个方块在顶点缓冲区中只有一个顶点。

    我对5M方块的结果(在nvidia GTX960M上)是:

    • 几何着色器 22 FPS
    • 实例渲染 30 FPS
    • 原始数据呈现 41 FPS

    我预计几何着色器不是最有效的方法。另一方面,我很惊讶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方格的情况下)?是否有另一种有效的方法来完成此渲染任务?我错过了什么吗?

    修改

    StrcturedBuffer方法

    可能的解决方案之一是使用StructuredBuffer作为@ galop1n建议(有关详细信息,请参阅他的回答)。

    我的结果(在nvidia GTX960M上)为5M正方形

    • StructuredBuffer 48 FPS

    观察

    • 有时我发现StructuredBuffer方法在 30 FPS - 55 FPS (100帧的累计数)之间振荡。它似乎很不稳定。中位数为48 FPS。我没有使用以前的方法观察到这一点。
    • 考虑绘制调用和StructuredBuffer大小之间的平衡。当我使用 1K - 4K点 的缓冲区时,我达到了 最快的 行为,适用于较小的模型。当我尝试渲染5M方形模型时,我有大量的绘制调用并且效率不高(30 FPS)。我观察到的5M方块的最佳行为是每个缓冲区 16K点 。每个缓冲区32K和8K点似乎设置较慢。

1 个答案:

答案 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并手动解压缩。如果要绘制数百万个四边形,则带宽使用率会降低。