Implement advanced anti-aliasing support (FXAA/SMAA) in rendering pipeline

This commit is contained in:
2026-05-21 08:08:56 +02:00
parent c010602b45
commit 8a5611ed4c
2 changed files with 60 additions and 7 deletions

View File

@@ -198,6 +198,7 @@ import {
type FaceUvState type FaceUvState
} from "../document/brushes"; } from "../document/brushes";
import { import {
ADVANCED_RENDERING_ANTI_ALIASING_MODES,
ADVANCED_RENDERING_DYNAMIC_GLOBAL_ILLUMINATION_QUALITIES, ADVANCED_RENDERING_DYNAMIC_GLOBAL_ILLUMINATION_QUALITIES,
ADVANCED_RENDERING_WATER_REFLECTION_MODES, ADVANCED_RENDERING_WATER_REFLECTION_MODES,
BOX_VOLUME_RENDER_PATHS, BOX_VOLUME_RENDER_PATHS,
@@ -225,6 +226,7 @@ import {
type WorldBackgroundSettings, type WorldBackgroundSettings,
type AdvancedRenderingSettings, type AdvancedRenderingSettings,
type AdvancedRenderingDistanceFogSettings, type AdvancedRenderingDistanceFogSettings,
type AdvancedRenderingAntiAliasingMode,
type BoxVolumeRenderPath, type BoxVolumeRenderPath,
type AdvancedRenderingWaterReflectionMode, type AdvancedRenderingWaterReflectionMode,
type AdvancedRenderingDynamicGlobalIlluminationQuality, type AdvancedRenderingDynamicGlobalIlluminationQuality,

View File

@@ -28,6 +28,7 @@ import {
DepthOfFieldEffect, DepthOfFieldEffect,
EffectComposer, EffectComposer,
EffectPass, EffectPass,
FXAAEffect,
NormalPass, NormalPass,
RenderPass, RenderPass,
ShaderPass, ShaderPass,
@@ -40,6 +41,7 @@ import {
import type { import type {
AdvancedRenderingSettings, AdvancedRenderingSettings,
AdvancedRenderingAntiAliasingMode,
BoxVolumeRenderPath, BoxVolumeRenderPath,
AdvancedRenderingShadowType, AdvancedRenderingShadowType,
AdvancedRenderingToneMappingMode AdvancedRenderingToneMappingMode
@@ -246,6 +248,48 @@ export function getAdvancedRenderingToneMappingMode(
} }
} }
function getAdvancedRenderingAntiAliasingMultisampling(
renderer: WebGLRenderer,
settings: AdvancedRenderingSettings
) {
if (
!settings.enabled ||
!settings.antiAliasing.enabled ||
!renderer.capabilities.isWebGL2
) {
return 0;
}
switch (settings.antiAliasing.mode) {
case "msaa2x":
return 2;
case "msaa4x":
return 4;
case "msaa8x":
return 8;
case "smaa":
case "fxaa":
return 0;
}
}
function createAdvancedRenderingAntiAliasingEffect(
mode: AdvancedRenderingAntiAliasingMode
): FXAAEffect | SMAAEffect | null {
switch (mode) {
case "smaa":
return new SMAAEffect({
preset: SMAAPreset.MEDIUM
});
case "fxaa":
return new FXAAEffect();
case "msaa2x":
case "msaa4x":
case "msaa8x":
return null;
}
}
export function configureAdvancedRenderingRenderer( export function configureAdvancedRenderingRenderer(
renderer: WebGLRenderer, renderer: WebGLRenderer,
settings: AdvancedRenderingSettings settings: AdvancedRenderingSettings
@@ -330,7 +374,10 @@ export function createAdvancedRenderingComposer(
const composer = new EffectComposer(renderer, { const composer = new EffectComposer(renderer, {
depthBuffer: true, depthBuffer: true,
stencilBuffer: false, stencilBuffer: false,
multisampling: 0, multisampling: getAdvancedRenderingAntiAliasingMultisampling(
renderer,
settings
),
frameBufferType: renderer.capabilities.isWebGL2 frameBufferType: renderer.capabilities.isWebGL2
? HalfFloatType ? HalfFloatType
: UnsignedByteType : UnsignedByteType
@@ -376,7 +423,7 @@ export function createAdvancedRenderingComposer(
} }
const effects: Array< const effects: Array<
BloomEffect | DepthOfFieldEffect | ToneMappingEffect | SMAAEffect BloomEffect | DepthOfFieldEffect | FXAAEffect | ToneMappingEffect | SMAAEffect
> = []; > = [];
if (settings.ambientOcclusion.enabled || dynamicGlobalIlluminationEnabled) { if (settings.ambientOcclusion.enabled || dynamicGlobalIlluminationEnabled) {
@@ -523,11 +570,15 @@ export function createAdvancedRenderingComposer(
mode: getAdvancedRenderingToneMappingMode(settings.toneMapping.mode) mode: getAdvancedRenderingToneMappingMode(settings.toneMapping.mode)
}) })
); );
effects.push( if (settings.antiAliasing.enabled) {
new SMAAEffect({ const antiAliasingEffect = createAdvancedRenderingAntiAliasingEffect(
preset: SMAAPreset.MEDIUM settings.antiAliasing.mode
}) );
);
if (antiAliasingEffect !== null) {
effects.push(antiAliasingEffect);
}
}
composer.addPass(new EffectPass(camera, ...effects)); composer.addPass(new EffectPass(camera, ...effects));