文章目录
28. Batch Rendering - An Introduction
在这里我们将在一个drawcall打包多个几何体。即 batch geometry。
我们在这里将聚焦于2d渲染,我们如何渲染一堆2d的quads或者说rectangles呢?
一种情况是比如一个2d游戏有很多个tile组成,要去渲染这些tile;另一种情况比如一个粒子系统有很多独立的quads,又或者UI渲染:把一个文字当作一个独立的 texture quad。
字面上,batching 就是 batch 一些几何体在一个的 vertex buffer 和 index buffer 中然后draw一次。
可以参考:https://zhuanlan.zhihu.com/p/98642798
cherno 的这种方法显然就是一个静态批处理,副作用是导致要传入的 vb 和 ib 的占用空间变大。
前置视频:https://www.youtube.com/watch?v=cybc6XA1czo
看来得先补一下引擎系列了。。。
这里先做一个最简单的方法:
直接把上面的 vertex buffer 改成两个 quad 这样:
然后再改 index buffer ,并原来drawelement是6个点这里改成12个。
然后就在一个 drawcall 里头渲染出两个 quad 啦!
29. Batch Rendering - Colors
为了解决颜色问题,一种简单的方式就是像之前那样,color 设置成一个 uniform 的,然后两个drawcall,每个 drawcall 前都用 glUniform4f 之类的函数去传递这个 uniform 值。
为了在一个 drawcall 完成,Cherno 认为最好的解决方法就是顶点颜色了,即存在 vertex buffer 中,像这样:
然后这个描述 layout 的地方也要改:
12 是因为 顶点颜色 4 个float,12个字节。
然后传入顶点着色器,再设置 out 把这个颜色信息传递给片段着色器:
结果:
30. Batch Rendering - Textures
一般而言,Texture 需要 glActiveTexture、glBindTexture,把 Texture 传入对应的槽上,供着色器采样。
有很多贴图的时候,一个常用方法是用 Texture Atlas,实际渲染的时候只需要对应的 UV (texcoord)即可。
但是在这里我们仍然有这么多张贴图,所以不是用的这种解决方法。
有了上节的基础后,我们很容易想到,对于 texture 就只需要把对应的 slot 存入 vertex buffer 即可。相当于存入了一个 texture 的索引。
最基本的使用 texture 的方法如下:
先写一个 load texture 的函数:
然后在vertex buffer中,除了 position 和 color,再存入一个 uv(texcoord,即 texture coordinate):
然后是顶点着色器和片段着色器:
(这里还没有采样 texture ,而是简单地把 uv 当作颜色输出了,之后再添加采样)
然后是开始 batch texture:
vb中存入 texture 的索引:
第一个texture对应的是0.0f,第二个是1.0f
然后再添一个 layout 的信息:
接着是顶点和片段着色器:
当然这里只是测试一下,还没有采样。
最后就要把 texture 绑定到 slots 上了,然后采样:
这里使用的是 glBindTextureUnit 函数。
接着是着色器和uniform,可以看到我们还需要先把之前传入的索引值给 int 一下:
这里 glUniform1iv 的v应该是vector的意思,表示是一个数组。相当于我们希望的索引的样子。
结果:
31. Batch Rendering - Dynamic Geometry
之前我们用的传输数据的方法大致是:
注意到在 glBufferData 中我们暗示这是一个 static 的 buffer,传入的数据是由 vertices 指针来指定的。但是实际上我们也可以预先分配一个大小的buffer,然后在每一帧渲染中来填充数据。
并且我们还会发现上面这样有一个弊端,就是我们不能很直观地看出 vertices 里头的数据分别是什么。我们可以这样指定一个 vertex 结构体:
我们用结构体的方式而不是数组的方式,是便于后面赋值。
然后像这样:
注意到这时候我们就暗示这个 buffer 是一个 DYNAMIC 的了,且不需要预先传输数据,所以直接给个 nullptr 就行了。
这里我们用了一个低版本的api:glBufferSubData,有点像那个 glBufferData。在 OnUpdate 中这样写:
这样就在每一帧中传入这个数据了。
不过这样还是不直观,我们不如写一个函数:
于是我们只需要:
实际上我们用这样的方式,还可以很轻松地用 ImGui 去控制:
32. Batch Rendering - Indices
对于 quads 是很容易预知 index buffer 的。因此我们处理起来很简单:
对于 index buffer :
然后改一下我们的 CreateQuad 函数:
在 OnUpdate 中我们这样:
SP32. Writing a BATCH RENDERER in ONE HOUR!
TODO
还没看,待补。。。