通过 DirectX 11 渲染正方形

标签 rendering shader directx-11

简介

我正在尝试以最有效的方式在 DirectX 11 中渲染正方形。每个方 block 都有一个颜色 (float3) 和一个位置 (float3)。正方形的典型数量约为 500 万。

我尝试了 3 种方法:

  1. 渲染原始数据
  2. 使用几何着色器
  3. 使用实例渲染

原始数据意味着,每个正方形在顶点缓冲区中表示为 4 个顶点,在索引缓冲区中表示为两个三角形。

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

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

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

我预计几何着色器不是最有效的方法。另一方面,令我惊讶的是实例化渲染比原始数据慢。顶点着色器中的计算完全相同。它只是与存储在常量缓冲区中的变换矩阵相乘 + 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;       
};

注意事项

对于更大的模型(2000 万平方),实例化渲染更有效(显然是因为内存流量)。

问题

为什么实例渲染比原始数据渲染慢(在 5M 正方形的情况下)?有没有另一种有效的方法来完成这个渲染任务?我错过了什么吗?

编辑

StructuredBuffer 方法

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

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

  • StructuredBuffer 48 FPS

观察

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

最佳答案

每个实例的小顶点数通常是充分利用硬件的好方法。我建议您使用该变体,它应该为每个供应商提供良好的性能。

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

关于通过 DirectX 11 渲染正方形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37191214/

相关文章:

html字体/矢量图形问题

graphics - Skia 或 Direct2D 如何使用 GPU 渲染线或多边形?

reflection - 如何用threejs实现逼真反射

c++ - IDXGIFactory 版本

c++ - 通用 Windows 平台 Direct3D C++ 应用程序上的 60 FPS 游戏循环

javascript - 如何将 View 呈现为字符串?

c# - 从文件系统读取 ASPX 文件并呈现为 HTML

javascript - Threejs 自定义着色器 - 屏幕撕裂

unity3d - 仅用于某些顶点的顶点着色器

c++ - D3D11_BUFFER_SRV - 如何使用它?