<pc-light>
<pc-light> 为实体添加灯光,可以是太阳般的平行光,或具有位置和范围的全向光、聚光灯。
- 必须直接位于
<pc-entity>、<pc-model>或<pc-node>下。
属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
cascade-blend | Number | "0" | 每级混入下一级的比例,0 到 1,仅多级平行光 |
cascade-distribution | Number | "0.5" | 视锥分段分布,0 线性,1 对数并集中近处,仅多级平行光 |
cast-shadows | Boolean | "false" | 是否投射阴影 |
color | Color | "1 1 1" | RGB、十六进制或颜色名称 |
enabled | Boolean | "true" | 组件启用状态 |
inner-cone-angle | Number | "40" | 聚光内锥角,单位为度,范围内完整强度。应小于外锥角,收窄到默认 40 度以下需同时降低两者 |
intensity | Number | "1" | 强度倍率 |
normal-offset-bias | Number | "0" | 阴影法线偏移 |
num-cascades | Number | "1" | 平行光级联数,整数 1 到 4,1 为不级联 |
outer-cone-angle | Number | "45" | 聚光外锥角,达到此角度时强度为零 |
penumbra-falloff | Number | "1" | PCSS 半影衰减 |
penumbra-size | Number | "1" | PCSS 半影大小 |
range | Number | "10" | 光照范围 |
shadow-bias | Number | "0.05" | 阴影深度偏移 |
shadow-blocker-samples | Number | "16" | PCSS 遮挡物采样数 |
shadow-bounds | BoundingBox | - | 平行光阴影适配的世界包围盒,替代摄像机级联,详见阴影边界 |
shadow-distance | Number | "40" | 最大阴影距离 |
shadow-intensity | Number | "1" | 阴影强度倍率 |
shadow-resolution | Number | "1024" | 阴影贴图分辨率 |
shadow-samples | Number | "16" | PCSS 阴影采样数 |
shadow-type | Enum | "pcf3-32f" | 滤波类型:pcf1-16f、pcf1-32f、pcf3-16f、pcf3-32f、pcf5-16f、pcf5-32f、vsm-16f、vsm-32f 或 pcss-32f |
shape | Enum | "punctual" | punctual、rect、disk 或 sphere。面形状用于 omni 和 spot,尺寸取实体缩放,还需 pc-app 的 area-light-luts,详见面光源 |
type | Enum | "directional" | directional、omni 或 spot |
volumetric-scattering | Number | "1" | 对体积雾散射的贡献倍率,0 排除。仅 omni/spot,且摄像机体积雾启用局部灯光时生效 |
vsm-bias | Number | "0.0025" | 方差阴影贴图偏移 |
vsm-blur-size | Number | "11" | 方差阴影模糊大小,1 到 25 |
默认值全部来自引擎,与直接创建的灯光一致。阴影参数刻意不为小场景预调,因此启用阴影后若有异常,需要自行调整 shadow-bias 和 normal-offset-bias。
阴影级联
单张阴影贴图覆盖长距离时分辨率不足,近处出现方块,远处粗糙。级联将摄像机视锥分段,分别提供阴影贴图,让细节跟随摄像机。仅适用于平行光,需要显式启用:
<pc-entity name="sun" rotation="45 30 0">
<pc-light cast-shadows
num-cascades="4"
cascade-distribution="0.7"
cascade-blend="0.1"
shadow-distance="200"
shadow-resolution="2048"></pc-light>
</pc-entity>
三个属性作用不同,只有 num-cascades 大于 1 时,另外两个才生效:
| 属性 | 作用 |
|---|---|
num-cascades | 1 到 4 段。共享同一阴影贴图,从 2 段起每段占四分之一,因此改善近处而非总分辨率。每段也增加一个阴影渲染通道 |
cascade-distribution | 0 均匀分布,1 集中近处。近景需要细节时增大,远处不足时减小 |
cascade-blend | 0 到 1 的相邻段淡变比例。小值可隐藏接缝,过大会浪费重叠区分辨率 |
shadow-distance 仍是总范围,增加段数不会扩大范围,只细分原区。shadow-resolution 决定共享贴图尺寸,2 到 4 级时每级边长为其一半。级联需要透视摄像机,不支持正交。
级联阴影示例在漫长沙漠堤道上调节三项参数,并绘制实际分割距离。引擎没有级联调试视图,因此这有助于理解分布滑块的作用。
阴影边界
级联随各摄像机视野分配阴影。当大场景只有局部需要阴影时,shadow-bounds 可将整张贴图集中到指定盒体:
<!-- the shadow covers a 10 x 4 x 10 box centered at a height of 2 -->
<pc-entity name="sun" rotation="45 30 0">
<pc-light type="directional" cast-shadows shadow-bounds="0 2 0 5 2 5"></pc-light>
</pc-entity>
六个世界空间数字依次为中心和半尺寸。盒体只需包含投影物。沿光照方向更远的接收面,例如地面,仍接收阴影;从灯光看来位于盒体侧外的投影物则不投影。
设置后忽略 num-cascades、shadow-distance、cascade-blend 和 cascade-distribution,无论距摄像机多远都会绘制。移除后恢复级联,详见阴影边界。
面光源
点状光源无限小,实际灯具则有尺寸,使高光和阴影变软。shape 可为 omni 或 spot 指定 rect、disk、sphere,大小来自实体缩放。单位缩放下,rect 是局部 XZ 平面的 1×1 矩形,disk 同平面直径 1,sphere 直径 1。衰减由形状尺寸和距离决定,range 仅作截断。
面光源需要引擎包未附带的 LTC 查找表,来自 Heitz、Dupuy、Hill 和 Neubelt 的 SIGGRAPH 2016 研究。pc-app 的 area-light-luts 引用 JSON <pc-asset>,包含 LTC_MAT_1 与 LTC_MAT_2,各 16384 个数字,与引擎 area-light-luts.json 格式一致。加载后为全应用启用:
<pc-app area-light-luts="luts">
<pc-asset id="luts" src="https://playcanvas.github.io/web-components/examples/assets/json/area-light-luts.json"></pc-asset>
<pc-scene>
<!-- A 2 by 1 ceiling panel; rect and disk shapes emit from the entity's XZ plane, so this one shines down -->
<pc-entity name="panel" position="0 3 0" scale="2 1 1">
<pc-light type="spot" shape="rect" intensity="8" range="12" outer-cone-angle="88"></pc-light>
</pc-entity>
</pc-scene>
</pc-app>
加载有效表会应用并启用面光源,清空属性会关闭,但已交给引擎的表保留。id 无匹配时关闭并警告,文件格式错误也拒绝并警告;否则引擎占位表会让 disk 不发光、所有形状缺镜面反射。不同于帧缓冲属性,此项立即生效,启动前设置则随资源加载。不支持面光源的设备忽略开关,仍以点状灯光渲染。
查找表来自引擎仓库 examples/assets/json/area-light-luts.json,MIT 许可。示例库提供约 300 KB 副本,适合试用,生产建议自行托管。
面光源示例用 rect 聚光灯构建顶灯、sphere 全向光构建灯泡,可直观观察 intensity、range 与尺寸的关系。
示例
修改 color、intensity 或 type,观察场景实时变化:
<pc-app>
<pc-scene>
<pc-entity name="camera" position="0 2.5 5" rotation="-15 0 0">
<pc-camera clear-color="#1d1f2b"></pc-camera>
</pc-entity>
<!-- A warm spot light shining down (spot lights point down the negative Y axis) -->
<pc-entity name="spot-light" position="-2 4 0">
<pc-light type="spot" color="#ffb47a" intensity="5" inner-cone-angle="25" outer-cone-angle="35" cast-shadows normal-offset-bias="0.05" shadow-bias="0.2"></pc-light>
</pc-entity>
<!-- A cool omni light between the shapes -->
<pc-entity name="omni-light" position="2 2 1">
<pc-light type="omni" color="#7ab8ff" intensity="2.5" range="10"></pc-light>
</pc-entity>
<!-- Shapes to light -->
<pc-entity name="ground" position="0 -0.5 0" scale="10 1 10">
<pc-render type="box"></pc-render>
</pc-entity>
<pc-entity name="sphere" position="-2 0.5 0">
<pc-render type="sphere"></pc-render>
</pc-entity>
<pc-entity name="box" position="2 0.5 0" rotation="0 30 0">
<pc-render type="box"></pc-render>
</pc-entity>
</pc-scene>
</pc-app>
JavaScript 接口
可以通过 LightComponentElement API创建和操作元素。
component 是底层 LightComponent,就绪前为 null,其余功能可通过它访问。
另请参阅
<pc-scene>:缩放灯光贡献的曝光。<pc-sky>:补充直接光之外的环境照明。<pc-render>:对象的阴影投射与接收。