跳到主要内容

<pc-light>

<pc-light> 为实体添加灯光,可以是太阳般的平行光,或具有位置和范围的全向光、聚光灯。

用法

属性​

属性类型默认值说明
cascade-blendNumber"0"每级混入下一级的比例,0 到 1,仅多级平行光
cascade-distributionNumber"0.5"视锥分段分布,0 线性,1 对数并集中近处,仅多级平行光
cast-shadowsBoolean"false"是否投射阴影
colorColor"1 1 1"RGB、十六进制或颜色名称
enabledBoolean"true"组件启用状态
inner-cone-angleNumber"40"聚光内锥角,单位为度,范围内完整强度。应小于外锥角,收窄到默认 40 度以下需同时降低两者
intensityNumber"1"强度倍率
normal-offset-biasNumber"0"阴影法线偏移
num-cascadesNumber"1"平行光级联数,整数 1 到 4,1 为不级联
outer-cone-angleNumber"45"聚光外锥角,达到此角度时强度为零
penumbra-falloffNumber"1"PCSS 半影衰减
penumbra-sizeNumber"1"PCSS 半影大小
rangeNumber"10"光照范围
shadow-biasNumber"0.05"阴影深度偏移
shadow-blocker-samplesNumber"16"PCSS 遮挡物采样数
shadow-boundsBoundingBox-平行光阴影适配的世界包围盒,替代摄像机级联,详见阴影边界
shadow-distanceNumber"40"最大阴影距离
shadow-intensityNumber"1"阴影强度倍率
shadow-resolutionNumber"1024"阴影贴图分辨率
shadow-samplesNumber"16"PCSS 阴影采样数
shadow-typeEnum"pcf3-32f"滤波类型:pcf1-16f、pcf1-32f、pcf3-16f、pcf3-32f、pcf5-16f、pcf5-32f、vsm-16f、vsm-32f 或 pcss-32f
shapeEnum"punctual"punctual、rect、disk 或 sphere。面形状用于 omni 和 spot,尺寸取实体缩放,还需 pc-app 的 area-light-luts,详见面光源
typeEnum"directional"directional、omni 或 spot
volumetric-scatteringNumber"1"对体积雾散射的贡献倍率,0 排除。仅 omni/spot,且摄像机体积雾启用局部灯光时生效
vsm-biasNumber"0.0025"方差阴影贴图偏移
vsm-blur-sizeNumber"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-cascades1 到 4 段。共享同一阴影贴图,从 2 段起每段占四分之一,因此改善近处而非总分辨率。每段也增加一个阴影渲染通道
cascade-distribution0 均匀分布,1 集中近处。近景需要细节时增大,远处不足时减小
cascade-blend0 到 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,其余功能可通过它访问。

另请参阅​

示例:基本形状、级联阴影、面光源和钟楼。