做光学设计这些年,我见过太多人在序列模式里得心应手,一转到非序列(NSC)就对着 Object Properties 面板发懵。尤其是“孔径”和“离轴镜面”这两个需求,看似简单,真上手时到处是坑:孔径开了但光线全被挡、离轴镜搭好了但焦点位置错得离谱、坐标断点顺序一换结果完全不一样。这篇就专门写清楚这两件事——在非序列里如何正确创建孔径,以及如何把离轴镜面搭得既快又稳。文章按实操顺序来:先讲清楚非序列孔径的本质,再手把手走一遍创建流程,然后重点拆解离轴镜面的建模关键,最后给一个完整的离轴抛物面案例和常见问题排查表,无论你是刚接触非序列的新手,还是从序列转非序列的老手,都能直接照着做。
1. 非序列里的“孔径”到底是个什么东西
1.1 先转变思路:孔径不是全局光阑,而是物体属性
在序列模式里,我们习惯用 System Explorer 里的 Stop 面来定义光阑,整个系统的入瞳、F 数都围绕它计算。但在非序列模式下,这个概念彻底变了——没有全局光阑,也没有系统入瞳,孔径变成了单个物体内部的属性。
这意味着你不能再想着“我要在系统某处放一个孔径”,而应该想“我要让某个物体上开一个孔,光从孔里穿过去”。这在模拟真实机械结构时特别有用,比如遮光罩、光阑片、镜筒开口、探测器前的冷光阑,本质都是“给物体加孔”。
孔径在非序列里是通过 Object Properties 窗口的 Aperture 标签页设置的。它不是一个独立物体,而是附着在已有物体上的面特征。这个特征定义了一个区域,光线在这个区域内被允许通过,区域外被拦截。这一点非常关键,很多人第一次操作时跑去新建物体,搜“Aperture”找不到,是因为理解错了层级关系。
1.2 哪些物体能开孔、哪些不能
不是所有物体都能加孔径。Zemax 非序列里的物体类型大致分几类,我对常用类型做了一个实际测试总结:
| 物体类型 | 是否支持 Aperture | 典型用途 |
|---|---|---|
| Standard Lens | 支持 | 透镜、窗口、反射镜基底 |
| Standard Surface | 支持 | 反射镜面、分光面 |
| Annular Lens | 支持 | 环形透镜(自带中心孔) |
| Polygon / Extruded Polygon | 支持 | 异形遮光片、多边形光阑 |
| Rectangular Volume / Toroidal | 支持 | 矩形棱镜、环形腔体 |
| Source 类(Source Ray、Source Diode 等) | 不支持 | 光源本身 |
| Detector 类(Detector Rectangle、Detector Color) | 不支持 | 探测器面 |
| Boolean 类(Boolean Native、Boolean Object) | 不支持直接设置 | 布尔运算后的组合体需要在其子物体上分别设置 |
最常用的是 Standard Lens 和 Standard Surface。Standard Lens 适合做带厚度的开孔件,比如一个中间开洞的金属挡板;Standard Surface 适合做薄片光阑或反射镜面。我的经验是:除非需要考虑厚度和侧壁反射,否则一律用 Standard Surface 做孔径,因为它不引入额外折射面,光线追迹更干净,调试也更简单。
1.3 孔径的三个关键参数背后的几何意义
打开 Aperture 标签页,你会看到 Aperture Type 下拉框和一系列参数。Aperture Type 默认是 None,也就是不开孔。我常用的类型有 Circular、Circular Annulus、Elliptical、Rectangular,偶尔用 User Defined。
先解释三个最基本的参数,理解它们比记住界面更重要:
- Min Radius / Max Radius:如果是 Circular 类型,Min Radius 和 Max Radius 定义了开孔的半径范围。Min Radius = 0 时就是普通圆孔;Min Radius > 0 时就变成环形孔,光只能从内外半径之间的圆环通过。
- X Half Width / Y Half Width:Rectangular 类型用到,分别定义矩形孔在本地 X 和 Y 方向的半宽度。注意是半宽,不是全长,设置 10 表示实际尺寸 20。
- Aperture About:这个决定孔径的参考基准。默认是 Mechanical,指孔径基于物体的机械半直径(Semi-Diameter)来约束;也可以改成 Chief Ray,让孔径沿着主光线方向居中。
这里有一个容易踩坑的点:孔径的 Min/Max 值并不会自动裁剪物体的轮廓大小。比如你有一个直径 50mm 的标准透镜,开了半径 10mm 的孔,物体本身还是 50mm 大小,只是光线在离轴超过 10mm 的位置过不去。如果你想同时让物体外形也变小,需要修改物体的 Semi-Diameter 参数,孔径管的是光线,Semi-Diameter 管的才是几何轮廓。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 从创建到验证:孔径实操全流程
2.1 圆形孔径:最简单的开孔
我以一个直径 50mm、厚度 3mm 的 Standard Lens 挡板为例,演示开一个半径 12mm 的中心圆孔。
在非序列模式下,先打开 Object Properties,找到 Aperture 标签页:
- 将 Aperture Type 设为 Circular。
- Min Radius 填 0,Max Radius 填 12。
- 确认不需要考虑孔径边缘的机械倒角,其他参数保持默认。
设置完后,你会发现在 3D Viewer 里物体看起来没有变化,因为孔径默认不显示为实体孔洞,光线追踪时才生效。如果做杂散光分析,这其实是个优点,因为不会引入额外面型导致追迹变慢。
想快速验证孔径是否生效,最简单的办法是加一个 Source Ray 光源,把光线打在挡板上,然后放一个 Detector Rectangle 在挡板后面。如果光线只出现在直径 12mm 的圆内,说明设置正确。如果光线全被挡住,先别怀疑孔径设置,大概率是光源方向和物体法线方向反了(Z 轴朝向问题),后面第 5 节会专门讲。
2.2 环形、矩形和自定义孔径:用表格对照来理解
真实系统中,环形孔径比圆形孔径更常见。比如卡塞格林望远镜的副镜遮挡,或者某些光谱仪里的环形光阑,本质都是环形孔。
环形孔设置方法很简单:在 Circular 类型下,把 Min Radius 设为 15,Max Radius 设为 20,就得到一个内半径 15mm、外半径 20mm 的圆环。注意这里 Min Radius 必须是正数,如果填 0,就退化成普通圆孔。我实际调试时有一回把 Min 和 Max 填反了,程序没报错但光线行为完全不对,这类参数错误很难查,建议填写时多看一眼。
矩形孔径更直观,适用场景是矩形探测器前的挡板、狭缝结构等。比如某光谱仪入射狭缝,X Half Width = 5mm(实际宽度 10mm)、Y Half Width = 0.25mm(实际高度 0.5mm),就成了一个典型的矩形狭缝。这些参数组合用一个表格整理出来,方便查阅:
| 孔径类型 | Min Radius / X Half Width | Max Radius / Y Half Width | 效果 |
|---|---|---|---|
| Circular | 0 | 12 | 直径 24mm 圆孔 |
| Circular Annulus(即 Circular + Min>0) | 15 | 20 | 内径 30mm、外径 40mm 圆环 |
| Rectangular | X = 5 | Y = 0.25 | 10mm x 0.5mm 矩形狭缝 |
| Elliptical | X = 8 | Y = 4 | 长轴 16mm、短轴 8mm 椭圆孔 |
如果这些标准形状都不够用,比如你要模拟一个六边形蜂窝状遮光片,可以用 User Defined 类型,配合自定义的孔径文件(DLL 或者用户自定义孔径),但这种情况比较少。我通常的做法是直接用 Boolean 去切一个多边形实体出来,或者用 Polygon Object 建模,比写自定义孔径快得多。后面第 4 节会展开这个思路。
2.3 如何在 3D 窗口里快速确认孔径形状
孔径默认是“隐形”的,这给调试带来不小的麻烦。我分享两个自己常用的确认方法:
第一个方法是开启 Shaded Model 显示。在 NSC 3D Viewer 里右键,选择 Shaded Model,如果用的是带厚度的物体(比如 Standard Lens),孔径边缘会以实体切口的形式显示出来,一眼就能看出开孔位置和大小对不对。
第二个方法是直接看光线。如果你只想确认孔径轮廓,可以在光源处用 Source Ray,设置一个合理的网格密度,或者用 Source Ellipse 打一束平行光,然后看探测器上的光斑形状。这个方法最直观,也最接近实际工作时关心的结果。
我还习惯在正式仿真前先用一张“纸面光源”验证几何关系。也就是把光源的波长、功率全部设为 1,不考虑材料吸收,单独看光线能不能照到预期位置。这个步骤可以帮你把“孔径设置错误”和“系统其他问题”区分开,排查问题时少走很多弯路。
3. 离轴镜面:思路、公式与坐标断点
3.1 为什么要用离轴镜,以及它和“偏心”的关系
离轴镜面(Off-axis Mirror)是反射系统中特别常见的元件。它的核心价值在于:保留反射镜的聚焦/准直能力,同时避免中心遮挡。 卡塞格林望远镜的次镜会遮住主镜中心区域,导致能量损失和衍射效应;而离轴抛物面镜相当于从一面大抛物面镜上取一块偏离中心的区域,用来反射光线,就不会挡住入射光束。
这里面有个概念必须先理清楚:离轴镜本质上是一个经过了偏心和倾斜的“偏心光阑 + 反射面”的组合。 所谓偏心(De-center),是指反射面的顶点不在系统光轴上;倾斜(Tilt),是指取出来的那一块镜面法线方向与母镜光轴不再平行。因此,在 Zemax 非序列里搭建离轴镜,需要同时控制两个东西:物体的位置偏移量和物体的角度倾斜量。这和热搜词里“zemax如何模拟透镜装配偏心”其实是同一类问题,只不过离轴镜更强调母镜面型与离轴量的几何关系。
3.2 离轴抛物面的核心几何关系
最常见的离轴镜是离轴抛物面镜(Off-axis Paraboloid, OAP),它由一面母抛物面镜截取而来。做 OAP 时,必须清楚三个参数之间的关系:
- f:母抛物面镜的焦距。
- h:离轴量(镜面中心到母镜光轴的垂直距离)。
- θ:离轴角(镜面中心处的法线与母镜光轴的夹角)。
对于抛物面,有一个近似公式非常实用:
[
\tan\theta \approx \frac{h}{2f}
]
这个公式是我在做离轴反射系统时经常用的。比如一面焦距 100mm 的母抛物面,我想取一块离轴量 50mm 的子镜,那么离轴角约为 arctan(50/200),也就是约 14 度。
这里要特别注意:这个公式是近似关系,严格来说,离轴镜几何还取决于母镜顶点、取镜位置和你定义的坐标原点。但做初始设计时用它定参数完全够用,最终反正要用 Zemax 里的坐标断点微调,不必一开始就纠结到亚角秒精度。
3.3 坐标断点(Coordinate Break)是离轴镜的灵魂
在非序列模式里,坐标断点是一种特殊物体,它不改变光的物理路径,但会改变光线的传播坐标。具体来说,你可以通过坐标断点给“接下来的物体”施加一个平移和旋转。序列模式里的 Coordinate Break 面在非序列里对应的是物体类型的 Coordinate Break,用法上有相似性,但逻辑完全不同。
非序列模式下,每个物体都有自己的本地坐标系。默认情况下,物体在全局坐标系里原封不动放置;一旦加了坐标断点,后续物体就被“搬到”新坐标系里。这是非序列建模的核心机制,理解不了它,离轴镜基本搭不对。
坐标断点有三个最关键参数:
- Order:执行顺序。1 表示先平移再旋转,2 表示先旋转再平移。这个顺序看着简单,实际上很多人错在这里。
- X/Y/Z Position:子坐标系原点相对于当前坐标系的位置偏移。
- X/Y/Z Tilt:子坐标系绕当前坐标系的旋转角度。
我强烈建议像做实验记录一样,把“当前坐标系在哪里、下个物体放在哪里”写在纸上,或者用注释物体(Comment Object)在物体列表里标注。不然等你搭了 4~5 个离轴镜之后,坐标关系基本靠猜。
4. 搭建一个离轴抛物面镜的完整案例
4.1 先定参数,再动手建模
我以一个典型 OAP 为例,演示从零到光线追迹的完整过程。
设计指标:
- 母镜焦距:f = 100mm。
- 离轴量:h = 50mm。
- 离轴角:按 arctan(50/200) 算,约 14.036°。
- 子镜口径:25.4mm(1英寸)。
- 光源:在焦点处放一个点光源,经离轴镜反射后准直出射。
建模仿真前先要把母镜半直径想清楚。子镜离轴 50mm、口径 25.4mm,最靠近母镜光轴的一侧是 50 - 12.7 = 37.3mm,最远一侧是 50 + 12.7 = 62.7mm。所以母镜半直径至少要超过 63mm,我直接取 70mm,留足余量。
标准镜面的曲率半径 R 与焦距 f 的关系是 R = 2f,所以母抛物面的曲率半径 = -200mm(反射镜面用负号表示球心在入射光一侧,注意抛物面最好用 Conic = -1 这个参数)。
4.2 物体列表和坐标断点的搭建顺序
这是最容易搞错的地方,我先把完整物体列表列出来,再解释每个坐标断点的作用:
| 序号 | 物体类型 | 关键参数 | 作用 |
|---|---|---|---|
| 1 | Source Point | 位置 (0,0,0) | 放在焦点处 |
| 2 | Coordinate Break | Y Position = 50, Order = 1 | 把坐标系向上平移 50mm(离轴量) |
| 3 | Coordinate Break | X Tilt = -14.036°, Order = 1 | 绕 X 轴旋转 -14.036°,使镜面准直入射光 |
| 4 | Standard Surface | R = -200, Conic = -1, Semi-Diameter = 70 | 反射抛物面 |
| 5 | Detector Rectangle | 放在足够远处 | 接收准直光斑 |
看到这里你可能想问:为什么坐标断点在镜面前面,而且连续放两个?
因为我们要先“移动到一个离轴位置”,再“在这个位置上让坐标系旋转”,这样镜面物体被放入时,它的本地 Z 轴已经指向了预期方向。坐标断点的顺序(Order = 1 表示先平移)确保了两个断点按“先平移、再旋转”的方式叠加。
我在实际调试中经常发现一个问题:如果只用一个坐标断点,同时填 Y Position 和 X Tilt,大概率得不到想要的结果。因为 Zemax 执行旋转和平移的顺序直接影响最终位置。建议把“平移”和“旋转”拆成两个坐标断点,一个做偏心一个做倾斜,逻辑清晰且不容易出错。
注意倾斜角符号。X Tilt = -14.036° 和 +14.036° 效果完全相反,一个让光向上反射,一个让光向下反射。判断符号最直接的方法:先设一个 1° 的小角度,看光线的偏移方向,确认后再改成真实角度。这个习惯能省很多排查时间。
4.3 光线追迹与结果验证
在非序列里搭建完成后,运行光线追迹(Ray Trace),观察 Detector Rectangle 上的光斑:
- 如果一切正常,点光源发出的发散光经 OAP 反射后应该变成一束平行光,探测器上看到一个接近圆形的均匀光斑。
- 如果光斑明显不对称或偏到探测器边缘,很可能是倾斜角符号反了或者离轴量方向错了。
- 如果光线打到镜面边缘直接飞出去了,说明母镜半直径不够大,子镜整个没有被包含在反射面内。
我把这个系统命名为“OAP_Test”,保存后可以继续优化。这时候可以尝试把 Source Point 换成 Source Ray 或 Source Ellipse,看看不同光源形状下准直光斑的变化。
还需要注意一个细节:Standard Surface 默认是两面的,如果你在反射镜后面放探测器,可能会接收到不该有的透射光。非序列里 Standard Surface 其实是一个“薄片”,需要确认它的表面属性。最稳妥的做法是在镜面的 Object Properties 里,把 Face 设置为 Mirror,或者使用专门的双面反射膜层。否则光线可能有一部分从背面透过去,导致探测器上出现诡异的杂散光。
5. 常见问题速查表与排查口诀
5.1 高频问题和对应解法
我积累了一个问题速查表,都是在做非序列孔径和离轴镜时高频出现的:
| 现象 | 可能原因 | 排查/解决方式 |
|---|---|---|
| 孔径设置了但光线全部被挡 | 物体法线方向反了;光源在孔径背面 | 选中物体,检查 Surface 的 Face 方向;把光源移到另一侧或翻转物体 |
| 光线透过孔径区域之外 | Aperture 类型没设对;Max Radius 值大于物体半径 | 回到 Aperture 标签页核对 Min/Max 值;确认 Aperture About 是 Mechanical |
| 3D 窗口看不到孔径 | 孔径默认不显示为实体孔洞 | 切到 Shaded Model;用光线照射验证 |
| 离轴镜反射方向反了 | 坐标断点 Tilt 符号不对 | 先设小角度试方向,再改回实际值 |
| 光束经过 OAP 后不是平行光 | 焦距/曲率半径设置错误;坐标断点旋转量不对 | 核对 R = -200 和 Conic = -1;确认离轴角公式用的 f 正确 |
| 追迹速度很慢 | 光线打到非预期物体上产生大量无效散射 | 在物体属性里设置 Ignore;给物体加 Filter 只追迹需要的区域 |
| 探测器上光斑有明显条纹 | 母镜边缘衍射;采样光线数不足 | 增大光线数;加大母镜半直径减少边缘效应 |
| 不知道光阑面(Stop)怎么设 | 非序列没有全局 Stop | 用物体孔径模拟光阑;或者在序列设计时先定好 Stop,再转换到非序列 |
5.2 几条实操经验
做离轴镜系统时,我觉得最值得分享的经验有两条:
第一,先画一张坐标系关系图再动手。 很多人打开软件就建模,建到一半发现坐标叠了好几层,根本分不清镜面朝向哪里。我的习惯是在纸上画出光源、镜面、探测器的相对位置,标注好每个坐标断点的 Y Position 和 X Tilt。画完再建模,通常一次就能搭对。坐标断点根本不是难在操作,而是难在脑子里的三维几何关系。
第二,从序列模式转非序列模式是一个可靠的高效路径。 如果你已经有一个在序列模式里调试好的离轴系统,可以直接选中整个系统,用 File 菜单里的 Convert to NSC Group,把序列面转换成非序列物体组。这样做的好处是序列模式里的表面偏心(Decenter)和倾斜(Tilt)会被自动换算成坐标断点。转换后你只需要微调孔径和物体属性,不用从零开始搭坐标断点。这对初学者来说,是比手动搭坐标断点稳妥得多的方案。
另外还有一件小事我经常提醒自己:非序列里的单位默认是毫米,但有时候我从别的软件导入模型,长度单位可能变成了厘米甚至英寸。做离轴镜时只要差一个数量级,光线就跑到不知道哪去了。每次建模开始前,先确认 System Explorer 里的单位设置,这个习惯让我少踩了很多坑。
5.3 和热搜词相关的问题结合着看
很多搜索“zemax 非序列 孔径”的人,其实是在做光学系统杂散光分析,或者是要把序列设计转成非序列原型。这个过程有另一个常见需求,就是设置光阑面。序列模式里 Stop 面很好找,但非序列里更常见的做法是用一个虚拟面加孔径,或者干脆用实物挡板。比如你在做一个成像系统,想让杂散光被限制在特定范围,就可以在探测器前面放一个带圆孔的 Standard Surface,孔的半径就等于你希望的像方光阑半径。这比在序列模式里设置 Stop 更接近真实结构,因为后续还能把挡板赋予吸光材料属性,模拟表面反射。
我见过好几个项目,一开始在序列模式里设计得很好,一转到非序列就乱了套,原因就出在光阑概念没切换过来。记住这句话:序列模式的光阑是整个系统的属性,非序列模式的孔径是单个物体的属性。 两者追求的目标一样,但实现路径完全不同。理解了这一点,非序列里的孔径和离轴镜建模基本就通关了一半。
