From 572e1434e452cb02e115810e5e2e2d1083f56452 Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Thu, 21 May 2026 08:11:20 +0200 Subject: [PATCH] auto-git: [change] src/app/App.tsx [change] src/document/migrate-scene-document.ts [change] src/document/scene-document-validation.ts [change] src/document/scene-document.ts [change] src/document/world-settings.ts [change] src/rendering/advanced-rendering.ts [change] tests/domain/advanced-rendering.test.ts [change] tests/serialization/scene-document-json.test.ts --- src/app/App.tsx | 11 +- src/document/migrate-scene-document.ts | 4 +- src/document/scene-document-validation.ts | 27 ++-- src/document/scene-document.ts | 6 +- src/document/world-settings.ts | 3 +- src/rendering/advanced-rendering.ts | 6 +- tests/domain/advanced-rendering.test.ts | 137 +++++++++++++++++- .../serialization/scene-document-json.test.ts | 7 +- 8 files changed, 160 insertions(+), 41 deletions(-) diff --git a/src/app/App.tsx b/src/app/App.tsx index ef9ea922..3da285eb 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -14044,8 +14044,7 @@ export function App({ "Set foliage wind direction", "Updated the foliage wind direction.", (advancedRendering) => { - advancedRendering.foliage.windDirectionDegrees = - windDirectionDegrees; + advancedRendering.foliage.windDirectionDegrees = windDirectionDegrees; } ); } catch (error) { @@ -21920,9 +21919,7 @@ export function App({ type="number" min="0" step="0.05" - value={ - advancedRenderingLensFlareIntensityDraft - } + value={advancedRenderingLensFlareIntensityDraft} onChange={(event) => setAdvancedRenderingLensFlareIntensityDraft( event.currentTarget.value @@ -21965,9 +21962,7 @@ export function App({ event.currentTarget.value ) } - onBlur={ - applyAdvancedRenderingLensFlareHaloSize - } + onBlur={applyAdvancedRenderingLensFlareHaloSize} onKeyDown={(event) => handleDraftVectorKeyDown( event, diff --git a/src/document/migrate-scene-document.ts b/src/document/migrate-scene-document.ts index 14ed3c6d..2689ab8d 100644 --- a/src/document/migrate-scene-document.ts +++ b/src/document/migrate-scene-document.ts @@ -889,9 +889,7 @@ function readAdvancedRenderingSettings( } if (value.antiAliasing !== undefined && !isRecord(value.antiAliasing)) { - throw new Error( - "world.advancedRendering.antiAliasing must be an object." - ); + throw new Error("world.advancedRendering.antiAliasing must be an object."); } if (value.depthOfField !== undefined && !isRecord(value.depthOfField)) { diff --git a/src/document/scene-document-validation.ts b/src/document/scene-document-validation.ts index a2611f91..b48039c8 100644 --- a/src/document/scene-document-validation.ts +++ b/src/document/scene-document-validation.ts @@ -1147,7 +1147,9 @@ function validateWorldSettings( ); } - if (!isAdvancedRenderingAntiAliasingMode(advancedRendering.antiAliasing.mode)) { + if ( + !isAdvancedRenderingAntiAliasingMode(advancedRendering.antiAliasing.mode) + ) { diagnostics.push( createDiagnostic( "error", @@ -1261,9 +1263,7 @@ function validateWorldSettings( ); } - if ( - !isNonNegativeFiniteNumber(advancedRendering.distanceFog.nearDistance) - ) { + if (!isNonNegativeFiniteNumber(advancedRendering.distanceFog.nearDistance)) { diagnostics.push( createDiagnostic( "error", @@ -3611,7 +3611,12 @@ function validateSplineCorridorJunction( ) ); } else { - validateScenePathRoadEdge(junction.edge, `${path}.edge`, document, diagnostics); + validateScenePathRoadEdge( + junction.edge, + `${path}.edge`, + document, + diagnostics + ); } if (!Array.isArray(junction.connections) || junction.connections.length < 2) { @@ -3950,8 +3955,7 @@ function validateTerrain( ); } - const expectedFoliageMaskValueCount = - mask.resolutionX * mask.resolutionZ; + const expectedFoliageMaskValueCount = mask.resolutionX * mask.resolutionZ; if (mask.values.length !== expectedFoliageMaskValueCount) { diagnostics.push( @@ -5172,9 +5176,7 @@ function validatePlayerStartEntity( ); } - if ( - !isPlayerStartGamepadActionBinding(entity.inputBindings?.gamepad.climb) - ) { + if (!isPlayerStartGamepadActionBinding(entity.inputBindings?.gamepad.climb)) { diagnostics.push( createDiagnostic( "error", @@ -5957,10 +5959,7 @@ function validateNpcEntity( ); } - if ( - typeof entity.targetAnchor !== "object" || - entity.targetAnchor === null - ) { + if (typeof entity.targetAnchor !== "object" || entity.targetAnchor === null) { diagnostics.push( createDiagnostic( "error", diff --git a/src/document/scene-document.ts b/src/document/scene-document.ts index b6747c73..d3f1c59f 100644 --- a/src/document/scene-document.ts +++ b/src/document/scene-document.ts @@ -41,8 +41,10 @@ export const ANTI_ALIASING_SCENE_DOCUMENT_VERSION = 113 as const; export const FOLIAGE_WIND_SCENE_DOCUMENT_VERSION = 112 as const; export const LENS_FLARE_SCENE_DOCUMENT_VERSION = 111 as const; export const CUSTOM_PBR_MATERIALS_SCENE_DOCUMENT_VERSION = 110 as const; -export const SPLINE_CORRIDOR_JUNCTION_SHAPE_SCENE_DOCUMENT_VERSION = 109 as const; -export const SPLINE_CORRIDOR_JUNCTION_EDGE_SCENE_DOCUMENT_VERSION = 108 as const; +export const SPLINE_CORRIDOR_JUNCTION_SHAPE_SCENE_DOCUMENT_VERSION = + 109 as const; +export const SPLINE_CORRIDOR_JUNCTION_EDGE_SCENE_DOCUMENT_VERSION = + 108 as const; export const SPLINE_CORRIDOR_JUNCTIONS_SCENE_DOCUMENT_VERSION = 107 as const; export const SPLINE_CORRIDOR_COLLISION_SCENE_DOCUMENT_VERSION = 106 as const; export const SPLINE_REPEATERS_SCENE_DOCUMENT_VERSION = 105 as const; diff --git a/src/document/world-settings.ts b/src/document/world-settings.ts index 655fe1c8..81eaab5a 100644 --- a/src/document/world-settings.ts +++ b/src/document/world-settings.ts @@ -759,8 +759,7 @@ export function createDefaultAdvancedRenderingSettings(): AdvancedRenderingSetti enabled: false, intensity: DEFAULT_ADVANCED_RENDERING_LENS_FLARE_INTENSITY, haloSize: DEFAULT_ADVANCED_RENDERING_LENS_FLARE_HALO_SIZE, - ghostIntensity: - DEFAULT_ADVANCED_RENDERING_LENS_FLARE_GHOST_INTENSITY, + ghostIntensity: DEFAULT_ADVANCED_RENDERING_LENS_FLARE_GHOST_INTENSITY, ghostCount: DEFAULT_ADVANCED_RENDERING_LENS_FLARE_GHOST_COUNT }, foliage: createDefaultFoliageQualitySettings(), diff --git a/src/rendering/advanced-rendering.ts b/src/rendering/advanced-rendering.ts index 7f5cc2a5..08fb331e 100644 --- a/src/rendering/advanced-rendering.ts +++ b/src/rendering/advanced-rendering.ts @@ -423,7 +423,11 @@ export function createAdvancedRenderingComposer( } const effects: Array< - BloomEffect | DepthOfFieldEffect | FXAAEffect | ToneMappingEffect | SMAAEffect + | BloomEffect + | DepthOfFieldEffect + | FXAAEffect + | ToneMappingEffect + | SMAAEffect > = []; if (settings.ambientOcclusion.enabled || dynamicGlobalIlluminationEnabled) { diff --git a/tests/domain/advanced-rendering.test.ts b/tests/domain/advanced-rendering.test.ts index 052b8bd1..0b7abf0d 100644 --- a/tests/domain/advanced-rendering.test.ts +++ b/tests/domain/advanced-rendering.test.ts @@ -486,9 +486,9 @@ describe("god rays parameters", () => { } }; - expect( - resolveDominantScreenSpaceGodRaysLightInput(visibleSun, null) - ).toBe(visibleSun); + expect(resolveDominantScreenSpaceGodRaysLightInput(visibleSun, null)).toBe( + visibleSun + ); expect( resolveDominantScreenSpaceGodRaysLightInput(visibleSun, visibleMoon) ).toBe(visibleMoon); @@ -532,9 +532,9 @@ describe("god rays parameters", () => { ).toBeGreaterThan(0.5); expect(resolveGodRaysSourceMask(0.035)).toBeLessThan(0.5); expect(resolveGodRaysSourceMask(0.035, 2)).toBeGreaterThan(0.5); - expect( - resolveGodRaysSourceMask(GOD_RAYS_SOURCE_MASK_RADII.haloOuter) - ).toBe(0); + expect(resolveGodRaysSourceMask(GOD_RAYS_SOURCE_MASK_RADII.haloOuter)).toBe( + 0 + ); }); }); @@ -667,6 +667,131 @@ describe("createAdvancedRenderingComposer", () => { expect(postprocessingState.ssaoCalls).toHaveLength(0); }); + it("keeps SMAA as the default post-process anti-aliasing effect", () => { + resetPostprocessingState(); + + const settings = createDefaultWorldSettings().advancedRendering; + settings.enabled = true; + + createAdvancedRenderingComposer( + { + capabilities: { + isWebGL2: true + } + } as unknown as never, + new Scene(), + new PerspectiveCamera(), + settings + ); + + expect(postprocessingState.composerOptions[0]).toMatchObject({ + multisampling: 0 + }); + expect(getLastEffectPassEffectNames()).toEqual([ + "MockToneMappingEffect", + "MockSMAAEffect" + ]); + }); + + it("can disable anti-aliasing in the post stack", () => { + resetPostprocessingState(); + + const settings = createDefaultWorldSettings().advancedRendering; + settings.enabled = true; + settings.antiAliasing.enabled = false; + + createAdvancedRenderingComposer( + { + capabilities: { + isWebGL2: true + } + } as unknown as never, + new Scene(), + new PerspectiveCamera(), + settings + ); + + expect(postprocessingState.composerOptions[0]).toMatchObject({ + multisampling: 0 + }); + expect(getLastEffectPassEffectNames()).toEqual(["MockToneMappingEffect"]); + }); + + it("uses FXAA when selected", () => { + resetPostprocessingState(); + + const settings = createDefaultWorldSettings().advancedRendering; + settings.enabled = true; + settings.antiAliasing.mode = "fxaa"; + + createAdvancedRenderingComposer( + { + capabilities: { + isWebGL2: true + } + } as unknown as never, + new Scene(), + new PerspectiveCamera(), + settings + ); + + expect(postprocessingState.composerOptions[0]).toMatchObject({ + multisampling: 0 + }); + expect(getLastEffectPassEffectNames()).toEqual([ + "MockToneMappingEffect", + "MockFXAAEffect" + ]); + }); + + it("uses composer MSAA samples on WebGL2 when an MSAA mode is selected", () => { + resetPostprocessingState(); + + const settings = createDefaultWorldSettings().advancedRendering; + settings.enabled = true; + settings.antiAliasing.mode = "msaa4x"; + + createAdvancedRenderingComposer( + { + capabilities: { + isWebGL2: true + } + } as unknown as never, + new Scene(), + new PerspectiveCamera(), + settings + ); + + expect(postprocessingState.composerOptions[0]).toMatchObject({ + multisampling: 4 + }); + expect(getLastEffectPassEffectNames()).toEqual(["MockToneMappingEffect"]); + }); + + it("falls back to no composer MSAA samples outside WebGL2", () => { + resetPostprocessingState(); + + const settings = createDefaultWorldSettings().advancedRendering; + settings.enabled = true; + settings.antiAliasing.mode = "msaa8x"; + + createAdvancedRenderingComposer( + { + capabilities: { + isWebGL2: false + } + } as unknown as never, + new Scene(), + new PerspectiveCamera(), + settings + ); + + expect(postprocessingState.composerOptions[0]).toMatchObject({ + multisampling: 0 + }); + expect(getLastEffectPassEffectNames()).toEqual(["MockToneMappingEffect"]); + }); + it("adds distance fog before post-world overlay layers", () => { postprocessingState.composerOptions.length = 0; postprocessingState.composerPasses.length = 0; diff --git a/tests/serialization/scene-document-json.test.ts b/tests/serialization/scene-document-json.test.ts index 17406816..3f8a9834 100644 --- a/tests/serialization/scene-document-json.test.ts +++ b/tests/serialization/scene-document-json.test.ts @@ -1877,11 +1877,8 @@ describe("scene document JSON", () => { const legacyDocument = JSON.parse( serializeSceneDocument(emptyScene) ) as Record; - const legacyFoliage = - legacyDocument.world.advancedRendering.foliage as Record< - string, - unknown - >; + const legacyFoliage = legacyDocument.world.advancedRendering + .foliage as Record; legacyDocument.version = LENS_FLARE_SCENE_DOCUMENT_VERSION; delete legacyFoliage.windEnabled;