我在使用 OpenGL 渲染 100 万个三角形时遇到性能问题

问题描述 投票:0回答:1

我正在使用 RTX 3060 GPU(笔记本电脑版本),我正在尝试渲染 100 万个三角形(通过 500,000 个实例四边形的实例化),GPU 似乎花费了大约 40 毫秒,如 nsight 所示,而 CPU 实际上什么也没做。我的着色器是简单的顶点和片段着色器,其中没有其他内容。这看起来非常微不足道,因为我认为 GPU 可以轻松渲染数百万个三角形。主渲染循环如下所示:

m_RenderData.InitialColorPass->Use();
m_RenderData.InitialColorPass->SetUniformMat4("ViewProjection", ViewProjectionMatrix);

InstanceBatch.BeginInstanceBatch();

glDrawElementsInstanced(
    GL_TRIANGLES,                     
    (GLuint)(Instance.GetCount()),     
    GL_UNSIGNED_INT,                   
    nullptr,                          
    (GLuint)(InstanceBatch.GetNumberOfInstances())
);

InstanceBatch.EndInstanceBatch();

在开始实例批处理中,我取消映射包含矩阵数据的缓冲区

if (m_CurrentBufferIndex == 0)
    m_InstanceBuffer.UnMap();
else if (m_CurrentBufferIndex == 1)
    m_InstanceSecondBuffer.UnMap();
else
    m_InstanceThirdBuffer.UnMap();

m_InstanceVAO.Bind();

然后在最终实例批处理中,我只需重新映射缓冲区范围,我在启用异步标志和三重缓冲的情况下执行此操作。

if (m_CurrentBufferIndex == 0)
{
    m_BufferMapBase = (float*)m_InstanceSecondBuffer.MapBufferRange();
    m_InstanceVAO.AttachVertexBuffer(m_InstanceSecondBuffer, 1, m_AttributeDataCopy.Offsets[1], m_AttributeDataCopy.Strides[1]);
    m_CurrentBufferIndex = 1;
}
else if (m_CurrentBufferIndex == 1)
{
    m_BufferMapBase = (float*)m_InstanceThirdBuffer.MapBufferRange();
    m_InstanceVAO.AttachVertexBuffer(m_InstanceThirdBuffer, 1, m_AttributeDataCopy.Offsets[1], m_AttributeDataCopy.Strides[1]);
    m_CurrentBufferIndex = 2;
}
else
{
    m_BufferMapBase = (float*)m_InstanceBuffer.MapBufferRange();
    m_InstanceVAO.AttachVertexBuffer(m_InstanceBuffer, 1, m_AttributeDataCopy.Offsets[1], m_AttributeDataCopy.Strides[1]);
    m_CurrentBufferIndex = 0;
}

起初我认为这是缓冲区同步问题并等待 GPU,这就是我实现三重缓冲的原因,虽然这实际上将 CPU 时间减少到零(每帧大约 2 毫秒),但 GPU 仍然需要很长时间。我开始认为这可能是硬件限制,但 3060 即使在笔记本电脑上也是强大的 GPU。接下来,我认为在控制面板中启用和禁用了垂直同步,但这似乎没有任何作用。我的集成显卡(amd ryzen 7 5800)也略胜于我的专用 3060。

我最近开始收到的一个警告是 [Core-Warn] 像素路径性能警告:像素传输与 3D 渲染同步。 当我最初重新映射缓冲区或使用新大小重建缓冲区时,会发生一次这种情况。

c++ performance opengl nvidia gpu-instancing
1个回答
0
投票

我发现了问题,结果发现其中一个映射的缓冲区错误地附加到顶点数组,所以我只使用双缓冲而不是我想要的三重缓冲,因为每一帧都没有映射,因此绘制调用将从空缓冲区。现在回想起来,对于如此多的数据,GPU 使用率高而 CPU 使用率低似乎是显而易见的。

© www.soinside.com 2019 - 2024. All rights reserved.