101 lines
3.8 KiB
JavaScript
101 lines
3.8 KiB
JavaScript
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";
|
|
export function resolveBoxVolumeRenderPaths(settings) {
|
|
if (!settings.enabled) {
|
|
return {
|
|
fog: "performance",
|
|
water: "performance"
|
|
};
|
|
}
|
|
return {
|
|
fog: settings.fogPath,
|
|
water: settings.waterPath
|
|
};
|
|
}
|
|
export function getAdvancedRenderingShadowMapType(shadowType) {
|
|
switch (shadowType) {
|
|
case "basic":
|
|
return BasicShadowMap;
|
|
case "pcf":
|
|
return PCFShadowMap;
|
|
case "pcfSoft":
|
|
return PCFSoftShadowMap;
|
|
}
|
|
}
|
|
export function getAdvancedRenderingToneMappingMode(mode) {
|
|
switch (mode) {
|
|
case "none":
|
|
return ToneMappingMode.LINEAR;
|
|
case "linear":
|
|
return ToneMappingMode.LINEAR;
|
|
case "reinhard":
|
|
return ToneMappingMode.REINHARD;
|
|
case "cineon":
|
|
return ToneMappingMode.CINEON;
|
|
case "acesFilmic":
|
|
return ToneMappingMode.ACES_FILMIC;
|
|
}
|
|
}
|
|
export function configureAdvancedRenderingRenderer(renderer, settings) {
|
|
renderer.shadowMap.enabled = settings.enabled && settings.shadows.enabled;
|
|
renderer.shadowMap.type = getAdvancedRenderingShadowMapType(settings.shadows.type);
|
|
renderer.toneMapping = NoToneMapping;
|
|
renderer.toneMappingExposure = settings.toneMapping.exposure;
|
|
}
|
|
export function createAdvancedRenderingComposer(renderer, scene, camera, settings) {
|
|
const composer = new EffectComposer(renderer, {
|
|
multisampling: 0,
|
|
frameBufferType: renderer.capabilities.isWebGL2 ? HalfFloatType : UnsignedByteType
|
|
});
|
|
composer.addPass(new RenderPass(scene, camera));
|
|
const effects = [];
|
|
if (settings.ambientOcclusion.enabled) {
|
|
effects.push(new SSAOEffect(camera, undefined, {
|
|
samples: settings.ambientOcclusion.samples,
|
|
radius: settings.ambientOcclusion.radius,
|
|
intensity: settings.ambientOcclusion.intensity
|
|
}));
|
|
}
|
|
if (settings.bloom.enabled) {
|
|
effects.push(new BloomEffect({
|
|
intensity: settings.bloom.intensity,
|
|
luminanceThreshold: settings.bloom.threshold,
|
|
radius: settings.bloom.radius
|
|
}));
|
|
}
|
|
if (settings.depthOfField.enabled) {
|
|
effects.push(new DepthOfFieldEffect(camera, {
|
|
focusDistance: settings.depthOfField.focusDistance,
|
|
focalLength: settings.depthOfField.focalLength,
|
|
bokehScale: settings.depthOfField.bokehScale
|
|
}));
|
|
}
|
|
effects.push(new ToneMappingEffect({
|
|
mode: getAdvancedRenderingToneMappingMode(settings.toneMapping.mode)
|
|
}));
|
|
effects.push(new SMAAEffect({
|
|
preset: SMAAPreset.MEDIUM
|
|
}));
|
|
composer.addPass(new EffectPass(camera, ...effects));
|
|
return composer;
|
|
}
|
|
export function applyAdvancedRenderingRenderableShadowFlags(root, enabled) {
|
|
root.traverse((object) => {
|
|
if (object.isMesh === true && object.userData.shadowIgnored !== true) {
|
|
const mesh = object;
|
|
mesh.castShadow = enabled;
|
|
mesh.receiveShadow = enabled;
|
|
}
|
|
});
|
|
}
|
|
export function applyAdvancedRenderingLightShadowFlags(root, settings) {
|
|
const shadowEnabled = settings.enabled && settings.shadows.enabled;
|
|
root.traverse((object) => {
|
|
if (object instanceof DirectionalLight || object instanceof PointLight || object instanceof SpotLight) {
|
|
object.castShadow = shadowEnabled;
|
|
object.shadow.bias = settings.shadows.bias;
|
|
object.shadow.mapSize.set(settings.shadows.mapSize, settings.shadows.mapSize);
|
|
}
|
|
});
|
|
}
|