3. 计算全息图(CGH)生成:点云法、多边形法、层析法

好,咱们进入正题。计算全息图,也就是 CGH,说白了就是让计算机算出一张干涉条纹图。这张图加载到空间光调制器上,就能重建出你想要的三维光场。

我刚开始接触这行时,总觉得 CGH 很玄乎。后来发现,核心问题就一个:怎么把三维物体的信息,编码到一张二维的复振幅分布里。方法有很多,但最经典的三种——点云法、多边形法、层析法——几乎覆盖了 90% 的应用场景。

核心思路:CGH 生成 = 三维物体离散化 + 衍射传播计算 + 编码量化。不同方法的区别,主要在于第一步“离散化”的方式。

3.1 点云法:最直观,但也是最“重”的

点云法的想法很简单。你把三维物体看成一大堆点光源的集合。每个点都朝全息面发射球面波。全息面上的光场,就是所有球面波的叠加。

数学上,就是这样一个累加:

// 伪代码:点云法 CGH 生成
for each point (x_p, y_p, z_p) in object:
    amplitude = A_p
    phase = 2 * PI / lambda * sqrt((x_h - x_p)^2 + (y_h - y_p)^2 + z_p^2)
    for each hologram pixel (x_h, y_h):
        H(x_h, y_h) += amplitude * exp(i * phase)

你看,双重循环。物体有 N 个点,全息面有 M 个像素,复杂度就是 O(N*M)。我几年前做过一个项目,点云只有 10 万个点,全息面 1920×1080,用 CPU 算,一张图跑了 40 多分钟。当时我就想,这要是做实时显示,黄花菜都凉了。

我的经验:点云法适合离线生成高精度全息图,或者物体点数很少(几千个)的场景。如果点数超过 10 万,建议用查表法(LUT)或者 GPU 加速。我曾经用 CUDA 把 40 分钟压缩到 40 秒,但显存占用是个新坑。

点云法的优点很明显:精度高,原理简单。每个点独立计算,没有近似误差。缺点也致命:计算量太大。而且,点云本身没有面信息,重建出来的物体看起来是“悬浮的星星”,缺少表面质感。

3.2 多边形法:用面片代替点,效率翻倍

既然点云法太慢,那能不能用面片代替点?这就是多边形法的思路。你把三维物体表面用三角形网格表示,每个三角形作为一个基本单元,计算它到全息面的衍射场。

这里有个关键技巧:解析衍射公式。对于三角形面片,它的衍射场可以用解析表达式算出来,不需要逐点累加。常用的方法有:

  • Fresnel 衍射解析解:适用于近场,计算快,但需要近似条件。
  • 角谱法(Angular Spectrum):适用于远场,精度高,但需要 FFT。
  • 遮挡与消隐处理:面片之间有前后遮挡关系,需要做深度测试,不然重建出来会“穿模”。

我记得有一次做汽车 HUD 的全息显示,用点云法算一个车标模型,卡得不行。换成多边形法后,面片数量只有点云数量的 1/10,计算时间直接降了一个数量级。而且重建出来的车标,表面连续、光洁,视觉效果好了很多。

方法 基本单元 计算复杂度 表面质感 适用场景
点云法 点 O(N*M) 差(离散点) 高精度、小点数
多边形法 三角形面片 O(K*M),K << N 好(连续表面) 大物体、实时性要求高
层析法 二维切片 O(L * M log M) 中等(层间有串扰) 医学图像、体数据

注意:多边形法虽然快,但遮挡处理是个坑。我曾经偷懒没做深度测试,结果重建出来的物体,后面的面片透过前面的面片显示出来,整个画面像“鬼影”一样。后来老老实实加了 Z-buffer 消隐,才解决问题。

3.3 层析法:把三维问题变成二维问题

层析法的思路更巧妙。你把三维物体沿着深度方向切成很多层切片。每一层都是一个二维图像。然后,对每一层单独计算全息图,最后把所有层的全息图叠加起来。

这样做的好处是:每一层的计算都可以用 FFT 加速。二维 FFT 的复杂度是 O(M log M),比点云法的 O(N*M) 快得多。而且,层析法天然适合处理体数据,比如 CT、MRI 扫描结果。

具体步骤:

  1. 切片:将三维物体沿 Z 轴等间距切片,得到 L 张二维图像。
  2. 衍射计算:对每一张切片,用 Fresnel 衍射或角谱法计算其到全息面的光场。
  3. 叠加:将所有切片的光场复振幅相加,得到最终的全息图。
  4. 编码:将复振幅编码为纯相位或纯振幅全息图。

你想想看,层析法把三维问题拆成了 L 个二维问题。每个二维问题都能用成熟的 FFT 库搞定。我做过一个医学全息显示的原型,用层析法处理 256 层的 MRI 数据,在 GPU 上跑,每秒能生成 30 帧全息图,基本达到了实时。

关键参数:切片间距 Δz 决定了深度分辨率。Δz 越小,深度精度越高,但计算量也越大。一般取 Δz = λ / (2 * NA^2),其中 NA 是光学系统的数值孔径。

层析法的缺点也很明显:层间串扰。因为每一层都是独立计算的,没有考虑层与层之间的遮挡和干涉。重建时,不同深度的物体会互相干扰,产生“重影”。解决方法是引入深度权重或者迭代优化,但这会增加计算量。

3.4 三种方法的对比与选择

说了这么多,到底该用哪种方法?我个人的经验是:

  • 追求精度、物体简单:选点云法。比如做单点或多点的光学陷阱、精密测量。
  • 追求效率、物体有表面:选多边形法。比如做工业设计展示、汽车 HUD。
  • 处理体数据、医学图像:选层析法。比如做 CT/MRI 的三维全息显示。

当然,实际项目中经常混合使用。比如,先用多边形法生成表面,再用层析法叠加内部细节。我最近的一个项目就是这种混合方案,效果还不错。

避坑指南:不管你用哪种方法,量化误差都是绕不开的坎。全息图最终要加载到 SLM 上,SLM 的灰度位深通常只有 8 位(256 级)。计算出来的复振幅需要量化,这个过程会引入噪声。我曾经试过用 4 位 SLM 做实验,重建出来的图像全是噪点,根本没法看。建议至少用 8 位,最好 10 位以上。

3.5 知识结构图

下面这张图总结了三种 CGH 生成方法的核心流程和关系。你可以把它当作本章的“思维导图”。

CGH 生成方法对比 三维物体 点云法 逐点累加球面波 复杂度 O(N*M) 精度高,速度慢 多边形法 解析衍射公式 复杂度 O(K*M) 表面连续,需遮挡处理 层析法 切片 + FFT 加速 复杂度 O(L*M log M) 适合体数据,有层间串扰 全息图 (CGH)

嗯,这张图把三种方法的输入、计算核心、输出都串起来了。你可以看到,无论哪种方法,最终都汇聚到一张全息图上。区别只在于中间那条路怎么走。

3.6 小结

这一章我们拆解了 CGH 生成的三种经典方法。点云法最直接,但计算量最大;多边形法用面片代替点,效率高了很多;层析法把三维问题变成二维问题,适合体数据。没有银弹,只有最适合你场景的方法。