OpenGL渲染/更新循环问题

时间:2016-11-21 14:28:30

标签: opengl

我想知道如何图形(/游戏)引擎可以处理大量异构数据,而当您进行一些小的更改时,自定义的简单渲染循环会变成一场噩梦。

示例:

首先,假设我们的场景中有一些块。

  1. 图形引擎:创建多维数据集并移动它们
  2. 自定义:为顶点,法线等创建立方体模板,复制并将它们转换为位置并复制,例如在vbo中。一个glDraw *调用完成了这项工作。
  3. 第二,一些奇怪的逻辑。我们希望块1,4,7,......在x轴上旋转,在y轴上旋转2,5,8,...,在z轴上旋转3,6,9,旋转速度与摄像机成线性关系距离。

    1. 图形引擎:操纵对象的矩阵并且可以正常工作
    2. 自定义:(我认为)每个对象glDraw *调用改变模型矩阵均匀不是一个好主意,所以翻译矩阵应该像属性一样?我必须每帧都更新它们。
    3. 第三,如果到相机的距离低于任何const值Q,则块应该消失。

      1. 图形引擎:if(object.distance(camera)< Q)scene.drop(object);
      2. 自定义:(我认为)我们的vbo无效,我们必须重新创建它?
      3. 再说第一句话:感觉就像引擎免费进行这些操作,而我们必须重新思考如何提供和更新数据。虽然我们这样做,引擎(可能,但我实际上不知道)说:'更新你想要的任何东西,至少我会发送所有的matrizes'。

        另一个例子:基于体素的世界(例如我的世界),我们只绘制可见表面,我们能够投掷炸弹并摧毁许多体素。如果世界的视图数据在一个巨大的缓冲区中,我们只有一个glDraw * -call,但每次都必须重新创建缓冲区。如果有较小的块,我们有许多glDraw * -calls,并且还必须操作较小的缓冲区。

        所以发送让我们说10MB的缓冲区更新数据而不是2 gl * -calls和1MB这是一个很好的交易?有多少更新可以吗?渲染循环应该处理延迟更新吗?

        我正在寻找一个指南60fps应用程序应该能够每帧更新/绘制的内容,以了解可能的内容。对于我的测试,每次优化尝试都是另一个瓶颈。

        我不希望那些教程说:嘿,有一个新的酷gl *实例调用超快,buuuuut你必须检查你的gpu是否支持它。好吧,我还首先考虑这是一个优化,而不是一个有意义的实现。

        您是否有任何想法,来源,最佳做法或经验法则如何最好地协同渲染/更新程序?

        我的问题几乎都是一样的:

        • 今天的硬件上每帧有多少个更新?
        • 我可以在几帧之后延迟加载数据,但不冻结我的应用程序
        • 如果在下一次渲染之前还有一些微秒,我是否必须进行小型更新并对我的循环进行分析?
        • 也许我应该实现一个随时间变化的实时分析器,更新有多贵并且可以确定每帧的更新量?

        谢谢。

1 个答案:

答案 0 :(得分:2)

目前还不清楚你的任何问题与你的图形引擎有什么关系? vs"定制"例子。您使用"图形引擎进行的所有更新"最终转换为那些OpenGL调用。

简而言之:

  

今天的硬件每帧有多少次更新?

今天的PCIe带宽很大(可以高达30 GB / s)。但是,要完全利用它,您必须通过合并OpenGL调用来减少数量事务。确切的更新次数完全取决于硬件,驱动程序和使用方式,图形硬件多种多样

这是你不想听到的那种答案,但不幸的是你必须面对这样的事实:为了减少OpenGL调用的数量,你必须使用更新的版本API。例如。而不是单独设置每个制服,你最好通过统一的着色器缓冲对象提交一堆。不是单独提交每个模型的每个MVP,而是使用实例化渲染更好。等等。

更激进的方法是转向更低级(和更新)的API,即Vulkan,旨在解决这个问题:向GPU提交工作的成本。

  

我可以在几帧之后延迟加载数据,但不冻结我的应用程序

是的,您可以异步上传缓冲区对象。有关详细信息,请参阅Buffer Object Streaming

  

如果在下一次渲染之前还有一些微秒,我是否必须进行小型更新并对循环进行分析?

     

也许我应该实现一个随时间变化的实时分析器,更新有多贵并且可以确定每帧的更新量?

如果您异步执行此操作,则不需要其中任何一项。