diff --git a/packages/frontend-misskey-world-engine/src/room/engine.ts b/packages/frontend-misskey-world-engine/src/room/engine.ts index f6f9b6b7e6..5cb470757c 100644 --- a/packages/frontend-misskey-world-engine/src/room/engine.ts +++ b/packages/frontend-misskey-world-engine/src/room/engine.ts @@ -1134,6 +1134,8 @@ export class RoomEngine extends EngineBase<{ this.grabbingCtx.onDone?.(); } this.grabbingCtx = null; + + this.envManager.renderShadow(); } public interact(oid: string, iid: string | null = null) { @@ -1369,6 +1371,8 @@ export class RoomEngine extends EngineBase<{ this.selectFuniture(null); this.isEditMode = false; + await this.envManager.renderShadow(); + await this.bake(); } @@ -1515,14 +1519,11 @@ export class RoomEngine extends EngineBase<{ // TODO: loadFunitureのものとある程度共通化 p.registerMeshes = (meshes) => { for (const mesh of meshes) { + mesh.receiveShadows = false; if (SYSTEM_MESH_NAMES.some(n => mesh.name.includes(n))) { - mesh.receiveShadows = false; mesh.isVisible = false; } else { mesh.metadata = { isPlayer: true, playerId: k }; - mesh.receiveShadows = true; - // TODO: メモリリークしそうだからいい感じにする - this.envManager.addShadowCaster(mesh); //if (mesh.material) (mesh.material as BABYLON.PBRMaterial).ambientColor = new BABYLON.Color3(0.2, 0.2, 0.2); if (mesh.material) { diff --git a/packages/frontend-misskey-world-engine/src/room/env.ts b/packages/frontend-misskey-world-engine/src/room/env.ts index bb4f13e406..9172909915 100644 --- a/packages/frontend-misskey-world-engine/src/room/env.ts +++ b/packages/frontend-misskey-world-engine/src/room/env.ts @@ -14,7 +14,7 @@ export abstract class EnvManager { protected engine: RoomEngine; public abstract envMapIndoor: BABYLON.CubeTexture | null; public abstract maxCameraZ: number; - protected shadowGenerators: BABYLON.ShadowGenerator[] = []; + private shadowGenerators: BABYLON.ShadowGenerator[] = []; protected isRoomLightOn = true; constructor(engine: RoomEngine) { @@ -36,6 +36,24 @@ export abstract class EnvManager { this.applyRoomLight(); } + protected registerShadowGenerator(shadowGenerator: BABYLON.ShadowGenerator) { + this.shadowGenerators.push(shadowGenerator); + + const shadowMap = shadowGenerator.getShadowMap()!; + shadowMap.refreshRate = BABYLON.RenderTargetTexture.REFRESHRATE_RENDER_ONCE; + + // https://forum.babylonjs.com/t/is-it-intentional-that-the-shadow-map-refresh-rate-is-ignored-under-fast-snapshot-rendering/63523 + const objectRenderer = shadowMap._objectRenderer; + const originalShouldRender = objectRenderer.shouldRender.bind(objectRenderer); + objectRenderer.shouldRender = function () { + if (this._engine.snapshotRendering) { + return this.refreshRate !== BABYLON.RenderTargetTexture.REFRESHRATE_RENDER_ONCE; + } + + return originalShouldRender(); + }; + } + public addShadowCaster(mesh: BABYLON.AbstractMesh) { for (const shadowGen of this.shadowGenerators) { shadowGen.addShadowCaster(mesh); @@ -48,6 +66,24 @@ export abstract class EnvManager { } } + public async renderShadow() { + this.engine.sr.disableSnapshotRendering(); + + for (const shadowGen of this.shadowGenerators) { + const shadowMap = shadowGen.getShadowMap()!; + shadowMap.refreshRate = 1; + } + + await new Promise(resolve => setTimeout(resolve, 1)); + + for (const shadowGen of this.shadowGenerators) { + const shadowMap = shadowGen.getShadowMap()!; + shadowMap.refreshRate = BABYLON.RenderTargetTexture.REFRESHRATE_RENDER_ONCE; + } + + this.engine.sr.enableSnapshotRendering(); + } + protected registerMeshes(meshes: BABYLON.AbstractMesh[]) { for (const mesh of meshes) { if (!this.engine.scene.meshes.includes(mesh)) this.engine.scene.addMesh(mesh); diff --git a/packages/frontend-misskey-world-engine/src/room/envs/customMadori.ts b/packages/frontend-misskey-world-engine/src/room/envs/customMadori.ts index 8d8e17bcd7..5e224cfa27 100644 --- a/packages/frontend-misskey-world-engine/src/room/envs/customMadori.ts +++ b/packages/frontend-misskey-world-engine/src/room/envs/customMadori.ts @@ -62,12 +62,9 @@ export class CustomMadoriEnvManager extends EnvManager { shadowGeneratorForRoomLight.bias = 0.0005; shadowGeneratorForRoomLight.usePercentageCloserFiltering = true; shadowGeneratorForRoomLight.filteringQuality = BABYLON.ShadowGenerator.QUALITY_HIGH; - if (this.engine.graphicsQuality <= GRAPHICS_QUALITY.MEDIUM) { - shadowGeneratorForRoomLight.getShadowMap().refreshRate = 60; // 効いてなさそう babylonのバグ? - } //shadowGeneratorForRoomLight.useContactHardeningShadow = true; //shadowGeneratorForRoomLight.contactHardeningLightSizeUVRatio = 0.01; - this.shadowGenerators.push(shadowGeneratorForRoomLight); + this.registerShadowGenerator(shadowGeneratorForRoomLight); } for (const materialDef of options.flooringMaterials) { diff --git a/packages/frontend-misskey-world-engine/src/room/envs/japanese.ts b/packages/frontend-misskey-world-engine/src/room/envs/japanese.ts index e26e60ed01..1b31ac7f25 100644 --- a/packages/frontend-misskey-world-engine/src/room/envs/japanese.ts +++ b/packages/frontend-misskey-world-engine/src/room/envs/japanese.ts @@ -46,12 +46,9 @@ export class JapaneseEnvManager extends EnvManager { shadowGeneratorForRoomLight.bias = 0.0005; shadowGeneratorForRoomLight.usePercentageCloserFiltering = true; shadowGeneratorForRoomLight.filteringQuality = BABYLON.ShadowGenerator.QUALITY_HIGH; - if (this.engine.graphicsQuality <= GRAPHICS_QUALITY.MEDIUM) { - shadowGeneratorForRoomLight.getShadowMap().refreshRate = 60; - } //shadowGeneratorForRoomLight.useContactHardeningShadow = true; //shadowGeneratorForRoomLight.contactHardeningLightSizeUVRatio = 0.01; - this.shadowGenerators.push(shadowGeneratorForRoomLight); + this.registerShadowGenerator(shadowGeneratorForRoomLight); } if (this.engine.graphicsQuality >= GRAPHICS_QUALITY.MEDIUM) { @@ -65,10 +62,7 @@ export class JapaneseEnvManager extends EnvManager { shadowGeneratorForSunLight.bias = 0.00001; shadowGeneratorForSunLight.usePercentageCloserFiltering = true; shadowGeneratorForSunLight.usePoissonSampling = true; - if (this.engine.graphicsQuality <= GRAPHICS_QUALITY.MEDIUM) { - shadowGeneratorForSunLight.getShadowMap().refreshRate = 60; - } - this.shadowGenerators.push(shadowGeneratorForSunLight); + this.registerShadowGenerator(shadowGeneratorForSunLight); } this.loaderResult = await BABYLON.ImportMeshAsync('/client-assets/room/envs/japanese/japanese.glb', this.engine.scene); diff --git a/packages/frontend-misskey-world-engine/src/room/envs/museum.ts b/packages/frontend-misskey-world-engine/src/room/envs/museum.ts index 0659952b45..602fd148e0 100644 --- a/packages/frontend-misskey-world-engine/src/room/envs/museum.ts +++ b/packages/frontend-misskey-world-engine/src/room/envs/museum.ts @@ -67,11 +67,8 @@ export class MuseumEnvManager extends EnvManager { shadowGeneratorForRoomLight.normalBias = 0.005; shadowGeneratorForRoomLight.usePercentageCloserFiltering = true; shadowGeneratorForRoomLight.filteringQuality = BABYLON.ShadowGenerator.QUALITY_HIGH; - if (this.engine.graphicsQuality <= GRAPHICS_QUALITY.MEDIUM) { - shadowGeneratorForRoomLight.getShadowMap().refreshRate = 60; - } //this.shadowGeneratorForRoomLight.useContactHardeningShadow = true; - this.shadowGenerators.push(shadowGeneratorForRoomLight); + this.registerShadowGenerator(shadowGeneratorForRoomLight); } for (const node of this.meshes.filter(mesh => mesh.name.includes('__LIGHT__'))) { diff --git a/packages/frontend-misskey-world-engine/src/room/envs/simple.ts b/packages/frontend-misskey-world-engine/src/room/envs/simple.ts index 846fce3f33..a5a00f8008 100644 --- a/packages/frontend-misskey-world-engine/src/room/envs/simple.ts +++ b/packages/frontend-misskey-world-engine/src/room/envs/simple.ts @@ -157,12 +157,9 @@ export class SimpleEnvManager extends EnvManager { shadowGeneratorForRoomLight.bias = 0.0005; shadowGeneratorForRoomLight.usePercentageCloserFiltering = true; shadowGeneratorForRoomLight.filteringQuality = BABYLON.ShadowGenerator.QUALITY_HIGH; - if (this.engine.graphicsQuality <= GRAPHICS_QUALITY.MEDIUM) { - shadowGeneratorForRoomLight.getShadowMap().refreshRate = 60; // 効いてなさそう babylonのバグ? - } //shadowGeneratorForRoomLight.useContactHardeningShadow = true; //shadowGeneratorForRoomLight.contactHardeningLightSizeUVRatio = 0.01; - this.shadowGenerators.push(shadowGeneratorForRoomLight); + this.registerShadowGenerator(shadowGeneratorForRoomLight); } if (this.engine.graphicsQuality >= GRAPHICS_QUALITY.MEDIUM) { @@ -176,10 +173,7 @@ export class SimpleEnvManager extends EnvManager { shadowGeneratorForSunLight.bias = 0.00001; shadowGeneratorForSunLight.usePercentageCloserFiltering = true; shadowGeneratorForSunLight.usePoissonSampling = true; - if (this.engine.graphicsQuality <= GRAPHICS_QUALITY.MEDIUM) { - shadowGeneratorForSunLight.getShadowMap().refreshRate = 60; // 効いてなさそう babylonのバグ? - } - this.shadowGenerators.push(shadowGeneratorForSunLight); + this.registerShadowGenerator(shadowGeneratorForSunLight); } this.envMapIndoor = BABYLON.CubeTexture.CreateFromPrefilteredData('/client-assets/room/indoor.env', this.engine.scene); diff --git a/packages/misskey-world/src/room/furnitures/ceilingFan.schema.ts b/packages/misskey-world/src/room/furnitures/ceilingFan.schema.ts index 51c9992f76..f663165507 100644 --- a/packages/misskey-world/src/room/furnitures/ceilingFan.schema.ts +++ b/packages/misskey-world/src/room/furnitures/ceilingFan.schema.ts @@ -22,4 +22,5 @@ export const ceilingFan_schema = defineFurnitureSchema({ }, placement: 'ceiling', hasCollisions: false, + castShadows: false, });