一层厚度固定的吸收介质,正面观察和倾斜观察会有不同透射。厚度没有改变,射线在介质内部走过的距离却变长了。如果直接给所有像素乘同一个“透明度”,便丢掉这个几何条件。

本篇选择均匀纯吸收作为第 19–24 篇表面传输的扩展。有限盒子给出真实介质路径,解析指数透射检查分段算法;粗步长产生负透射的失败结果也保存。实验没有入射散射、发光、完整光谱或景深。

从局部损失到指数透射

设沿射线传播的辐亮度为 L(s),均匀吸收系数为 σ_a,单位为距离单位的倒数。没有沿途发光与散射进入时,一个微小距离 ds 的局部变化为 dL=−σ_a L ds。负号表示能量离开当前光束,系数非负。

将方程除以 L 并从 0 积分到 d:

log⁡L(d)L(0)=−σad,T(d)=L(d)L(0)=e−σad.\log\frac{L(d)}{L(0)}=-\sigma_a d, \qquad T(d)=\frac{L(d)}{L(0)}=e^{-\sigma_a d}.

σ_a d 必须无量纲。若世界长度从米改成厘米,吸收系数也必须相应换算;把几何放大一百倍而仍沿用原系数,会改变实际光学厚度。

一般消光 σ_t 还包含散射离开当前方向的损失,σ_t=σ_a+σ_s。但有散射时,其他方向的光也可能进入当前方向,仅乘 T 无法计算完整辐亮度。本文设 σ_s=0,只检查纯吸收,因而输出 L_out=T L_bg 是完整的当前简化模型。

在 σ_a=ln2、d=1 时 T=1/2;距离加倍时 T=1/4。σ_a=0 或 d=0 则 T=1。四个解析值作为程序的第一组检查。透射随距离相乘:T(d₁+d₂)=T(d₁)T(d₂),不能将两段透射直接相加。

对非均匀系数则有 T=exp(−∫σ_a(s)ds),积分需要额外算法。均匀公式不能仅用起点的系数代表任意密度变化;本实验没有这种输入。

有限介质中的距离怎样求

介质盒范围 x,y∈[−10,10],z∈[0,1]。射线 r(t)=o+t v 有自己的有限 [t_min,t_max]。每轴求进入和离开参数,三轴与射线区间取交集,得到 t_enter、t_exit:

d=max⁡(0,texit−tenter)∥v∥.d=\max(0,t_{exit}-t_{enter})\|v\|.

这里的 t 未必是世界距离。使用 v=(0,0,2) 时,参数差只有实际距离的一半,乘回 ‖v‖才正确;第 17 篇“何时要求归一化”的条件仍然适用。

平行于某轴的射线不能除以零:起点在该轴范围外就是未穿过,范围内则不改变区间。起点已在盒内时从 t_min 开始;盒子后半段被 t_max 截断时,只积累被允许的长度。

检查器分别执行正向穿透、斜向穿透、未命中、内部起点、非单位方向以及有限区间截断。起点 z=0.25、方向 (0,0,2),真实距离为 0.75;起点 z=−1、方向 (0,0,1)、t_max=1.25 时,只走入盒内 0.25。二者都不能用固定盒厚 1 代替。

对于本图中从 z=−1 沿 +Z 分量为 cosθ 的单位射线,且没有从盒子侧面提前离开,d=1/cosθ。角度 60°时长度为 2、透射为 1/4。如果角度或起点改变到先穿过侧面,必须重新求有限盒区间,不能继续使用无限平板公式。

分段的两种算法

把距离 d 分成 n 等段,每段用解析透射 exp(−σ_a d/n),相乘得到:

Tn=∏i=1ne−σad/n=e−σad.T_n=\prod_{i=1}^{n}e^{-\sigma_a d/n}=e^{-\sigma_a d}.

均匀条件下,这种分段没有积分截断误差,仅有浮点乘法舍入。增加段数通常不会提高精度;本实验用 σ_a∈{0,ln2,2}、d∈{1,2}、n∈{1,2,4,8,16,32,64,128},共 48 组,最大差约 8.33×10⁻¹⁶。

另一种方法是局部 Euler:一段内用 L_next=L(1−σ_aΔs),于是 T_E=(1−σ_a d/n)ⁿ。它把指数截成一次项,n→∞时收敛到指数,但有限 n 会引入偏差。

