本笔记仅为个人的理解,如果有误欢迎指出。
Tiled Deferred Blending
基于瓦片的延迟混合

这篇文章主要技术讲的是,使用多重纹理(Multi-Texturing)代替多次渲染(Multiple Passes)这一建议应用到 Alpha 混合问题上。该技术是在OpenGL ES 2.0 上使用,适用于粒子系统,任意组合的透明纹理四边形,例如:Sprites,UI界面等,不适用于Mesh上。
同时为了适用于移动平台,文章采用了Tile 进行分组的方法。
核心思路还是使用多重纹理代替多次渲染上,现代渲染管线中,在不考虑合批等操作下,每个物体都会在片元/像素 Pass 进行采样对应的一个纹理进行颜色计算,并在后续流程进行混合。基于Tile渲染则在一次Pass 渲染中通过采样多个物体的纹理,在当前Pass中完成后续的混合计算。
算法:
该算法基于一种思想:将整个渲染区域划分为多个较小屏幕空间的Tile。
一旦Tile 布局确定后,整个算法可以概括为以下几个步骤:
1,CPU计算每个Sprite 在屏幕空间的覆盖范围。
2,对于每个Sprite,找到他覆盖到的Tile,将sprite的ID存储到受影响的Tile的列表中。
3,(可选)优化TIle网格,将可以合并的Tile单元进行分组。
4,对于每个Tile,计算渲染该Tile内所有Sprite所需的数据
5,对于每个非空的Tile,每个片元利用插值后的纹理坐标采样绑定的纹理,并手动完成颜色混合
1~4 步骤中,在旧版本的OpenGL 中这些计算都需要在CPU上完成,新版本则可以考虑使用Computer shader

Tile布局优化方案:对于sprite的ID列表相同的Tile就将其合并成一个大块的Tile

Tile 布局 :

| 布局 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 水平切片(Horizontal Tiles) | Draw Call 较少 | 对竖直分布的 Sprite 利用率低 | 云层、地平线等横向场景 |
| 垂直切片(Vertical Tiles) | Draw Call 较少 | 对横向分布的 Sprite 利用率低 | 瀑布、UI 列表等竖向场景 |
| 网格布局(Grid) | Tile 更精细,空白区域更少 | Tile 数量增加,管理成本更高 | 大多数通用场景(最常用) |
| 全屏 Tile(Fullscreen Tile) | 只有一次 Draw Call | 每个像素都要处理所有 Sprite,效率最低 | Sprite 很少时才可能适用 |
理想的Tile 布局应当具备以下两个特点:
1,尽量减少被部分覆盖的Tile
2,尽可能减少Draw Call的数量
图层支持:
Tile 有个优点就是同一个位置可以加入多个Tile片,当Pass支持的纹理小于当前Tile存在的纹理数量时,可以划分多几个Tile来渲染。要注意,分层后的Tile要确定好渲染顺序。

关于深度:
由于当前渲染的是屏幕空间Tile,对于深度就必须要自己手动实现深度测试。
具体做法如下:
在Fragment Shader 中绑定一张深度纹理并采样,每个片元就能把自身的深度值与对应的Tile 的深度进行比较。
