体数据 = 标量场 + 规则网格
最常见的体数据是把空间切成小立方体,每个小格存一个数值 —— 这就是体素(Voxel),类比像素的 3D 版本。所有体素连起来构成标量场 f(x,y,z):CT 里是 Hounsfield 单位,MRI 里是信号强度,气象里可以是温度或水汽密度。
- 分辨率决定细节:如 512×512×300 已是近 8000 万体素
- 间距(spacing)不一定各向同性,层厚常大于面内像素
- 标量本身没有颜色,颜色是后面“赋予”的
体渲染把 CT、MRI、地震、气象这类三维标量场,不抽成一张“皮”,而是让光线穿过整个数据体,沿途不断采样、着色、累积透明度,最终合成一幅能同时看到外壳、内部结构与密度变化的图像。这一页把概念、光学模型、算法与术语一次讲清。
把数据想成一团有颜色的雾:每个位置都有密度。光线穿过雾时,前面的雾会遮挡后面、也会被后面透过来的光点亮 —— 体渲染算的就是这件事。
与面渲染最大的区别:面渲染只保留等值面,体渲染保留整条光线上的信息,所以能做半透明分层、密度渐变与内部透视。
体渲染处理的对象不是三角形,而是一个定义在三维空间上的函数。
最常见的体数据是把空间切成小立方体,每个小格存一个数值 —— 这就是体素(Voxel),类比像素的 3D 版本。所有体素连起来构成标量场 f(x,y,z):CT 里是 Hounsfield 单位,MRI 里是信号强度,气象里可以是温度或水汽密度。
面渲染先提取一个阈值对应的表面(如骨骼表面),再用光照画这张皮 —— 快、边界锐利,但阈值之内/之外的信息全丢了。直接体渲染(DVR)不提取表面,每条视线都穿过全量数据做积分,因此能同时呈现皮肤、肌肉、骨骼的半透明叠加。
采样点往往落在体素之间,需要插值。顺序不同,结果差别很大:
体渲染里一个采样点贡献多少,不只看它自己的不透明度 α,还看它前面已经累积了多少遮挡。前面越不透明,后面贡献越小 —— 这就是前向后合成(Front-to-Back Compositing),也是能做早期终止优化的根本原因:累积不透明度接近 1 时,后面再算也是浪费。
所有 DVR 实现,本质都在数值求解同一个积分。理解积分,算法只是不同的求解策略。
光线以步长 Δs 前进,在每个采样位置用三线性/高阶插值取标量值。
传递函数把标量(+梯度)映射为颜色 RGB 与不透明度 α。
用梯度当法线,做漫反射/镜面反射,可选环境光遮蔽与阴影。
沿光线按前→后或后→前累积颜色与透明度,得到像素值。
离开数据体、或累积 α≈1 时停止,避免无效采样。
C = ∫₀ᴸ C(s) · α(s) · exp( − ∫₀ˢ α(t) dt ) ds
C(s) 该点发射的颜色(经传递函数 + 着色)
α(s) 该点的不透明度 / 消光系数
exp(−∫α) 从该点到眼睛还剩多少透过率
L 光线在体内的总长度离散化后就是熟悉的迭代:C ← C + (1 − A) · αᵢ · Cᵢ A ← A + (1 − A) · αᵢ 其中 A 为已累积不透明度。
真实光在介质里有吸收、发射、散射、反射四件事。经典 DVR 只保留吸收 + 发射,忽略散射 —— 假设每个体素自己发光、同时吸收穿过它的光。这个简化让积分可沿单条光线独立求解,才有了实时交互。
同一份数据,换一条传递函数,看到的器官完全不同。它是体渲染里最重要、也最难调的一步。
1D TF:横轴是标量值,纵轴是不透明度,再配一条颜色曲线。把骨骼标量区间拉高 α、软组织压低,就能“透过皮肤看骨头”。本质是窗宽窗位的彩色、非线性推广。
2D TF:横轴标量、纵轴梯度幅值。均匀组织内部梯度低、组织交界梯度高 —— 用梯度这一维,就能只强化边界、抑制内部噪声,临床上对血管与器官轮廓尤其有效。
自动 TF 设计(基于直方图、聚类、信息熵)是长期研究方向,但临床落地仍以预设 + 交互微调为主。
按“遍历顺序”分类最清晰:以图像为序、以对象为序、混合方法。实时系统今天几乎全是 GPU 光线投射。
| 方法 | 原理一句话 | 优势 | 代价 / 局限 | 典型场景 |
|---|---|---|---|---|
| 光线投射 Ray Casting / Marching | 图像序:每个像素发一条光线,沿线步进采样并合成。GPU 并行天然契合。 | 画质最高、支持任意 TF 与着色、易做空间跳跃 | 采样数 ∝ 分辨率×步数,大数据需加速结构 | 现代 DVR 事实标准 |
| 纹理切片 Texture-based Slicing | 用一组平行于视面的多边形切片采样 3D 纹理,靠硬件混合合成。 | 实现简单、老硬件也能跑、混合免费 | 视角切换有 popping、着色与跳跃难做 | 早期 GPU、嵌入式 |
| 抛雪球 Splatting | 对象序:每个体素投成一个带足迹的雪球 splat, splat 之间混合。 | 只处理非空体素、渐进细化方便 | 排序与足迹计算复杂、易有伪影 | 稀疏数据、历史方案 |
| Shear-Warp | 把体数据错切到易于逐片扫描的坐标系,先合成中间图再 warp 回正。 | CPU 时代最快、缓存友好 | 画质与灵活性受限,GPU 时代已淘汰 | 经典教材、历史实现 |
| 等值面提取 Marching Cubes | 不做体积分,先按阈值抽三角面,再走传统面渲染管线。 | 边界锐利、可测可打印、可与手术规划对接 | 丢内部信息、阈值敏感、拓扑噪声 | 骨骼、植入物、3D 打印 |
每条光线只取沿途最大标量值,不做透明度累积。高密度结构(造影血管、骨)极醒目,计算最便宜。
完整的发射–吸收积分 + 传递函数。有深度、有层级、能半透明,是“体渲染”狭义所指的方法。
沿任意平面重切数据体,得到轴/冠/矢或斜位、曲面断层图。不是投影,是“换个方向看切片”。
拖动步长、切换合成模式,看同一条光线如何得到完全不同的像素 —— 这是理解采样误差最快的方式。
下方为合成密度截面(两团高密度 + 背景)。中线为当前光线,圆点为采样位置。
步长越大越快,但越容易跨过薄结构(欠采样 → 断裂、木纹伪影)。步长小于体素尺寸约 0.5–1 倍是常用起点。
实际 α 需按步长做校正:α' = 1 − (1−α)Δs/Δs₀,否则改步长就会改亮度 —— 这是最常见的实现 bug。
A = 0.00 · 透过率 100%
三线性插值是默认重构核:便宜、连续,但会平滑高频。追求锐利可用高阶 B-spline / Catmull-Rom,代价是过冲与计算量。
预积分(Pre-integration)把一个步长区间内的积分预先算进 2D/3D 查找表,用区间两端标量查表代替单点采样 —— 同步长下画质显著更好,尤其消除木纹与阶梯伪影,是高质量 DVR 的标配。
没有着色,DVR 只是一团彩色烟雾。立体感主要来自梯度着色,而不是颜色本身。
标量场的梯度 ∇f 指向密度增长最快的方向,与等值面垂直,天然可当法线用:中心差分在采样点邻域估梯度,再代入 Phong / Blinn-Phong 做漫反射 + 高光。
与近年的 3D Gaussian Splatting 区分:3DGS 是用显式高斯基元拟合外观做新视角合成,不求解体渲染积分,也不保证密度物理量守恒 —— 两者问题定义不同,不能互相替代来谈“准不准”。
用上方搜索框或分类筛选。每个术语给一句可用的定义,而不是词典式复述。
按这个顺序学,能避开大多数人卡住的地方。
体素、spacing、标量范围、直方图。不会看直方图,就不会调传递函数。
手推一遍离散合成迭代,弄清 α 校正与前后合成顺序 —— 这是所有 bug 的源头区。
片段着色器里 100 行就能跑通:光线求交、步进、查 TF、合成。跑通后再谈加速。
预积分、空间跳跃、砖块调度、渐进渲染。工程优化必须建立在前三步正确之上。
体渲染 = 对标量场沿视线做发射–吸收积分;传递函数决定可见性,梯度决定立体感,步长与预积分决定画质下限,空间跳跃与早期终止决定速度上限。MIP 看最亮,DVR 看层级,MPR 看断层,等值面看硬边界。