
OpenUSD usdLux DistantLight 光照模式详解平行光原理、angle/intensity 参数与 USD 实战【免费下载链接】OpenUSDUniversal Scene Description项目地址: https://gitcode.com/GitHub_Trending/ope/OpenUSD导读本文以 OpenUSD 仓库中 DistantLight 官方 schema 文档 为骨架系统讲解 usdLux 域内唯一的内置平行光类型DistantLight它沿-Z轴方向发射近似平行的光线常被用来模拟太阳等远距离光源。读完本文你将掌握 DistantLight 的 schema 继承关系与数据流NonboundableLightBase - LightAPI、inputs:angle与inputs:intensity两个核心参数的物理含义与取值范围、light:shaderId的 Sdr 节点注册机制以及如何编写可直接渲染的.usda灯光层并配合 shadowLink/lightLink 等集合实现精细化灯光控制。DistantLight 是什么沿 -Z 轴发射的方向光从 schema.usda 可以看到DistantLight的 schema 定义如下class DistantLight DistantLight ( inherits /NonboundableLightBase doc Light emitted from a distant source along the -Z axis. Also known as a directional light. ) { uniform token light:shaderId DistantLight ( customData { bool apiSchemaOverride true } ) float inputs:angle 0.53 ( displayGroup Basic displayName Angle Extent doc Angular diameter of the light in degrees. As an example, the Sun is approximately 0.53 degrees as seen from Earth. Higher values broaden the light and therefore soften shadow edges. This value is assumed to be in the range 0 angle 360, and will be clipped to this range. ... ) float inputs:intensity 50000 ( doc Scales the brightness of the light linearly. Intensity is overridden on DistantLight from LightAPI so that we can supply a high default intensity to approximate the Sun. ) }其核心语义是光线来自一个位于无限远处的点光源沿本地坐标系的-Z轴照射这也是游戏引擎与 DCC 工具中常说的 directional light方向光。由于光源被认为无限远光线到达场景中任意位置时都是近似平行的因此不存在随距离衰减的平方反比问题——这正是它与 SphereLight、RectLight 等 boundable有边界灯光的本质区别。在 usdLux 体系中的位置在 overview.md 中DistantLight 被明确归类为非 boundable无边界内置光源之一同类的还有DomeLight、DomeLight_1、PluginLight。它的类继承链为UsdLuxDistantLight └─ UsdLuxNonboundableLightBase ├─ UsdLuxXformable (可变换) └─ LightAPI (apiSchemas) (赋予灯光能力)对应的 C 侧distantLight.h 中声明class UsdLuxDistantLight : public UsdLuxNonboundableLightBase并在 distantLight.cpp 中通过TF_REGISTRY_FUNCTION将DistantLight类型别名注册进TfType系统从而支持UsdPrim::IsAUsdLuxDistantLight()之类的运行时查询。有三个值得注意的派生特性无边界但可变换与 boundable 光源一样DistantLight 从Xformable继承可以使用xformOp/xformOpOrder做旋转、平移但 lighting 计算会忽略非 boundable 光源的平移只有旋转方向有意义——这也符合无限远光源的物理直觉。LightAPI 赋予灯光能力通过prepend apiSchemas [LightAPI]见 schema.usda 中NonboundableLightBase的定义DistantLight 自动获得inputs:color、inputs:exposure、inputs:specular、inputs:diffuse、inputs:normalize等全部 LightAPI 灯光计算属性。shaderId 固定light:shaderId被apiSchemaOverride覆盖为DistantLight渲染器通过它识别应使用的着色节点。完整示例一个可直接渲染的 DistantLight 场景原文档给出了一段完整的.usda示例一个DistantLightinputs:angle 1.0适度加宽光线、inputs:intensity 10000降低默认强度照亮一个球体和一个立方体#usda 1.0 ( upAxis Y ) def Scope Lights { def DistantLight Light1 { float inputs:angle 1.0 float inputs:intensity 10000 } } def Xform TestGeom { def Sphere Sphere1 { color3f[] primvars:displayColor [(1, 1, 1)] ( interpolation constant ) double3 xformOp:translate (0, 0, -2) uniform token[] xformOpOrder [xformOp:translate] } def Cube Cube { color3f[] primvars:displayColor [(1, 1, 1)] ( interpolation constant ) double size 8 double3 xformOp:translate (0, 0, -8) uniform token[] xformOpOrder [xformOp:translate] } }要点解读灯光被放在Scope Lights下几何放在Xform TestGeom下这是 USD 场景组织的常见惯例便于后续用 lightLink/shadowLink 集合做灯光关联默认情况下灯光不设置xformOp即保持本地-Z方向照射若要让太阳从斜上方照下来只需给灯光加float3 xformOp:rotateXYZ旋转几何体使用primvars:displayColor赋予白色显示颜色在无材质绑定时即可观察到光照效果。核心属性详解inputs:angle —— 光源角直径项目值USD 类型float默认值0.5299999713897705即 0.53声明float inputs:angle 0.53见 schema.usdainputs:angle表示光源的角直径angular diameter单位为度。默认值 0.53 度恰好近似从地球观测到的太阳角直径——这也是为什么 DistantLight 默认就能模拟出比较真实的阳光效果。其物理行为遵循值越大光线越不平行阴影边缘越柔和光锥变宽值越小阴影越锐利。当angle 0时DistantLight 退化为完全平行的理想平行光。该值被假定在0 angle 360范围内超出部分会被**截断clip**到该范围。当angle 180时理论上灯光可以覆盖超过半球范围的光照区域。这在语法上合法但文档特别提示大角度场景下使用 DomeLight穹顶灯可能获得更好的渲染性能。增大 angle 还会增加场景中的总光量因此往往需要同步降低 intensity/exposure以补偿避免过曝。在 C 侧distantLight.cpp 通过UsdLuxTokens-inputsAngle与SdfValueTypeNames-Float暴露GetAngleAttr()/CreateAngleAttr()两个接口Python 侧则对应UsdLux.DistantLight(stage, path).GetAngleAttr()。inputs:intensity —— 线性亮度缩放项目值USD 类型float默认值50000.0声明float inputs:intensity 50000见 schema.usdainputs:intensity线性缩放灯光亮度。关键点这一属性是从 LightAPI 继承后**被 DistantLight 显式覆盖override**的属性apiSchemaOverride true覆盖的目的是为 DistantLight 提供高达50000 的默认强度来近似阳光——其他灯光的默认强度通常是 1。其物理意义由如下公式给出L 为基础、未乘除的发光亮度单位 nits即 cd/m²L_{Scalar} intensity规范性说明灯光的发光量以光谱辐射亮度spectral radiance为单位归一化使得一个intensity 1、exposure 0且垂直入射到传感器平面的灯光在 RGB 渲染器中产生[1, 1, 1]的像素值即 1 nit 亮度。因此intensity 2, exposure 0→ 2 nitsintensity 10000, exposure 0→ 10000 nits示例中的配置。与inputs:exposure以 2 为底的指数缩放exposure 1约使能量翻倍配合使用时最终贡献为二者的乘积。由于 DistantLight 不考虑距离衰减intensity 直接决定整体曝光水平实际创作中常见的做法是先固定 angle如 0.53再调节 intensity/exposure 达到期望的画面明暗。light:shaderId —— Sdr 着色器标识项目值USD 类型token默认值DistantLight可变性uniform见 schema.usdalight:shaderId标识 DistantLight 应使用的着色器。文档指出USD 会自动为它注册一个标识为DistantLight、source type 为USD的SdrShaderNode其 inputs 与灯光的属性一一对应。这一机制在测试中有直接印证testUsdLuxLight.py 的test_SdrShaderNodesForLights用例会遍历所有 usdLux 灯光类型验证每个类型的 Sdr 节点是否注册成功并且DistantLight相比 LightAPI 公共输入还额外多出angle一个专属输入见expectedLightNodes { DistantLight : [angle], ... }。换句话说渲染器如 Hydra/RenderMan通过查询 Sdr 注册表即可拿到 DistantLight 的完整可着色输入列表从而把inputs:angle、inputs:intensity等接入自身的灯光材质图。从 LightAPI 继承的灯光计算属性虽然 DistantLight 自己的 schema 只声明了inputs:angle但通过 LightAPI 它还拥有整套灯光计算属性。在 overview.md 中有详细说明要点如下属性作用备注inputs:color灯光颜色着色color3f默认白inputs:exposure以 2 为底的指数亮度缩放与 intensity 相乘inputs:specular/inputs:diffuse对材质高光/漫反射分量的倍率建议 0.0~1.0inputs:colorTemperature色温着色开尔文需enableColorTemperature true范围 1000~10000默认 6500D65 白点对应 sRGB/Rec.709inputs:normalize是否让灯光面积影响功率对 DistantLight 而言角直径即面积collection:lightLink/collection:shadowLink光照/阴影关联集合控制灯光照亮哪些物体、哪些物体投影针对 DistantLight 特别值得注意的用法灯光关联lightLink与阴影关联shadowLink这两个集合默认includeRoot true照亮/投影所有物体。若要只照亮特定 prim可设includeRoot 0并列出includes或使用membershipExpression路径表达式如/TestGeom/*2。示例见 overview.md。阴影软硬控制DistantLight 常配合ShadowAPIprepend apiSchemas [ShadowAPI]使用inputs:shadow:falloff控制阴影过渡区。在 overview.md 的示例中两个 DistantLight 分别用shadow:falloff 0硬阴影与shadow:falloff 1.5软阴影形成对比同时shadow:distance 4.5限制了阴影投射距离。ShapingAPI 的有限支持文档提示部分渲染器对 DistantLight 只使用shaping:focus而忽略shaping:cone:angle见 overview.md因为平行光本就没有锥形光束概念。Python/C 编程接口速查除手写.usda外DistantLight 也可通过 Pythonpxr.UsdLux或 C API 程序化创建与修改from pxr import Usd, UsdLux stage Usd.Stage.CreateNew(sunlight.usda) light UsdLux.DistantLight.Define(stage, /Lights/Sun) angle_attr light.GetAngleAttr() angle_attr.Set(1.0) # 等价于 USD 里的 float inputs:angle 1.0 intensity_attr light.GetIntensityAttr() # 来自 LightAPI intensity_attr.Set(10000) # 降低阳光默认的 50000 强度C 侧对应的创建与查询入口为UsdLuxDistantLight::Define(stage, path)/Get(stage, path)与GetAngleAttr()/CreateAngleAttr()见 distantLight.h。测试文件 testUsdLuxLight.py 还验证了 DistantLight 的定义可用性以及它不属于UsdGeom.Boundableself.assertFalse(UsdGeom.Boundable(distLight))从侧面印证了其无边界光源的语义。继承属性一览Xformable / Imageable除上述专属与 LightAPI 属性外DistantLight 还继承自Xformable与Imageable相关属性在 DistantLight.md 中列出属性类型默认值说明xformOpOrdertoken[]—变换操作顺序来自 XformableproxyPrimrel—代理 prim 关系来自 Imageablepurposetokendefault渲染用途default / render / proxy / guide来自 Imageablevisibilitytokeninherited可见性可设invisible来自 Imageable实际创作中purpose常用于区分预览代理与最终渲染几何visibility则可用于在动画特定帧关闭太阳光。常见问题与最佳实践阴影太硬/太锐利将inputs:angle从默认 0.53 提高到 1.0~5.0光线发散后阴影边缘随之柔和注意同时降低inputs:intensity补偿增大的光量。画面过曝DistantLight 默认强度 50000参考 示例 将其降到 10000 左右或使用负的inputs:exposure。希望光线斜射给灯光 prim 添加float3 xformOp:rotateXYZ如(25, 0, 0)并声明uniform token[] xformOpOrder [xformOp:rotateXYZ]平移操作会被渲染器忽略。角度需求超过 180 度优先考虑用DomeLight穹顶环境光替代文档明确提示其在大角度场景下性能更优。只照亮特定物体设置uniform bool collection:lightLink:includeRoot 0并填写rel collection:lightLink:includes [...]避免平行光无差别照亮整个场景。延伸阅读DistantLight 官方 schema 文档本文核心依据含完整属性说明与公式。usdLux 域总览介绍全部内置光源、LightAPI、ShapingAPI、ShadowAPI、mesh light 与灯光关联的完整示例。LightAPI 文档intensity/exposure/color/colorTemperature 等灯光计算属性的完整定义。DomeLight 文档大角度/环境光照场景下的替代方案。schema.usda 中 DistantLight 定义schema 层面最权威的属性声明与文档字符串。testUsdLuxLight.py验证 DistantLight 可定义性、非 boundable 语义与 Sdr 节点注册的测试用例。【免费下载链接】OpenUSDUniversal Scene Description项目地址: https://gitcode.com/GitHub_Trending/ope/OpenUSD创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考