优化场景图形

Optimize scene graph

本文关键字:图形 优化      更新时间:2023-10-16

我用c++用opengl写了一个标准的场景图。

我的场景图有节点和形状。

节点是矩阵,它们在应用矩阵后绘制出所有的子节点。

void Node::draw(Affine3f amatrix) const
{
   amatrix = amatrix * matrix;
   for (Drawable* child : childern)
   {
      child->draw(amatrix);
   }
}

形状是简单打包的vbo,它们从draw调用中获取矩阵,将其设置为统一的模型视图矩阵,然后绘制vbo。

void Shape::draw(Affine3f mat) const
{
   renderer.setModelView(mat);
   myVertices.draw();
}

我喜欢这个设计,它非常简单和灵活。但是,它的效率非常低,有大量的CPU端矩阵乘法和大量的draw调用。

我的问题是:

我如何优化这个设计,删除不需要的矩阵乘法和不必要的绘制调用?

就像每次绘制时不重新计算矩阵(只计算改变的)和统一形状,这样它们就可以用一次调用来绘制。

更多信息:

  • 形状是静态的(目前),包含的顶点永远不会改变。
  • 有静态几何(活在根节点没有操作)和动态几何(被操作节点的子节点)的混合

首先,我会为传入的矩阵传递一个const &。你是按值传递的,如果你有一些draw函数最终不需要对矩阵做任何特殊的操作,这是很多不必要的复制。

如果你想在矩阵没有改变的情况下防止矩阵计算,你需要有一个"脏"标志来确定矩阵的值在你上次使用它之后是否发生了变化。RenderWare用它的矩阵做了类似的事情。

否则,就像在评论中那样,没有看到你的整体设计,你所拥有的本质上没有什么问题。

您是否绘制树中的每个元素,即使它不可见?如果是这样,您应该检查八叉树来过滤不可见的节点。

你也可以尝试在着色器中进行大多数矩阵计算,通过将它们作为变量传递。我也看到你的矩阵是仿射的,但也许你在你的实现中仍然做了一个昂贵的逆计算。如果是这样的话,你可以看看我的教程,看看如何让它更便宜。