光度学光源 (IES)
概述
在基于 daNetGame 的项目中,除了聚光灯或泛光灯等传统光源外,您还可以使用 IES 格式 添加光度学光源。
IES 文件实质上是一个文本文件,它根据 3D 空间中的角度定义来自源的光强度分布。格式规范可以在 这里找到。
您可以从 Internet 下载现成的 IES 文件,因为大多数照明制造商都为其产品提供 IES 配置文件。此外,还有大量的 IES 库可用,其中包含数千个适合各种可视化需求的配置文件。
或者,您可以使用各种编辑器手动创建 IES 配置文件。我用过这个 IES 生成器,它使用起来很简单:你可以用鼠标在垂直平面上绘制光线轮廓。 然后,生成的轮廓将围绕垂直轴“旋转”(类似于 3ds Max* 中的 Lathe 修改器,它从样条线创建 3D 对象)。 但是,此工具无法沿两个轴创建非对称 IES 剖面,这意味着墙壁和地板上的光分布不能同时变化。

如果需要更复杂的 IES 配置文件,则必须查找并测试其他软件,或搜索现有的 IES 文件。对于更简单的任务,此工具就足够了。本文末尾提供了示例。
在基于 daNetGame 的项目中集成 IES 文件
下载或创建 IES 文件后,将其放在以下目录中:
/<project_name>/develop/assets/manmade_common/textures/ies
全局 foled.blk 文件中的以下块处理 IES 文件的处理:
virtual_res_blk{
find:t="^(.*)\.ies$"
className:t="tex"
contents{
addrU:t="clamp"; addrV:t="clamp"
convert:b=yes
buildIES:b=yes
textureWidth:i=128
textureHeight:i=128
}
}
这意味着在构建过程中,每个 IES 文件都会转换为 L8 格式的简单 128x128 像素纹理。
有关引擎实现的详细信息,请参阅 Photometry部分。
在光源中使用 IES 文件
要将特定的 IES 文件用作光源,只需在模板的 light.texture_name 变量下指定其名称并编译 vroms。
基于 daNetGame 的项目的轻量级模板位于:
/<project_name>/prog/gameBase/content/common/gamedata/templates/_lights.blk
例如,带有两个灯的壁灯将如下所示:
light_sconce_medium{
_extends:t="omni_light"
light.max_radius:r=3.5
light.offset:p3=0, 0, 0
light.color:c=255, 152, 70, 255
light.brightness:r=2.5
light.contact_shadows:b=false
light.texture_name:t="ies_doublelamp_sconce_a"
}
关于 IES 和 Omni 灯的重要说明
光度学灯光只能应用于泛光灯,这意味着它们不会投射阴影。因此,它们不适合在灯、聚光灯或类似光源中使用。相反,它们应该保留用于艺术照明效果。
IES 使用示例
以下是一些示例 IES 配置文件(从左到右:Asset Viewer、在 IESGen 4 生成器中查看,并在游戏中查看):
ies_doublelamp_sconce_a
ies_multilamp_sconce_a
ies_singlelamp_sconce_a
ies_singlelamp_sconce_b
ies_hand_lantern_a(最初用于煤油灯,但最终用于紧急出口标志)。
在其中一个示例中,为了在天花板上获得不均匀的照明,我只需将光源水平旋转 90 度即可。
ies_monitor_a
如上一个示例所示,即使在表格下方也有光,因为泛光灯不会投射阴影。但是,结果是可以接受的——肯定比将带有刺眼阴影的聚光灯放在那里要好。
IES 的局限性
请务必了解,单个 IES 配置文件无法完美地重现多源或基于表面的灯光的复杂灯光模式。光线总是从单个点辐射,而不是从多个光源或一个区域辐射。例如,使用单个 IES 配置文件表示具有许多小灯泡的壁灯始终是一种折衷方案。您会注意到光线是从中心发出的,而不是从每个单独的灯泡发出的。尽管如此,结果在视觉上仍然是可以接受的。

