光度学光源 (IES)

概述

在基于 daNetGame 的项目中,除了聚光灯或泛光灯等传统光源外,您还可以使用 IES 格式 添加光度学光源。

IES 文件实质上是一个文本文件,它根据 3D 空间中的角度定义来自源的光强度分布。格式规范可以在 这里找到。

您可以从 Internet 下载现成的 IES 文件,因为大多数照明制造商都为其产品提供 IES 配置文件。此外,还有大量的 IES 库可用,其中包含数千个适合各种可视化需求的配置文件。

或者,您可以使用各种编辑器手动创建 IES 配置文件。我用过这个 IES 生成器,它使用起来很简单:你可以用鼠标在垂直平面上绘制光线轮廓。 然后,生成的轮廓将围绕垂直轴“旋转”(类似于 3ds Max* 中的 Lathe 修改器,它从样条线创建 3D 对象)。 但是,此工具无法沿两个轴创建非对称 IES 剖面,这意味着墙壁和地板上的光分布不能同时变化。

Photometric Light Sources

如果需要更复杂的 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 配置文件表示具有许多小灯泡的壁灯始终是一种折衷方案。您会注意到光线是从中心发出的,而不是从每个单独的灯泡发出的。尽管如此,结果在视觉上仍然是可以接受的。

Limitations of IES

光度法

基于 daNetGame 的项目支持光度学文件来描述泛光灯的光分布。本文介绍了如何使用它们。

支持的文件类型

文件放置

光度法文件应放置在适当文件夹下的 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_ 前缀。没有它,它们将无法在游戏中被识别为光度纹理。

textureWidthtextureHeight组件全局定义生成的纹理的分辨率。虽然可以导出不同分辨率的光度法纹理,但游戏将无法加载它们。如果创建其他块来解析 ‘.ies’ 文件或稍后添加其他类型,请确保所有光度法纹理保持相同的分辨率。

聚光灯和特殊选项

对于聚光灯,光线集中在中心周围,从而提高纹理质量。IES 导出器支持将光强度限制为围绕视图方向的特定角度(例如,180 度以将光限制为向前方向)。

如何使用

此选项必须单独应用于灯光:

  1. .ies 文件放在适当的目录中(带有相应的.folder.blk进行处理)。

  2. 打开Asset Viewer并选择 IES 资源。

    • 检查右侧面板中的光度信息。

    • 前三个值(模糊半径、缩放、旋转)显示当前配置。

    • 底部的两个值表示计算出的最优值。

  3. 创建一个虚拟资产.blk文件,例如ies_flashlight_a.tex.blk代表 ies_flashlight_a.ies

  4. 使用最佳值指定 iesScale:riesRotation:b 属性。(目前,此过程不是自动化的。

How to Use

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=0thetaMax:r=93的垂直限制。您必须在 .folder.blk 中使用这些参数创建新的虚拟资源(例如<project-name>/develop/assets/manmade_common/textures/ies/.folder.blk)。

为 Omni Light 设置 Photometric

要设置泛光灯的光度计:

  1. .ies文件添加到资产文件夹。

  2. 在贴图的.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 (默认):提供更好的样本分布。

    Octahedral Mapping

  • Spherical Mapping: 虽然实现了,但由于性能稍差且样本分布不均匀(两极密集,侧面稀疏),因此未使用。

更改映射算法

要启用球形映射:

  1. <engine_root>/prog/gameLibs/publicInclude/render/renderLights.hlsl中,注释或取消注释该行:

#define USE_OCTAHEDRAL_MAPPING
  1. prog/tools/sceneTools/assetExp/exporters/texExp.cpp中,修改以下内容:

IesReader::ImageData img = ies.generateOctahedral(width, height);
// IesReader::ImageData img = ies.generateSpherical(width, height)

生成的纹理的技术细节

  • 格式: L8 (8-bit, 单通道)

  • 文件类型: .DDSX

  • Spherical Mapping: 第一个和最后一个像素列几乎相同,以避免在折叠线处出现插值问题(冗余: h 像素)。

  • Octahedral Mapping: 边缘像素与相应的折叠像素几乎匹配(冗余: h + w 像素)。

示例: