GTAO
AO
is used to describe the effect of objects obscuring the diffuse light around them when they intersect or come close to each other, and can solve or improve problems such as light leakage, floating, and unrealistic shadows. It improves the representation of gaps, folds, and edges. Small objects in the scene are also better represented.It enhances details, especially in dark shadows.The sense of depth and realism of space is improved.The contrast between light and dark is strengthened and improved.The overall artistic effect of the image is enhanced.Within the engine, by sampling the pixels within a specified distance range in the screen range and integrating them, the current pixel AO
coefficient is assigned.
//Engine initialization
await Engine3D.init();
Engine3D.setting.render.postProcessing.gtao.maxDistance = 5;
Engine3D.setting.render.postProcessing.gtao.maxPixel = 50;
Engine3D.setting.render.postProcessing.gtao.darkFactor = 1;
Engine3D.setting.render.postProcessing.gtao.rayMarchSegment = 6;
Engine3D.setting.render.postProcessing.gtao.multiBounce = true;
Engine3D.setting.render.postProcessing.gtao.blendColor = true;
// Add GTAOPost
let postProcessing = this.scene.addComponent(PostProcessingComponent);
postProcessing.addPost(GTAOPost);
//Start rendering
let view = new View3D();
view.scene = this.scene;
view.camera = this.camera;
Engine3D.startRenderView(view);
Engine3D.setting.render.postProcessing.gtao configuration parameters:
Parameter | Type | Description |
---|---|---|
maxDistance | number | Sets the maximum distance when searching the 3D space around during AO sampling. |
maxPixel | number | Sets the maximum distance when searching surrounding pixels during AO sampling. |
darkFactor | number | Sets the coefficient of the AO value when outputting to the screen, 1: all output, 0: no output. |
rayMarchSegment | number | Sets the number of steps for the AO sampling. The larger the value, the better the quality of the AO effect, but the more performance it consumes. |
multiBounce | boolean | Whether to simulate color bouncing. |
blendColor | boolean | True: blend with the mainColor of GBuffer; false: output only the color of AO. |
import { View3D, DirectLight, Engine3D, PostProcessingComponent, LitMaterial, HoverCameraController, KelvinUtil, MeshRenderer, Object3D, PlaneGeometry, Scene3D, SphereGeometry, CameraUtil, webGPUContext, BoxGeometry, TAAPost, AtmosphericComponent, GTAOPost } from '@orillusion/core';
import * as dat from 'dat.gui';
class Sample_GTAO {
lightObj: Object3D;
scene: Scene3D;
async run() {
Engine3D.setting.shadow.shadowSize = 2048;
Engine3D.setting.shadow.shadowBound = 500;
Engine3D.setting.shadow.shadowBias = 0.05;
await Engine3D.init();
this.scene = new Scene3D();
this.scene.addComponent(AtmosphericComponent).sunY = 0.6;
let mainCamera = CameraUtil.createCamera3DObject(this.scene, 'camera');
mainCamera.perspective(60, webGPUContext.aspect, 1, 5000.0);
let ctrl = mainCamera.object3D.addComponent(HoverCameraController);
ctrl.setCamera(0, -15, 500);
await this.initScene();
let view = new View3D();
view.scene = this.scene;
view.camera = mainCamera;
Engine3D.startRenderView(view);
let postProcessing = this.scene.addComponent(PostProcessingComponent);
let post = postProcessing.addPost(GTAOPost);
post.maxDistance = 6;
post.maxPixel = 15;
this.gui();
}
async initScene() {
{
this.lightObj = new Object3D();
this.lightObj.rotationX = 45;
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 = 5;
lc.indirect = 0.3;
this.scene.addChild(this.lightObj);
}
{
let mat = new LitMaterial();
mat.roughness = 1.0;
mat.metallic = 0.0;
let floor = new Object3D();
let mr = floor.addComponent(MeshRenderer);
mr.geometry = new PlaneGeometry(400, 400);
mr.material = mat;
this.scene.addChild(floor);
{
let wall = new Object3D();
let mr = wall.addComponent(MeshRenderer);
mr.geometry = new BoxGeometry(5, 260, 320);
mr.material = mat;
wall.x = -320 * 0.5;
this.scene.addChild(wall);
}
{
let wall = new Object3D();
let mr = wall.addComponent(MeshRenderer);
mr.geometry = new BoxGeometry(5, 260, 320);
mr.material = mat;
wall.x = 320 * 0.5;
this.scene.addChild(wall);
}
{
let wall = new Object3D();
let mr = wall.addComponent(MeshRenderer);
mr.geometry = new BoxGeometry(320, 260, 5);
mr.material = mat;
wall.z = -320 * 0.5;
this.scene.addChild(wall);
}
{
{
let sp = new Object3D();
let mr = sp.addComponent(MeshRenderer);
mr.geometry = new SphereGeometry(50, 30, 30);
mr.material = mat;
this.scene.addChild(sp);
}
}
}
}
private gui() {
let postProcessing = this.scene.getComponent(PostProcessingComponent);
let post = postProcessing.getPost(GTAOPost);
let GUIHelp = new dat.GUI();
let f = GUIHelp.addFolder('GTAO');
f.add(post, 'maxDistance', 0.0, 50, 1);
f.add(post, 'maxPixel', 0.0, 50, 1);
f.add(post, 'rayMarchSegment', 4, 10, 0.001);
f.add(post, 'darkFactor', 0.0, 5, 0.001);
f.add(post, 'blendColor');
f.add(post, 'multiBounce');
f.open();
}
}
new Sample_GTAO().run();