当 0<σ_aΔs<1,log(1−x)<−x,所以 T_E<T;在相同正系数下,它吸收得过多。若 σ_aΔs>1,单段因子为负;奇数段数可能得到负透射,偶数段数也可能碰巧变回正数却没有物理意义。

实际 σ_a=2、d=1、n=1 得 T_E=−1,解析 T=e⁻²≈0.135335。程序保留这个值用于失败检查,没有 clamp 成零后把问题隐藏。σ_a d=4、n=4 时每段因子为零,同样无法表示真实的 e⁻⁴。

“结果落在 [0,1]”是必要范围检查,并不证明精度足够。采用正透射的四段 Euler 仍可能明显偏暗;解析参考让这类错误可以数值定位。

图像先保留线性值

图像为 64×64。列 x 对应 θ=(x+0.5)/64×π/3,即从接近 0°到接近 60°;每个像素都从同一起点以指定角度穿过介质,再读取固定棋盘背景。这是一张角度测试图,不是带统一相机投影的三维透视照片。

背景每 8 像素切换明暗,线性 RGB 为 (v,0.6v,0.25v),v∈{0.3,0.9}。每像素先计算解析 T,再乘三个通道;共享 display_pixel 仅在写图时执行一次 sRGB 编码。吸收系数对三个通道相同,所以这是中性衰减,不能把颜色偏暖解释成光谱选择性吸收。

逐像素用独立平面长度 1/cosθ 核对有限盒算法,4,096 个长度误差均小于 10⁻¹⁴。四段 Euler 与解析透射的最大差为 0.0671266。这个数是线性透射差,不是 PNG 码值差,也不是图像感知指标。

三张图同一像素的背景相同,透射随角度变化来自路径增加,棋盘的明暗交替仍来自输入。若在 sRGB 码值上直接乘 T,显示会产生另一种非线性误差;因此原始 CSV 保存 cosθ、路径长度、两种 T、背景 RGB 与输出线性 RGB,PNG 只作为查看结果。

透射和半透明叠面怎样联系

对一块不发光、纯吸收介质,背景项确实可以写成 (1−α)C_bg,令 α=1−T。不过没有前层颜色贡献,不能同时给它随意的白色或雾色 source 项,再称为这个纯吸收模型。

当 d 随视线改变时 α 也必须随之改变。多段纯吸收沿光路相乘,可等价成一个总消光;涉及折射、散射进入和多方向照明时,二维 source-over 的顺序关系不足以表示完整传输。

本代码仅添加三个短函数:有限盒长度、解析透射、Euler 对照,复用射线、线性颜色和文件输出。非法负系数、负距离、NaN 或无限距离会被拒绝;二进制只在仓库 build 运行。没有随机采样或性能结论。

练习与自检

练习一。某均匀介质一米透射 0.8,两米透射是多少?吸收系数是多少?

答案:两米为 0.8²=0.64,σ_a=−ln0.8≈0.223144 m⁻¹。用 0.8+0.8 或 0.8−0.2 都不满足指数传输。

练习二。厚度 1、cosθ=0.5 的无限平板,σ_a=ln2。若误用厚度而不是光路距离,透射偏差是多少?若有限盒侧面先离开又怎样?

答案:真实 d=2、T=0.25,错误 d=1、T=0.5,绝对偏差 0.25。有限盒应取实际进入/离开区间,侧面提前离开会使 d 小于无限平板的 2,不能继续套固定答案。

练习三。σ_a d=3,Euler 至少多少等段才能保证每段因子严格为正?这是否保证给定的误差阈值?

答案:要求 1−3/n>0,即 n>3,整数至少 4。仅保证正性;还要和 e⁻³比较,或用误差分析确定达到所需精度的 n。

复跑记录与出处

在 examples/computer-graphics/ 中执行:

1
2
make build/mediumE03_check
build/mediumE03_check build

累计实现 mediumE03.hpp 及检查器输出三图、48 组分段比较与 4,096 个像素。首次记录保存于本文素材目录:完整报告、分段对照、线性像素,命令和 SHA 在 writing-plans/computer-graphics/evidence/E03-cpu.txt。图像与透射公式都没有借 CPU 验证宣称 GPU 体积渲染。

  • PBRT 4,§11.2 Transmittance,式 11.5–11.7:消光积分、均匀介质指数与分段乘法。本文额外施加纯吸收、固定系数和无发光条件,Euler失败来自独立实验。

系列入口 · 上一篇:透明合成与历史颜色 · 下一篇:GPU工作队列。