为了天真地渲染精灵,您可以发送单个矩形及其位置,旋转,大小和纹理。这很容易,但是考虑到减少状态变化,绘制调用和数据上传是提高渲染性能的好方法,显然这不是一种有效的解决方案。几何着色器中的矩形非常吸引人,但是如果针对WebGL之类的平台甚至是较旧的硬件,则无法使用。渲染精灵?

我对与API无关的答案很感兴趣,但是出于说明目的,可以使用OpenGL或Direct X这样的特定API。

评论

您是在专门谈论OpenGL吗?特别是关于WebGL?可以使用实例化吗?

好问题,让我澄清一下。尽管我确实希望在GPU上完成工作,但我对特定的图形API并没有特别的兴趣。

#1 楼

提高Sprite渲染效率的一种好方法是几何实例化。这使您可以使用一个顶点/索引缓冲区对来定义网格,然后使用第二个顶点缓冲区(其元素定义实例)在一次绘制调用中渲染该网格的许多实例。它比几何体着色器得到更广泛的支持。特别是在WebGL中,通过ANGLE_instanced_arrays扩展支持它。

要将其应用于子画面,一个顶点缓冲区可以定义子画面的形状(即由两个三角形组成的四边形),然后定义另一个顶点缓冲区可能包含每个子画面的信息,例如位置,旋转,大小等。每个精灵中的每个顶点一次。您将使用顶点着色器将来自两个缓冲区的信息放在一起,将每个顶点适当地转换为精灵的属性。这使GPU可以为精灵生成所有顶点,并保存从CPU上传的数据。


以这种方式使用实例化确实需要以相同状态绘制所有精灵,即相同的着色器,纹理,混合模式等。如果某些精灵需要不同的状态,则每种状态组合都需要单独的一批实例。

评论


$ \ begingroup $
可以使用点精灵代替2x三角形顶点吗?实例数据可以是vec2,用于定义方向和大小。尽管您可能需要在其中放置另一个用于矩形精灵的浮动对象。
$ \ endgroup $
–PaulHK
16-8-8 3:00



$ \ begingroup $
@PaulHK Point子画面非常有限-有时取决于GPU,它们的最大大小较小,并且它们不支持旋转或任何非正方形形状。而且,它们会根据其中心点被剪切,因此,当它们离开屏幕边缘时,弹出时间太早。我不会理会他们。
$ \ endgroup $
–内森·里德(Nathan Reed)
16年8月8日,下午3:32

$ \ begingroup $
是的,我认为它们会有些不灵活,可以在碎片着色器中旋转,但是随后需要过度投影尺寸以适合对角线。
$ \ endgroup $
–PaulHK
16年8月8日,下午3:51

$ \ begingroup $
我已经看过它的评论,如果您要处理非常小的网格(例如一对三角形),则实例化会很慢。您可以对此发表评论吗?
$ \ endgroup $
–porglezomp
16年8月8日在19:14

$ \ begingroup $
在我自己的绘制精灵的实验中,渲染具有6k个顶点的网格(即,一个包含所有精灵的网格)比渲染具有6个顶点和1k实例的网格要快。请注意,在实例化过程中,我没有使用glVertexAttribDivisor,而是从缓冲区对象中读取了数据。使用glVertexAttribDivisor可能更快,因为gpu可以将数据推送到着色器,而读取缓冲区对象则意味着着色器必须提取其数据。但我没有对此进行基准测试,因此不重要。我仍然喜欢实例化,因为它是一种简单的干净解决方案。
$ \ endgroup $
–user4925
16年8月16日在10:17