环境光遮蔽 - GTAO
AO
是用来描绘物体和物体相交或靠近的时候遮挡周围漫反射光线的效果,可以解决或改善漏光、飘和阴影不实等问题,解决或改善场景中缝隙、褶皱与墙角、角线以及细小物体等的表现不清晰问题,综合改善细节尤其是暗部阴影,增强空间的层次感、真实感,同时加强和改善画面明暗对比,增强画面的艺术性。引擎内部通过采样指定屏幕范围内,指定距离范围内的像素点,求积分用于赋值当前像素 AO
系数。
ts
//初始化引擎
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;
// 添加 GTAOPost
let postProcessing = this.scene.addComponent(PostProcessingComponent);
postProcessing.addPost(GTAOPost);
//开始渲染
let view = new View3D();
view.scene = this.scene;
view.camera = this.camera;
Engine3D.startRenderView(view);
//初始化引擎
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;
// 添加 GTAOPost
let postProcessing = this.scene.addComponent(PostProcessingComponent);
postProcessing.addPost(GTAOPost);
//开始渲染
let view = new View3D();
view.scene = this.scene;
view.camera = this.camera;
Engine3D.startRenderView(view);
Engine3D.setting.render.postProcessing.gtao 配置参数。
参数 | 类型 | 描述 |
---|---|---|
maxDistance | number | 设定ao采样时搜索3D空间周边的最大距离。 |
maxPixel | number | 设定ao采样时搜索周边像素时的最大距离。 |
darkFactor | number | 设定ao数值参与输出到屏幕时的系数,1:全部输出,0:不输出。 |
rayMarchSegment | number | 设定ao采样时的步进的步数,值越大将会获得质量更好的ao效果,同时消耗更多的性能。 |
multiBounce | boolean | 是否模拟颜色反弹。 |
blendColor | boolean | true:将与GBuffer的mainColor混合;false:将只输出ao的颜色。 |
ts
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.0002
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 = 60
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 = 30
this.scene.addChild(this.lightObj)
}
{
let mat = new LitMaterial()
mat.baseMap = Engine3D.res.grayTexture
mat.normalMap = Engine3D.res.normalTexture
mat.aoMap = Engine3D.res.whiteTexture
mat.maskMap = Engine3D.res.createTexture(32, 32, 255.0, 255.0, 0.0, 1)
mat.emissiveMap = Engine3D.res.blackTexture
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()
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.0002
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 = 60
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 = 30
this.scene.addChild(this.lightObj)
}
{
let mat = new LitMaterial()
mat.baseMap = Engine3D.res.grayTexture
mat.normalMap = Engine3D.res.normalTexture
mat.aoMap = Engine3D.res.whiteTexture
mat.maskMap = Engine3D.res.createTexture(32, 32, 255.0, 255.0, 0.0, 1)
mat.emissiveMap = Engine3D.res.blackTexture
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()