概念页
体素
Voxels
体素是"体积元素",表示均匀三维网格中的一块空间,位置由网格索引隐含。体素是存储体积数据的传统方式,可存占用位、密度、颜色、法线、有向距离等。数据量按分辨率立方增长,常用稀疏体素八叉树 (SVO) 等结构压缩;可由 GPU 体素化生成,并通过光线投射、转多边形、移动立方体或等值面/水平集光线追踪来渲染(RTR4 13.10 节)。
应用
- 规则网格便于整体操作:体积就是内部体素数之和;明确的局部邻域便于用元胞自动机模拟烟、侵蚀、云的形成;有限元分析算抗拉强度;雕刻就是减去体素,把多边形模型放进网格求重叠体素即可建模。这些构造实体几何 (CSG) 操作高效、可预测、保证成功,不像多边形工作流要处理奇异和精度问题。
- OpenVDB、NVIDIA GVDB Voxels 用于电影制作、科学与医学可视化、3D 打印等。
存储
- :每维 1000 就是十亿个位置。《我的世界》以 16×16×256 的区块在玩家周围按半径流式加载,每个体素存方块 ID 和朝向/样式;每种方块有自己的多边形表示(石头是立方体,窗户是 alpha 纹理,草是一对镂空公告板)。
- 体素数据相干性强,且大部分常为空(稀疏体积)。在网格上施加八叉树:最底层 2×2×2 全相同则记在节点上并丢弃体素,向上依次合并相同子节点,只在数据不同处存储,即稀疏体素八叉树 (SVO),天然提供 LOD,相当于三维 mipmap。
体素化
| 方法 | 做法 | 特点 |
|---|---|---|
| 六视图 (Karabassi 等) | 从上下和四个侧面正交渲染六张深度缓冲,比六张都深的体素判为内部 | 快但粗,六个方向都看不到的特征会被误判为内部 |
| 视觉外壳 (Loop 等) | 多张照片提取人物轮廓,按相机位置雕刻掉体素 | 用于真实人物 |
| 切片 / slicemap | 逐片调整近远平面渲染;slicemap 把 32 位目标当 32 个深度位,宽格式 + MRT 可一遍渲染更多层(现代 GPU 单遍可达 1024 层) | 只得到表面(边界表示) |
| 计算着色器 (Schwarz 与 Seidel、Pantaleoni) | 直接构建 SVO | |
| 图像读写 + 保守光栅化 (Crassin 与 Green) | 找出与体素重叠的所有三角形,计算占用、平均颜色和法线;自顶向下只细分非空节点构建 SVO,再自底向上滤波生成 mip | 开源;Rauwendaal 与 Bailey 讨论如何正确使用保守光栅化避免误报;Takeshige 指出可接受少量误差时 MSAA 可替代保守光栅化 |
- 三种体素化类型:实心(测试体素中心是否在内);保守的 26-分离(表面触及的体素都选中,内部与外部体素不共享面、边或顶点);6-分离(可共享边和角)。
- Baert 等的 SVO 可核外 (out-of-core) 构建,不必把整个模型放进内存。
- 动态物体:Gaitatzes 与 Papaioannou 渐进更新——用相机渲染结果和阴影贴图,比记录深度更近的体素清除,深度缓冲点变换到世界空间后设置对应体素。与视点相关,没被任何相机看到的部分未知、可能出错,但足够快,使动态环境中的体素 GI 可交互运行。
渲染实体体素
- 直接光线投射体积,求每个立方体最近的命中面。
- 转为多边形:网格渲染快但体素化时代价更高,适合静态体积。相邻不透明立方体之间的面可剔除,只剩空心外壳;再用简化或贪心合并面。书中例子:17,074 个体素的实心球,每体素 6 面共 102,444 个四边形 → 剔除共享面后 4,770 → 贪心合并为 2,100。
- 移动立方体 (surface extraction / polygonalization):把体素看作点样本,相邻 2×2×2 的八个样本构成立方体角,根据各角内外状态推断穿过立方体的表面:上四角在外、下四角在内则是一个水平正方形;一角在外则是连接该角三条边中点的三角形。八个角位组成 0–255 的索引查表得到三角形数量和位置,非常高效。若角上存有向距离,可沿边插值把顶点放在 0 值处,共享边的立方体顶点位置一致,保证无裂缝。
- 水平集:体素存到表面的有向距离(书中约定内部为正、外部为负),可直接光线追踪零等值面,无需额外属性即可得到曲面和法线。密度数据可选不同密度值定义等值面(如肾脏与肾结石),可调值对科学可视化很有用;也可提取为多边形。
- 锥追踪:Olick (2008) 展示直接光线投射稀疏体素,GPU 上可交互。Crassin 利用 mipmap 般的层次:一条光线沿途感兴趣半径增大,就到层次更高处采样,近似一个锥内的可见性,可快速算软阴影和景深,也有助于抗锯齿和法线过滤。Kasyan 用于面光源阴影(书中对比:Maya 光线追踪 20 秒 vs 体素化 + 锥追踪约 20 ms,模型本身仍用多边形渲染)。GI 应用见动态漫反射全局光照。
- 八叉树之外:八叉树光线追踪需要大量遍历跳转和中间节点。Hoetzlein 显示 GPU 光线追踪 VDB 树(网格的层次)比八叉树快得多且更适合动态体积;Fogal 等用索引表两遍渲染大体积:先找可见子区域 (brick) 并从磁盘流入,再渲染驻留部分。
其他话题
- 多边形化有多种变体和细节问题,例如立方体隔角在内时这些角是否应连起来;Austin 比较后认为立方体移动正方形 (cubical marching squares) 性质最好。
- 光线投射时不必完全多边形化:Laine 与 Karras 给每个体素附一组平行平面近似表面,再用后处理模糊掩盖体素间的不连续;Heitz 与 Neyret 用可线性过滤的有向距离表示,可在任意位置和分辨率重建平面方程和方向覆盖率。
- 阴影:体素可做深度阴影贴图(半透明重叠表面投影);一个体素化场景可测试所有光源的阴影光线,不必每光源一张阴影贴图。眼睛对阴影和间接光等次级效果的误差更宽容,所需体素数据少得多。
- 只记录占用时,许多稀疏节点高度自相似(如墙体在多层上相同),可共享相同子树存成有向无环图 (DAG),大幅减少内存。
PBRT 的视角:作为 majorant 网格与介质存储的体素(PBRT 4e 11.4.3–11.4.5)
- 离线体积渲染中,体素网格有两种用途:存储介质密度/发射(
GridMedium、RGBGridMedium,三线性插值),以及存储每个区域的最大密度作为零散射的局部上界(MajorantGrid)。后者分辨率通常远低于前者,书中云模型每边 64–256 体素最快。 - 光线穿过网格用 3D DDA 逐体素步进:记录每轴下次穿越的参数
nextCrossingT、步长deltaT、步进方向 ±1 和出界坐标;每次选nextCrossingT最小的轴,用三次比较组成 3 位索引查表,避免分支。 - 均匀网格浪费内存;延伸阅读给出自适应层次网格 VDB(Museth 2013)、Field3D(Wrenninge 2015)、GPU 友好的 NanoVDB(Museth 2021)。练习 11.1 提出八叉树或 8/16 位量化密度。透射率估计的细节见 零散射与透射率估计。
出处
- realtime_rendering_4ed.pdf 第 13 章 Beyond Polygons
- PBRT 4e source excerpt: chapter 11 (Volume Scattering)
- Pharr, Jakob, Humphreys《Physically Based Rendering: From Theory to Implementation》第 4 版(MIT Press, 2023)第 11 章 11.4.3–11.4.5 节,pbr-book.org/4ed/Volume_Scattering
相关页面
图形学动态漫反射全局光照Dynamic Diffuse Global Illumination烘焙动辄数小时,拖慢美术迭代,几何在运行时变化或由用户创建时甚至无法预计算。动态漫反射 GI 方法无需预处理或预处理快到每帧可做,主要有:基于虚拟点光源的反射阴影贴图 (RSM)、光传播体积 (LPV)、体素锥追踪 (VXGI) 以及屏幕空间补充(RTR4 11.5.5–11.5.9 节)。图形学点云渲染Point Cloud Rendering点渲染用大量互不连接的三维点表示表面,每个点画成有半径的"溅射斑" (splat)。随着激光扫描、LIDAR、深度相机和摄影测量普及,点云数据可达数千亿点,因此几乎所有系统都用层次结构按预算加载和显示,并用不透明溅射、屏幕空间 AO 或眼罩光照 (EDL) 给无法线的点着色(RTR4 13.9 节)。图形学光栅化Rasterization光栅化(也叫扫描转换)把屏幕空间里带深度和着色数据的顶点,转换成三角形覆盖的像素(片元),交给像素处理阶段。它是几何处理和像素处理之间的同步点:三个顶点在这里组成三角形。图形学滤波阴影贴图Filtered Shadow Maps普通阴影贴图的深度不能直接过滤。滤波阴影贴图存的是深度的某种统计量(矩、指数),可以像普通纹理一样模糊、做 mipmap、用求和面积表,只取一个样本就能得到平滑的半影。代表方法有方差阴影贴图 (VSM)、卷积阴影贴图、指数阴影贴图 (ESM/EVSM) 和矩阴影贴图;共同难点是漏光。图形学纹理过滤与 MipmapTexture Filtering & Mipmap纹理在屏幕上被放大时需要插值,被缩小时一个像素覆盖许多纹素,必须预先滤波才能避免混叠。放大用最近邻、双线性或双三次;缩小的主流方案是 mipmap + 三线性插值,斜视角下用各向异性过滤减少过度模糊。注意:过滤纹理值只在输入与着色结果线性相关时等价于过滤最终颜色。图形学参与介质与体积散射Participating Media & Volumetric Scattering参与介质是充满粒子、通过吸收和散射参与光传输的体积,如空气、水、雾、烟、云;皮肤、蜡等致密材质也有强烈散射——"一切都是散射"。实时渲染主要考虑单次散射:沿视线积分透射率衰减后的内散射光,内散射由相位函数和对光源的可见性(不透明阴影 × 体积阴影)决定。通用实时方案把介质材质和散射结果体素化到相机视锥体素 (froxel) 中逐片累积(RTR4 14.1、14.3、14.8 节)。图形学隐式曲面与有符号距离函数Implicit Surfaces & Signed Distance Functions隐式曲面用 f(\mathbf{p})=0 定义:代入点结果为零即在曲面上。返回到最近表面有符号距离的 f 称为有符号距离函数 (SDF)。它们便于做光线求交、构造实体几何 (CSG)、混合与变形,通常用光线步进可视化,也可用移动立方体等方法转为三角形。图形学空间数据结构Spatial Data Structures空间数据结构把几何体按 n 维空间组织起来,通常是层次化的树,使"几何体是否重叠"一类查询从 O(n) 降到大约 O(\log n)。常见类型有包围体层次 (BVH)、BSP 树(轴对齐的 k-d 树与多边形对齐两种)、四叉树/八叉树(含松散八叉树),以及更偏向组织模型关系的场景图。它们是剔除、光线求交、碰撞检测等加速算法的基础。游戏数学包围体重叠测试Bounding Volume Overlap Tests碰撞检测先测试包围体是否重叠,只有重叠时才逐图元测试;最底层则需要三角形之间、三角形与盒之间的精确测试。本页整理 RTR4 第 22.10~22.13 节:平面与 AABB/OBB(只测两个角的"投影半径"法)、三角形-三角形(Guigue-Devillers 行列式法)、三角形-AABB(13 轴 SAT)、球-球、球-盒(Arvo 及其向量化版本)、AABB-AABB、k-DOP-k-DOP 与 OBB-OBB(15 轴 SAT)。更复杂的 BV(OBB、k-DOP)空体积更少、更紧,代价是测试更贵。图形学网格简化Mesh Simplification网格简化(数据缩减、抽取 decimation)在尽量保持外观的前提下减少三角形数,使应用能在低端机器上伸缩。核心操作是可逆的边折叠,用代价函数(典型是 Garland–Heckbert 的二次误差度量 QEM)排序;它产生的渐进网格可用于连续 LOD 与渐进传输,但自动化并非万能。游戏数学零散射与透射率估计Null Scattering & Transmittance Estimation透射率 Tr=e^{-\tau} 在非均匀介质里没有解析解。直接估计光学厚度 \tau 再取指数会因 Jensen 不等式产生偏差;零散射 (null scattering) 用一个常数上界(majorant)\sigma{maj} 把介质"填满"成均匀介质,得到可无偏采样的积分方程,由此推出 next-flight、比率追踪 (ratio tracking) 和 delta 追踪 (delta tracking) 等估计器。本页对应 PBRT 4e 11.2 与 11.4.3。