跳到主要内容

重新光照

高斯泼溅采集时光照已烘焙。重新光照通过标准灯光照亮场景的代理网格,再逐像素传递到泼溅,让运行时可以添加软阴影太阳、点光源或更换环境。

查看实时示例:HDRI、PCSS 平行光和投影点光源重新照亮场景。

查看实时示例

工作原理​

  1. 将近似场景的简化网格放入专用图层,与负责照亮它的灯光一起。网格可由泼溅重建或来自摄影测量。
  2. GsplatRelighting 用匹配主相机的内部相机向离屏纹理渲染该层,RGB 保存光照颜色,alpha 保存覆盖遮罩。
  3. 片元阶段代码块按自身屏幕位置采样光照,调制每个片元。纹理与主相机屏幕对齐,无需重投影,光照逐像素传递。

未被代理覆盖的天空等内容不染色,或由独立背景乘数缩放,以跟随环境曝光。

配置​

技术封装在 GsplatRelighting 脚本,附加到主相机实体:

import { GsplatRelighting } from 'playcanvas/scripts/esm/gsplat/gsplat-relighting.mjs';

camera.addComponent('script');
const relighting = camera.script.create(GsplatRelighting, {
properties: {
blend: 0.5,
brightness: 1
}
});

将代理网格放到重光照图层,配置材质写入覆盖遮罩:

const meshMaterial = new pc.StandardMaterial();
meshMaterial.diffuse = new pc.Color(0.5, 0.5, 0.5);
relighting.configureMaterial(meshMaterial);

const meshEntity = meshAsset.resource.instantiateRenderEntity();
meshEntity.findComponents('render').forEach((render) => {
render.layers = [relighting.layer.id];
render.meshInstances.forEach((meshInstance) => {
meshInstance.material = meshMaterial;
});
});
app.root.addChild(meshEntity);

向同一图层添加标准灯光,支持 IBL、投影平行光和点光源:

const light = new pc.Entity('sun');
light.addComponent('light', {
type: 'directional',
layers: [relighting.layer.id],
castShadows: true
});
app.root.addChild(light);

脚本属性​

属性默认值用途
blend1光照影响程度,0 为原样,1 为完全调制
brightness2染色亮度,2 补偿代理材质的 0.5 灰反照率
background1未被网格覆盖的天空等内容乘数,跟随环境曝光
textureScale1光照纹理相对后备缓冲区分辨率
layerName'Relighting'代理与灯光图层名,不存在时创建
priority-1内部相机优先级,应低于主相机以先渲染纹理

光照纹理可通过 relighting.texture 访问,支持时使用 HDR,可供调试或继续处理。

说明​

  • 代理质量直接决定结果,轮廓不匹配会让光照边界落错位置,更贴合的网格是主要改进手段。
  • 静止灯光可用 SHADOWUPDATE_THISFRAME 仅渲染一次阴影,示例点光源采用该方式。

另请参见​