从 LM-63 到实时预览:Unity IES 光度文件编辑器

IES 文件保存的不是一张灯光纹理,而是灯具在不同空间方向上的光强分布。这个工具的目标,是让技术美术和灯光美术无需离开 Unity,就能读取 IESNA LM-63、检查光度曲线、观察真实落地形状、编辑能量分布,并把结果重新保存成可被其他渲染器继续使用的标准文件。

Unity IES 光度文件预览与高级曲线编辑界面
工具同时展示光度学数据与可编辑曲线。所有截图均来自独立测试资源,不包含项目场景、业务资产或内部路径。
IESNA LM-63文本解析与标准回写
C-γ Table二维坎德拉分布
2D + 3D曲线、投影与空间预览
Editor Only不引入运行时成本

问题:一份 IES 文件为什么难以直接判断

传统的纹理预览适合颜色和法线,却不适合 IES。IES 记录的是光强 I(C, γ)γ 表示相对灯具光轴的垂直角,C 表示绕光轴旋转的水平角。一个值的单位是 candela,它描述“向这个方向发出多强的光”,而不是屏幕上的最终亮度。

因此,工程里真正需要回答的是三类问题:文件是否有效,光束在角度域里是什么形状,以及它打到真实表面后会形成怎样的照度。只有极坐标图会缺少空间直觉;只把 IES 挂到场景灯光上,又会被曝光、材质、天气和渲染管线干扰。工具把这三层拆开,分别提供数据、物理投影和独立 3D 预览。

LM-63 TextHeader / TILT / Angles / Candela

IESDataC-γ 二维光强表

PreviewPolar / Surface / 3D

EditScale / Spread / Shift / Curve

Serialize重算峰值与光通量

第一层:把 LM-63 解析成可工作的光度数据

解析器先读取版本头与方括号关键字,直到遇到 TILT=;随后把换行、空格、制表符和逗号统一视为数值分隔符。这样可以兼容不同厂商导出时的折行差异。数值读取使用 InvariantCulture,避免编辑器系统语言改变小数点语义。

数据段 主要字段 工具中的用途
Header / Keywords LM-63 版本、灯具名称、厂商描述 资产识别与保存时保留元数据
Photometric header 灯数、流明、倍率、角度数量、Type、单位和灯具尺寸 校验文件、显示摘要、确定数组尺寸
Vertical angles γ[0..V-1] 描述离开光轴的采样角
Horizontal angles C[0..H-1] 描述绕光轴的采样平面与对称性
Candela table cd[H,V] × multiplier 预览、编辑与保存的核心数据

读取坎德拉表时,原始 multiplier 会立即乘进每个样本,内部始终使用绝对光强。同时遍历整张表得到峰值 candela 及对应的 (C, γ),后续的归一化、曝光参考和光束角计算都依赖这一组统计数据。

TILT 的处理边界

解析器能够跳过文件内嵌的 TILT 数据,使预览不会因额外数值段错位;但编辑和保存只允许 TILT=NONE。这是刻意的防御性约束:没有完整实现倾斜灯具的变换语义前,不应该写出看似合法、实际方向错误的文件。

第二层:极坐标图把“光往哪里走”画出来

极坐标图以灯具光轴为 0°,绘制 C0 和 C90 两个典型截面。半径表示光强,角度表示 γ。线性模式适合比较绝对能量,Log 模式能把弱尾部拉出来检查;Normalize 则让不同功率的灯具可以只比较光束形状。

IES C0 与 C90 平面的极坐标光度曲线和元数据
极坐标曲线与文件摘要并排显示。示例为轴对称分布,因此 C0 与 C90 重合;工具仍明确标记两个光度平面的语义。

Beam Angle 和 Field Angle 不是额外存储的字段,而是从峰值向两侧寻找阈值交点得到的派生指标。工具分别使用峰值的 50% 和 10% 作为阈值,用于快速判断主光束宽度与外围有效范围。它们适合资产筛选,但不能替代完整曲线,因为两个光束角相同的灯具仍可能拥有完全不同的肩部和尾部。

第三层:从坎德拉到表面照度

为了回答“打到地面或墙上是什么样”,工具提供纯 CPU 的表面投影。每个像素先从灯具位置构造方向,换算为 (C, γ),再在坎德拉表中做双线性插值。最终照度遵循点光源的基本关系:

E(p) = I(C, γ) · max(0, N · L) / r²

其中 I 是该方向的光强,N · L 是表面入射余弦, 是平方反比衰减。预览再用峰值和灯距做自动曝光,并经过指数型 tone mapping 与 sRGB 转换。这样既保留光束形状,又不会让不同量级的 IES 在编辑器里直接全白或全黑。

对称性展开是正确采样的关键

IES 文件为了节省数据,常常只保存部分水平角:一行代表轴对称,0° 到 90° 代表四象限对称,0° 到 180° 代表双边对称,接近完整一圈则按全方向数据处理。采样任意 C 角时,工具先按文件声明隐含的对称性折叠到已存区间,再在 C 和 γ 两个方向插值。忽略这一步,预览会出现缺扇区、断边或左右不一致。

第四层:不依赖渲染管线的 3D 实时预览

场景预览没有创建 Unity Light,也不要求 HDRP 的 IES Profile。CPU 先把分布烘焙为一张 360 × 181RGBAHalf 查找纹理,U 对应 C 角 0° 到 360°,V 对应 γ 角 0° 到 180°,R 通道保存相对峰值归一化的光强。

IES 灯具位置方向与地面照明的交互式三维预览
灯具位置、Yaw、Pitch 和曝光可以实时调整;相机支持环绕、缩放和 FOV 修改。预览关注光斑方向与空间尺度,而不是复刻某条项目渲染管线。

