Enhance advanced rendering by adding normal pass and refining SSAO effect settings
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import { BasicShadowMap, DirectionalLight, HalfFloatType, Mesh, NoToneMapping, PCFShadowMap, PCFSoftShadowMap, PointLight, SpotLight, UnsignedByteType } from "three";
|
||||
import { BloomEffect, DepthOfFieldEffect, EffectComposer, EffectPass, RenderPass, SMAAEffect, SMAAPreset, SSAOEffect, ToneMappingEffect, ToneMappingMode } from "postprocessing";
|
||||
import { BloomEffect, DepthOfFieldEffect, EffectComposer, EffectPass, NormalPass, RenderPass, SMAAEffect, SMAAPreset, SSAOEffect, ToneMappingEffect, ToneMappingMode } from "postprocessing";
|
||||
const AMBIENT_OCCLUSION_LUMINANCE_INFLUENCE = 0.15;
|
||||
const MAX_AMBIENT_OCCLUSION_EFFECT_RADIUS = 0.2;
|
||||
export function resolveBoxVolumeRenderPaths(settings) {
|
||||
if (!settings.enabled) {
|
||||
return {
|
||||
@@ -43,9 +45,10 @@ export function configureAdvancedRenderingRenderer(renderer, settings) {
|
||||
renderer.toneMappingExposure = settings.toneMapping.exposure;
|
||||
}
|
||||
export function createAdvancedRenderingComposer(renderer, scene, camera, settings) {
|
||||
const requiresDepthBuffer = settings.ambientOcclusion.enabled || settings.depthOfField.enabled;
|
||||
// The scene is always rendered into the composer's offscreen targets first,
|
||||
// so those targets need depth for correct visibility even when no effect samples it.
|
||||
const composer = new EffectComposer(renderer, {
|
||||
depthBuffer: requiresDepthBuffer,
|
||||
depthBuffer: true,
|
||||
stencilBuffer: false,
|
||||
multisampling: 0,
|
||||
frameBufferType: renderer.capabilities.isWebGL2 ? HalfFloatType : UnsignedByteType
|
||||
@@ -53,9 +56,15 @@ export function createAdvancedRenderingComposer(renderer, scene, camera, setting
|
||||
composer.addPass(new RenderPass(scene, camera));
|
||||
const effects = [];
|
||||
if (settings.ambientOcclusion.enabled) {
|
||||
effects.push(new SSAOEffect(camera, undefined, {
|
||||
// postprocessing's internal depth-downsampling path writes zero normals unless
|
||||
// a real normal buffer is supplied, which turns SSAO into speckled noise.
|
||||
const normalPass = new NormalPass(scene, camera);
|
||||
composer.addPass(normalPass);
|
||||
effects.push(new SSAOEffect(camera, normalPass.texture, {
|
||||
depthAwareUpsampling: true,
|
||||
luminanceInfluence: AMBIENT_OCCLUSION_LUMINANCE_INFLUENCE,
|
||||
samples: settings.ambientOcclusion.samples,
|
||||
radius: settings.ambientOcclusion.radius,
|
||||
radius: Math.min(settings.ambientOcclusion.radius, MAX_AMBIENT_OCCLUSION_EFFECT_RADIUS),
|
||||
intensity: settings.ambientOcclusion.intensity
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
DepthOfFieldEffect,
|
||||
EffectComposer,
|
||||
EffectPass,
|
||||
NormalPass,
|
||||
RenderPass,
|
||||
SMAAEffect,
|
||||
SMAAPreset,
|
||||
@@ -35,6 +36,9 @@ import type {
|
||||
AdvancedRenderingToneMappingMode
|
||||
} from "../document/world-settings";
|
||||
|
||||
const AMBIENT_OCCLUSION_LUMINANCE_INFLUENCE = 0.15;
|
||||
const MAX_AMBIENT_OCCLUSION_EFFECT_RADIUS = 0.2;
|
||||
|
||||
export interface ResolvedBoxVolumeRenderPaths {
|
||||
fog: BoxVolumeRenderPath;
|
||||
water: BoxVolumeRenderPath;
|
||||
@@ -93,9 +97,10 @@ export function createAdvancedRenderingComposer(
|
||||
camera: PerspectiveCamera,
|
||||
settings: AdvancedRenderingSettings
|
||||
): EffectComposer {
|
||||
const requiresDepthBuffer = settings.ambientOcclusion.enabled || settings.depthOfField.enabled;
|
||||
// The scene is always rendered into the composer's offscreen targets first,
|
||||
// so those targets need depth for correct visibility even when no effect samples it.
|
||||
const composer = new EffectComposer(renderer, {
|
||||
depthBuffer: requiresDepthBuffer,
|
||||
depthBuffer: true,
|
||||
stencilBuffer: false,
|
||||
multisampling: 0,
|
||||
frameBufferType: renderer.capabilities.isWebGL2 ? HalfFloatType : UnsignedByteType
|
||||
@@ -106,10 +111,17 @@ export function createAdvancedRenderingComposer(
|
||||
const effects: Array<SSAOEffect | BloomEffect | DepthOfFieldEffect | ToneMappingEffect | SMAAEffect> = [];
|
||||
|
||||
if (settings.ambientOcclusion.enabled) {
|
||||
// postprocessing's internal depth-downsampling path writes zero normals unless
|
||||
// a real normal buffer is supplied, which turns SSAO into speckled noise.
|
||||
const normalPass = new NormalPass(scene, camera);
|
||||
composer.addPass(normalPass);
|
||||
|
||||
effects.push(
|
||||
new SSAOEffect(camera, undefined, {
|
||||
new SSAOEffect(camera, normalPass.texture, {
|
||||
depthAwareUpsampling: true,
|
||||
luminanceInfluence: AMBIENT_OCCLUSION_LUMINANCE_INFLUENCE,
|
||||
samples: settings.ambientOcclusion.samples,
|
||||
radius: settings.ambientOcclusion.radius,
|
||||
radius: Math.min(settings.ambientOcclusion.radius, MAX_AMBIENT_OCCLUSION_EFFECT_RADIUS),
|
||||
intensity: settings.ambientOcclusion.intensity
|
||||
})
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user