光度法
基于 daNetGame 的项目支持光度学文件来描述泛光灯的光分布。本文介绍了如何使用它们。
支持的文件类型
IES
文件详情: Lifewire 关于 .ies 文件的文章
文件放置
光度法文件应放置在适当文件夹下的 develop/assets/ 目录中。要导出这些资源,请将以下块添加到.folder.blk中:
virtual_res_blk{
find:t="^(.*)\.ies$"
className:t="tex"
contents{
convert:b=yes
buildIES:b=yes
textureWidth:i=128
textureHeight:i=128
blurRadius:r=3
phiMin:r=0
phiMax:r=360
thetaMin:r=0
thetaMax:r=180
edgeFadeout:r=-1
}
}
确保资产名称具有 ies_ 前缀。没有它,它们将无法在游戏中被识别为光度纹理。
textureWidth 和 textureHeight组件全局定义生成的纹理的分辨率。虽然可以导出不同分辨率的光度法纹理,但游戏将无法加载它们。如果创建其他块来解析 ‘.ies’ 文件或稍后添加其他类型,请确保所有光度法纹理保持相同的分辨率。
聚光灯和特殊选项
对于聚光灯,光线集中在中心周围,从而提高纹理质量。IES 导出器支持将光强度限制为围绕视图方向的特定角度(例如,180 度以将光限制为向前方向)。
如何使用
此选项必须单独应用于灯光:
将
.ies文件放在适当的目录中(带有相应的.folder.blk进行处理)。打开Asset Viewer并选择 IES 资源。
检查右侧面板中的光度信息。
前三个值(模糊半径、缩放、旋转)显示当前配置。
底部的两个值表示计算出的最优值。
创建一个虚拟资产
.blk文件,例如ies_flashlight_a.tex.blk代表ies_flashlight_a.ies。使用最佳值指定
iesScale:r和iesRotation:b属性。(目前,此过程不是自动化的。

rotation 值还会隐式调整缩放比例。这些指定的值应接近 Asset Viewer 中显示的最佳值。如果值太低,导致纹理质量下降,则 daBuild 将显示警告并建议最佳值。如果缩放无法正确存储纹理,则 daBuild 将产生错误。
模糊
模糊有助于减少光照中的像素化或锯齿。blurRadius 以度为单位指定,而不是以像素为单位,并应用于整个球体以确保纹理边缘无缝对齐。
用法
在 .folder.blk 或虚拟资产 .blk 文件中定义 blurRadius:r 参数,如示例中所示。默认值为 3。
角度限制
光源的内容可以限制为两个轴上的特定角度范围。相关选项包括:
phiMin:r=0
phiMax:r=360
thetaMin:r=0
thetaMax:r=180
edgeFadeout:r=-1
phiMin-phiMax范围定义围绕前进方向的限制。thetaMin-thetaMax定义从向前(theta=0) 到向后 (theta=180)的限制。
光强度完全保留在指定区域内。在此区域之外,它会根据edgeFadeout淡出。默认情况下,edgeFadeout:r=-1会计算一个自动淡出,以确保光线不会在纹理上渗出多个像素(取决于分辨率)。如果 edgeFadeout >= 0,则将其视为度值,与纹理分辨率无关。
示例:
为防止背光透过墙壁泄漏,请使用thetaMin:r=0 和 thetaMax:r=93的垂直限制。您必须在 .folder.blk 中使用这些参数创建新的虚拟资源(例如<project-name>/develop/assets/manmade_common/textures/ies/.folder.blk)。
为 Omni Light 设置 Photometric
要设置泛光灯的光度计:
将
.ies文件添加到资产文件夹。在贴图的
.blk文件中定义泛光灯的光度计:
entity{
_template:t="omni_light"
light.direction:p3=0, 1, 0
light.texture_name:t="asset_name"
...
}
自定义纹理注意事项
任何纹理都可以用作
light.texture_name中的光度纹理,但对于自定义纹理(不是由 IES 转换器生成),请记住以下几点:红色通道用于着色器。
分辨率必须与
.folder.blk中指定的光度分辨率匹配。布局必须与映射算法 (球面或八面体) 匹配。
如果分辨率较低,则在光线强度下可能会看到折叠线。这可以通过模糊折叠线处的像素对以具有相似的值来缓解:
Spherical mapping: 左侧和右侧
(0, y)↔(w-1, y)Octahedral mapping: 每侧的两半折叠在一起,例如,对于顶部:
(x, 0)↔(w-x-1, 0)
不建议将自定义纹理用于测试以外的目的,因为与分辨率和布局更改相关的维护开销。
游戏将根据
ies_前缀加载资产。此外,由于光度测量不均匀,因此必须指定光源方向。默认情况下,光线指向下方,但这可能与
.ies文件中的光度法方向不匹配。虽然这适用于测试文件,但没有规则保证.ies文件中的特定方向。为了获得更好的性能,光源不存储完整的方向,并且可以围绕其方向自由旋转。以下是如何处理光源方向的确切细节:
光的 方向 对应于其 Y 轴。对光度数据进行采样时,此方向由
theta = 0表示,而phi在[0, 2*pi]范围内变化。这通常反映了测量过程中光线指向的方向。X 轴 是
(1, 0, 0)或(0, 0, 1)— 无论哪个选项都会产生垂直于光线方向的向量。沿光源方向的 parallel 分量将被删除,以确保这种垂直度。选择离光源方向较远的轴。
如果未找到纹理,游戏将发出警告并继续,而不应用光度纹理。
在未指定或定位光度法纹理的情况下,灯光将像以前一样使用完全强度。
Mapping
.ies 文件通常包含有限数量的非均匀间距样本。
这些贴图使用以下两种映射方法之一转换为纹理:
Octahedral Mapping (默认):提供更好的样本分布。

Spherical Mapping: 虽然实现了,但由于性能稍差且样本分布不均匀(两极密集,侧面稀疏),因此未使用。
更改映射算法
要启用球形映射:
在
<engine_root>/prog/gameLibs/publicInclude/render/renderLights.hlsl中,注释或取消注释该行:
#define USE_OCTAHEDRAL_MAPPING
在
prog/tools/sceneTools/assetExp/exporters/texExp.cpp中,修改以下内容:
IesReader::ImageData img = ies.generateOctahedral(width, height);
// IesReader::ImageData img = ies.generateSpherical(width, height)
生成的纹理的技术细节
格式: L8 (8-bit, 单通道)
文件类型:
.DDSXSpherical Mapping: 第一个和最后一个像素列几乎相同,以避免在折叠线处出现插值问题(冗余: h 像素)。
Octahedral Mapping: 边缘像素与相应的折叠像素几乎匹配(冗余: h + w 像素)。
示例: