布告牌(Billboards)
布告牌(Billboard)是一种始终面向观察者的纹理四边形,常用来渲染图标、文字、粒子等。
本章重点介绍如何用 GPU 高效地渲染大量带有不同纹理的布告牌,并在此基础上实现文字标签。
11.1 基础渲染流程
| 实现位置 | 思路 | 优劣 |
|---|---|---|
| CPU | 每帧计算顶点并上传 | 过时;CPU 和总线负载高 |
| Point Sprite | 固定功能点精灵 | 已废弃;不支持旋转/缩放 |
| 顶点着色器 | 四点四边形,偏移 | 通用,但顶点重复 4× |
| 几何着色器(推荐) | 每布告牌 1 点 → 输出 4 点四边形 | 现代硬件最优;内存/指令最少 |
几何着色器核心步骤
- 顶点输入
仅传入布告牌的 世界坐标 和可选 纹理坐标/偏移。 - 窗口坐标变换
在顶点着色器完成model → clip → window转换。 - 四边形生成
在几何着色器用 像素尺寸 沿窗口坐标轴挤出四角,输出三角形带(图 9.3)。 - 片元着色器
采样纹理,alpha 丢弃,再乘用户颜色。
注意:
- 输出标量数 ≤ 24(4 顶点 × 6 标量)可在多数 GPU 全速运行。
- 无索引数据,节省显存。
11.2 减少纹理切换
| 技术 | 描述 | 适用 |
|---|---|---|
| 按纹理排序 | 同纹理连续绘制 | 纹理种类少时有效 |
| 纹理图集(Atlas) | 多个小图合并为一张大纹理 | 通用,最灵活 |
| 3D 纹理 / 纹理数组 | 每片层存一张图 | 所有图必须同尺寸,mipmap 麻烦 |
9.2.1 运行时图集打包
- 问题:NP-hard 二维装箱。
- 贪心算法(OpenGlobe 实现):
- 按高度降序排序输入图。
- 预估正方形边长
sqrt(sum(area))。 - 从左到右、自上而下逐行填充;行高由该行最高图决定。
- 可选:旋转 90°、双向蛇形填充,进一步减少空隙。
- 结果:
- 支持任意尺寸、非 2 的幂。
- 运行时或离线生成均可。
11.3 原点与偏移
- 需求:图标 + 标签并排(图 9.8)。
- 方案:
- 每个布告牌存 原点枚举(左/中/右 × 上/中/下) + 像素偏移。
- 几何着色器在窗口空间应用原点 + 偏移,实现任意布局而无需合并纹理。
11.4 文字渲染
文字可视为带纹理的布告牌。两种主流方法:
| 方法 | 流程 | 纹理需求 | 顶点/像素权衡 |
|---|---|---|---|
| 整句缓存 | 一句话一张小图 → 单布告牌 | 可能重复,占用大 | 顶点少,纹理多 |
| 逐字符缓存 | 字符级图集 → 每字符一布告牌 | 仅 1 张图集 | 顶点多,纹理少,支持逐字动画 |
- 字符级实现:
- 图集存所有字形(图 9.12)。
- 顶点存 公共世界位置 + 字符偏移 + 字符纹理坐标。
- 几何着色器按字符宽度水平排布。
- 商用惯例:Insight3D、大多数引擎采用“逐字符”。
小结
- 几何着色器 + 纹理图集 是目前最快、最灵活的布告牌方案。
- 文字 = 布告牌的特例,只需额外图集与字符偏移逻辑。
- 运行时图集打包支持动态内容,贪心算法已足够实用。
1746

被折叠的 条评论
为什么被折叠?



