全局光照
一般光照系统只考虑光源直接照射到物体表面所产生的效果,不会计算光源经过物体表面反射或折射的光线,即间接光照
。全局光照系统能够对间接光照进行建模,实现更加逼真的光线效果。
ts
//初始化引擎
await Engine3D.init({ });
Engine3D.setting.gi.enable = true;
Engine3D.setting.gi.gridYCount = 3;
Engine3D.setting.gi.gridXCount = 4;
Engine3D.setting.gi.gridZCount = 4;
Engine3D.setting.gi.probeSpace = 30;
Engine3D.setting.gi.offsetX = 22;
Engine3D.setting.gi.offsetY = 56;
Engine3D.setting.gi.offsetZ = 23;
Engine3D.setting.gi.indirectIntensity = 2;
Engine3D.setting.gi.probeSize = 64;
Engine3D.setting.gi.octRTSideSize = 128;
Engine3D.setting.gi.autoRenderProbe = true;
let probeObj = new Object3D();
let component = probeObj.addComponent(GlobalIlluminationComponent);
this.scene.addChild(probeObj);
//创建渲染器
let renderJob = new ForwardRenderJob(this.scene);
Engine3D.startRender(renderJob);
Engine3D.setting.gi 配置参数。
参数 | 类型 | 描述 |
---|---|---|
enable | boolean | 开启/关闭 |
offsetX | number | 探针组的注册点在x轴的偏移量 |
offsetY | number | 探针组的注册点在y轴的偏移量 |
offsetZ | number | 探针组的注册点在z轴的偏移量 |
gridXCount | number | 探针在x轴的数量 |
gridYCount | number | 探针在y轴的数量 |
gridZCount | numbe` | 探针在z轴的数量 |
ProbeSize | number | 每个探针采样到的数据尺寸 |
probeSpace | number | 探针与探针之间的距离 |
indirectIntensity | number | 间接光的光照强度 |
bounceIntensity | number | 反射光的光照强度 |
octRTMaxSize | number | 设置八面体贴图的总尺寸 |
octRTSideSize | number | 设置八面体贴图,每个八面体正方形的尺寸 |
autoRenderProbe | boolean | 设置探针是否自动更新 |
ts
import {
Camera3D,
defaultTexture,
DirectLight,
Engine3D,
ForwardRenderJob,
GLTFParser,
GUIHelp,
LitMaterial,
HoverCameraController,
KelvinUtil,
MeshRenderer,
Object3D,
PlaneGeometry,
Scene3D,
SphereGeometry,
SSRPost,
SSR_IS_Kernel,
Time,
CameraUtil,
webGPUContext,
GTAOPost,
HDRBloomPost,
TAAPost,
GlobalIlluminationComponent,
PointLight,
BoxGeometry,
Color,
} from "@orillusion/core";
export class Sample_GI {
lightObj: Object3D;
cameraObj: Camera3D;
scene: Scene3D;
hover: HoverCameraController;
constructor() {}
async run() {
await Engine3D.init({});
Engine3D.setting.material.materialChannelDebug = true;
Engine3D.setting.material.materialDebug = false;
Engine3D.setting.gi.enable = true;
Engine3D.setting.gi.debug = true;
Engine3D.setting.gi.probeYCount = 3;
Engine3D.setting.gi.probeXCount = 6;
Engine3D.setting.gi.probeZCount = 6;
Engine3D.setting.gi.probeSpace = 60;
Engine3D.setting.gi.offsetX = 0;
Engine3D.setting.gi.offsetY = 60;
Engine3D.setting.gi.offsetZ = 0;
Engine3D.setting.gi.indirectIntensity = 1;
Engine3D.setting.gi.probeSize = 64;
Engine3D.setting.gi.octRTSideSize = 64;
Engine3D.setting.gi.octRTMaxSize = 2048;
Engine3D.setting.gi.ddgiGamma = 1;
Engine3D.setting.gi.autoRenderProbe = true;
Engine3D.setting.shadow.shadowBound = 200;
Engine3D.setting.shadow.shadowBias = 0.002;
Engine3D.setting.shadow.debug = true;
Engine3D.setting.shadow.autoUpdate = true;
Engine3D.setting.shadow.updateFrameRate = 1;
Engine3D.setting.render.postProcessing.bloom = {
enable: true,
debug: false,
blurX: 4,
blurY: 4,
intensity: 0.5,
brightness: 1.25,
};
GUIHelp.init();
this.scene = new Scene3D();
Camera3D.mainCamera = CameraUtil.createCamera3DObject(this.scene);
Camera3D.mainCamera.perspective(60, webGPUContext.aspect, 1, 5000.0);
let ctrl = Camera3D.mainCamera.object3D.addComponent(HoverCameraController);
ctrl.setCamera(-60, -25, 150);
let renderJob = new ForwardRenderJob(this.scene);
renderJob.debug();
this.addGIProbes();
Engine3D.startRender(renderJob);
await this.initScene();
}
private addGIProbes() {
let probeObj = new Object3D();
let component = probeObj.addComponent(GlobalIlluminationComponent);
this.scene.addChild(probeObj);
}
async initScene() {
/******** light *******/
{
this.lightObj = new Object3D();
this.lightObj.rotationX = 15;
this.lightObj.rotationY = 110;
this.lightObj.rotationZ = 0;
let lc = this.lightObj.addComponent(DirectLight);
lc.lightColor = KelvinUtil.color_temperature_to_rgb(5355);
lc.castShadow = true;
lc.intensity = 18;
lc.debug();
this.scene.addChild(this.lightObj);
}
{
let po4 = new Object3D();
let pl4 = po4.addComponent(PointLight);
pl4.intensity = 2.5;
pl4.range = 1000;
pl4.castShadow = true;
po4.x = 86;
po4.y = 23.61;
po4.z = -23.61;
this.scene.addChild(po4);
pl4.debug();
pl4.debugDraw(true);
}
{
let floorHeight = 20;
let floor = this.GetSingleCube(1000, floorHeight, 1000, 0.6, 0.6, 0.6);
floor.y = -floorHeight;
this.scene.addChild(floor);
}
{
let greenBall = this.GetSingleSphere(30, 0.1, 0.8, 0.2);
this.scene.addChild(greenBall);
greenBall.x = -70;
greenBall.y = 40;
}
{
let chair = (await Engine3D.res.loadGltf(
"https://cdn.orillusion.com/PBR/SheenChair/SheenChair.gltf",
{
onProgress: (e) => this.onLoadProgress(e),
onComplete: (e) => this.onComplete(e),
}
)) as Object3D;
chair.scaleX = chair.scaleY = chair.scaleZ = 100;
chair.rotationZ = chair.rotationX = 130;
chair.z = -120;
this.scene.addChild(chair);
}
{
let Duck = (await Engine3D.res.loadGltf(
"https://cdn.orillusion.com/PBR/Duck/Duck.gltf",
{
onProgress: (e) => this.onLoadProgress(e),
onComplete: (e) => this.onComplete(e),
}
)) as Object3D;
Duck.scaleX = Duck.scaleY = Duck.scaleZ = 0.3;
Duck.transform.y = 0;
Duck.transform.x = 0;
Duck.transform.z = 80;
this.scene.addChild(Duck);
GUIHelp.addFolder("Move Duck");
GUIHelp.add(Duck.transform, "x", -80, 80, 1);
GUIHelp.add(Duck.transform, "z", -80, 80, 1);
GUIHelp.endFolder();
}
{
// let car = await Engine3D.res.loadGltf(
// "https://cdn.orillusion.com/gltfs/pbrCar/pbrCar.gltf"
// );
// car.scaleX = car.scaleY = car.scaleZ = 1.5;
// this.scene.addChild(car);
// car.x = 20;
}
GUIHelp.addButton("Start GI", () => {
Engine3D.renderJob.probeRenderer.startRenderGI();
});
}
onLoadProgress(e) {
console.log(e);
}
onComplete(e) {
console.log(e);
}
renderUpdate() {}
public GetSingleCube(
sizeX: number,
sizeY: number,
sizeZ: number,
r: number,
g: number,
b: number
) {
let mat = new LitMaterial();
mat.baseColor = new Color(r, g, b, 1);
let obj = new Object3D();
let mr = obj.addComponent(MeshRenderer);
mr.castGI = true;
mr.geometry = new BoxGeometry(sizeX, sizeY, sizeZ);
mr.material = mat;
return obj;
}
public GetSingleSphere(radius: number, r: number, g: number, b: number) {
let mat = new LitMaterial();
mat.baseColor = new Color(r, g, b, 1);
let obj = new Object3D();
let mr = obj.addComponent(MeshRenderer);
mr.castGI = true;
mr.geometry = new SphereGeometry(radius, 20, 20);
mr.material = mat;
return obj;
}
}
new Sample_GI().run();