为什么合并几何会提高渲染速度?

时间:2015-05-30 14:12:51

标签: merge three.js geometry vertices

在我的Web应用程序中,我只需要在场景中添加静态对象。它运行缓慢所以我开始搜索,我发现合并几何和合并顶点是解决方案。当我实现它时,它确实工作得更好。所有文章都表示,这种改进的原因是WebGL调用次数的减少。由于我不熟悉OpenGL和WebGL(我使用Three.js以避免其复杂性),我想知道为什么它会减少WebGL调用? 因为您发送一个大对象而不是许多littles,开销会减少。所以我知道将一个大网格加载到场景比许多小网格更快。 但我不明白为什么合并几何也会对渲染计算产生积极影响?我还想知道合并几何和合并顶点之间的区别吗?

提前致谢!

1 个答案:

答案 0 :(得分:1)

three.js是一个可以帮助您使用WebGL API的框架。

什么"网格"对于webgl,它是三个.js,它是一系列低级别调用,用于设置状态并向GPU发出调用。

让我们以球体为例。使用three.js,您可以使用几行创建它:

var sphereGeometry = new THREE.SphereGeometry(10); 
var sphereMaterial = new THREE.MeshBasicMaterial({color:'red'});
var sphereMesh = new THREE.Mesh( sphereGeometry, sphereMaterial);

myScene.add( sphereMesh );

你有你的renderer.render()调用,poof,屏幕上会出现一个球体。

但很多事情都在幕后发生。

第一行创建球体" geometry" - cpu将会有一堆数学和逻辑描述一个带有点和三角形的球体。点是向量,三个浮点组合在一起,三角形是通过indecis(整数组)对这些点进行分组的结构。

某处有一个循环根据三角函数(sin,cos)计算向量,另一个循环用于将生成的向量数组织成三角形(取每N,N + M,N + 2M,创建三角形等) )。

现在这些数字存在于javascript版本中,它只是一堆浮点数和整数,以特定的方式组合在一起来描述立方体,球体和外星人等形状。

您需要一种在屏幕上绘制此构造的方法 - 一个二维像素数组。

WebGL实际上并不了解3D。它知道如何管理gpu上的内存,如何并行计算(或给你工具),它确实知道如何进行对3d图形至关重要的数学运算,但同样的数学可以用来挖掘比特币,甚至没有画任何东西。

为了让WebGL在屏幕上绘制内容,它首先需要将数据放入适当的缓冲区,它需要具有着色器程序,需要为该特定调用设置(是否要进行混合 - 透明度为3.js土地,深度测试,模板测试等),然后它需要知道它实际绘制的是什么(所以你需要提供步幅,属性大小等让它知道网格&#39的位置39;实际上是在记忆中),它是如何绘制的(三角形条,扇形,点......)以及用它绘制的内容 - 哪些着色器将应用于您提供的数据。

所以,你需要一种方法来教导' WebGL做3d。

我认为熟悉这个概念的最好方法是查看this tutorial,必要时重新阅读,因为它解释了透视中的每个单个3d对象所发生的事情< /强>

总结教程:

  • 透视摄像头基本上是两个4x4矩阵 - 透视矩阵,将事物放入视角,以及视图矩阵,将整个世界移动到摄像机空间。你制作的每一台相机都由这两个矩阵组成。
  • 每个对象都存在于对象空间中。 TRS矩阵,(三个.js术语中的世界矩阵)用于将此对象转换为世界空间。

所以这个东西 - 一个概念,例如&#34;投影矩阵&#34;是什么教webgl如何绘制透视。

Three.js进一步抽象出来,给你一些像#34;视野&#34;和&#34;宽高比&#34;顶部而不是左上方。

Three.js还抽象了变换矩阵(摄像机上的视图矩阵和每个对象上的世界矩阵),因为它允许您设置&#34;位置&#34;和&#34;轮换&#34;并在此基础上计算基于此的矩阵。

由于每个网格必须由顶点着色器和像素着色器处理才能显示在屏幕上,因此每个网格都需要提供所有这些信息。

当为特定网格物体发出绘制调用时,该网格物体将具有相同的透视矩阵,并且视图矩阵与使用相同相机渲染的任何其他对象一样。他们每个人都有自己的世界矩阵 - 数字可以在你的场景中移动它们。

这是单独的转换,发生在顶点着色器中。然后栅格化这些结果,并转到像素着色器进行处理。

让我们考虑两种材料 - 黑色塑料和红色塑料。它们将具有相同的着色器,可能是您使用THREE.ShaderMaterial编写的,或者可能是三个库中的一个。它是相同的着色器,但它有一个统一的值 - 颜色。这允许您有许多塑料材质的实例,绿色,蓝色,粉红色,但这意味着每个都需要单独的绘制调用。

Webgl必须发出特定的调用以将该制服从红色变为黑色,然后它就可以使用该材料来绘制内容了#39;。

所以现在想象一个粒子系统,显示每个具有独特颜色的千个立方体。如果将它们视为单独的网格并通过制服改变颜色,则必须发出一千个绘制调用来绘制它们。

另一方面,如果为每个立方体指定顶点颜色,则不再依赖于制服,而是依赖于属性。现在,如果将所有多维数据集合并在一起,则可以发出单个绘制调用,使用相同的着色器处理所有多维数据集。

你可以通过从three.js一眼看看webglrenderer,以及为了将你的3d调用转换为webgl而必须做的所有事情,从而看出为什么这样做更有效率。做得好一千次以上。

回到这3行,sphereMaterial可以采用颜色参数,如果查看源,这将转换为着色器中的统一vec3。但是,您也可以通过渲染顶点颜色并预先指定所需的颜色来实现相同的功能。

sphereMesh会将计算出的几何体包装到三个webglrenderer理解的对象中,从而相应地设置webgl。