重新光照
高斯泼溅采集时光照已烘焙。重新光照通过标准灯光照亮场景的代理网格,再逐像素传递到泼溅,让运行时可以添加软阴影太阳、点光源或更换环境。
查看实时示例:HDRI、PCSS 平行光和投影点光源重新照亮场景。
查看实时示例
工作原理
- 将近似场景的简化网格放入专用图层,与负责照亮它的灯光一起。网格可由泼溅重建或来自摄影测量。
- GsplatRelighting 用匹配主相机的内部相机向离屏纹理渲染该层,RGB 保存光照颜色,alpha 保存覆盖遮罩。
- 片元阶段代码块按自身屏幕位置采样光照,调制每个片元。纹理与主相机屏幕对齐,无需重投影,光照逐像素传递。
未被代理覆盖的天空等内容不染色,或由独立背景乘数缩放,以跟随环境曝光。
配置
技术封装在 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);
脚本属性
| 属性 | 默认值 | 用途 |
|---|---|---|
blend | 1 | 光照影响程度,0 为原样,1 为完全调制 |
brightness | 2 | 染色亮度,2 补偿代理材质的 0.5 灰反照率 |
background | 1 | 未被网格覆盖的天空等内容乘数,跟随环境曝光 |
textureScale | 1 | 光照纹理相对后备缓冲区分辨率 |
layerName | 'Relighting' | 代理与灯光图层名,不存在时创建 |
priority | -1 | 内部相机优先级,应低于主相机以先渲染纹理 |
光照纹理可通过 relighting.texture 访问,支持时使用 HDR,可供调试或继续处理。
说明
- 代理质量直接决定结果,轮廓不匹配会让光照边界落错位置,更贴合的网格是主要改进手段。
- 静止灯光可用
SHADOWUPDATE_THISFRAME仅渲染一次阴影,示例点光源采用该方式。