GPU 侧通过一次 Graphics.Blit 执行全屏 ray caster。每个像素构造相机射线,与地面平面求交,在灯具局部基底中恢复 C 和 γ,再查询 IES LUT 并计算 I · cosθ / r²。地面网格只用于提供尺度与透视参照。因为整个过程只依赖一个隐藏 Shader 和一张 512² RenderTexture,所以 Built-in、URP 与 HDRP 编辑器环境都能使用同一套预览。

为什么不直接复用项目灯光

独立预览把 IES 本身与场景变量隔离开。它不会受到曝光卷积、阴影、材质 BRDF、体积雾或天气系统影响,因此非常适合判断“文件是否正确”。最终落地仍需回到目标渲染管线验收,两者解决的是不同问题。

编辑:修改的是能量分布,不是灯的 Transform

编辑器始终保留一份 Source,并在每次参数变化时深拷贝出 Edited Snapshot。所有操作都作用于坎德拉表,因此保存后的光束形状可以被其他支持 IES 的软件复现,而不是只在当前 Unity 场景里生效。

IES 基础编辑参数,包括亮度、展宽和二维光束偏移
基础编辑面向高频操作:整体亮度、光束展宽,以及不移动灯具 Transform 的前后/左右光束偏移。
参数 实现方式 结果
Brightness 所有采样乘以全局 Scale Factor 保持形状,改变绝对 candela
Beam Spread 按比例反向重采样 γ 角距离 大于 1 展宽,小于 1 收窄
Push Forward / Sideways 把输出方向旋转回源分布后采样 光轴不动,能量峰值在 IES 内偏移
γ Remap 按垂直角应用 AnimationCurve 倍率 独立调整中心、肩部与远端能量
C0 / C90 Freehand 用归一化曲线覆盖指定光度平面 直接塑造两个关键截面

二维光束偏移是其中最容易被低估的一步。工具先把目标偏移量组合成一个峰值方向,再通过 Quaternion 构造“目标峰值到原始光轴”的旋转。对输出表中的每个方向,先做逆向方向映射,再回到源表双线性采样。这样避免直接平移数组造成角度空间变形。

轴对称文件只有一行水平角,无法表达偏向某个 C 平面的光束。一旦发生非零二维偏移,工具会把它扩展为 0° 到 360°、每 10° 一行的完整表,再进行方向重采样。这个扩展会增加文件数据量,却是打破轴对称后保持信息完整所必须付出的成本。

IES 高级 γ 重映射与 C0 C90 自由曲线编辑
高级模式允许按 γ 角做乘法重映射,并直接编辑 C0/C90 曲线。界面根据轴对称、四象限、双边或全方向数据自动限制不可表达的通道。

保存:不只把数组写回文本

序列化器保留原有关键字,把内部的绝对 candela 写回文件,并强制 multiplier 为 1,避免“数组已经乘过倍率、文件又重复乘一次”的二次放大。保存时还可以追加一条编辑历史说明;界面默认提供 Save As,并把覆盖原文件放在明确的危险操作中。

编辑后的总光通量通过球面积分重新估计:

Φ = ∫₀²π ∫₀π I(γ, C) · sin(γ) dγ dC

离散实现沿相邻 γ 区间积分,并对已存 C 范围求平均,再利用轴对称、四象限或双边对称扩展到完整 2π。结果乘以 Ballast Factor,写回 Lumens Per Lamp。峰值 candela 与峰值角度也会重新遍历计算,保证文件摘要与编辑后数据一致。

模块拆分与职责

模块 职责 设计价值
Parser / IESData LM-63 读取、字段归一化、峰值统计 让所有视图共享同一份明确数据模型
Plot Renderer C0/C90 极坐标曲线、线性/对数显示 快速检查角度域分布
Light Projector 对称性映射、双线性采样、地面/墙面照度 提供不依赖场景的物理形状参考
Scene Previewer + Shader LUT、全屏射线、相机和灯具交互 跨管线提供实时空间反馈
Editor 非破坏重采样、曲线覆盖、对称性扩展 把艺术控制落到标准光度数据
Serializer 元数据保留、流明积分、LM-63 回写 形成可交付、可复用的闭环

性能与工程边界

这是 Editor-only 工具,不进入 Player,也不会给游戏运行时增加 Pass、Draw Call 或常驻纹理。解析与编辑的主要复杂度是 O(H × V);默认 LUT 约 6.5 万个采样,3D 预览是一张固定 512² RT 的全屏 Pass。CPU 表面投影默认 256²,最大限制为 1024²,只有重建时发生。

边界 当前策略 后续可扩展方向
TILT 非 NONE 允许安全读取,禁止编辑保存 实现完整倾斜几何与外部 TILT 文件解析
Photometric Type A/B 保留数据;空间预览按常用 Type C 语义解释 加入 A/B 到 Type C 的坐标转换
异常水平角表 标准 0/90/180/360 对称;其他范围钳制 按 LM-63 边界情况增加更严格校验
高分辨率 CPU 投影 同步生成并限制分辨率 编辑防抖、Jobs/Burst 或 GPU Compute
最终画面一致性 独立曝光与简化地面模型 增加目标管线适配层与基准场景对照

结论

这套工具的价值不在于多做了一个 IES 缩略图,而在于建立了一条完整、可验证的数据链:从标准文件读取方向光强,经过对称性正确的采样与物理照度预览,再以非破坏方式重塑分布,最后重算派生量并写回标准格式。它把灯光资产从“只能导入后试效果”的黑盒,变成可以检查、比较、编辑和交付的数据资产。

对生产工具而言,最重要的并不是把所有边界一次性覆盖,而是明确哪些数据已经被正确解释、哪些操作会改变物理量、哪些格式暂时只读。正是这些约束,让实时反馈不会以牺牲文件可靠性为代价。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注