diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 7a6b374181..d8df27f7f0 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -3567,8 +3567,10 @@ _miWorld: separateRenderingThread_description: "有効にするとパフォーマンスが向上します。不安定になる場合は無効すると改善する可能性があります。" graphicsQuality: "グラフィックの品質" graphicsSettings: "グラフィック設定" - frameRate: "フレームレート" + frameRateLimitation: "フレームレート制限" + higherValuePerformanceNote: "高くすると体験が向上しますが、消費電力が増加するなどパフォーマンスに影響を与えます。" resolution: "解像度" + fov: "視野角" failedToInitialize: "初期化に失敗しました" crushed_description: "描画が継続できなくなりました。デバイスのリソース不足の可能性が考えられます。" antialiasing: "アンチエイリアス" diff --git a/packages/frontend-misskey-world-engine/src/room/engine.ts b/packages/frontend-misskey-world-engine/src/room/engine.ts index 99bc6f11ac..e1e946c41e 100644 --- a/packages/frontend-misskey-world-engine/src/room/engine.ts +++ b/packages/frontend-misskey-world-engine/src/room/engine.ts @@ -81,6 +81,7 @@ export class RoomEngine extends EngineBase<{ private useGlow: boolean; public camera: BABYLON.UniversalCamera; private cameraHeight = cm(130); + private fov: number; private fixedCamera: BABYLON.FreeCamera; public furnitureContainers: Map = new Map(); private envManager: EnvManager | null = null; @@ -191,6 +192,7 @@ export class RoomEngine extends EngineBase<{ graphicsQuality: number; fps: number | null; antialias: boolean; + fov: number; useVirtualJoystick?: boolean; }) { super({ @@ -208,6 +210,7 @@ export class RoomEngine extends EngineBase<{ this.roomAttachments = roomAttachments; this.graphicsQuality = options.graphicsQuality; this.useGlow = this.graphicsQuality >= GRAPHICS_QUALITY.MEDIUM; + this.fov = options.fov; this.time = TIME_MAP[new Date().getHours() as keyof typeof TIME_MAP]; registerBuiltInLoaders(); @@ -227,7 +230,7 @@ export class RoomEngine extends EngineBase<{ this.camera = new BABYLON.FreeCamera('camera', new BABYLON.Vector3(0, this.cameraHeight, cm(0)), this.scene); this.camera.minZ = cm(1); this.camera.maxZ = cm(1000); - this.camera.fov = 1; + this.camera.fov = this.fov; this.camera.ellipsoid = new BABYLON.Vector3(cm(15), cm(65), cm(15)); this.camera.checkCollisions = true; this.camera.applyGravity = true; @@ -434,10 +437,10 @@ export class RoomEngine extends EngineBase<{ } else { if (this.scene.activeCamera === this.camera) { this.camera.fov += ev.deltaY * 0.001; - this.camera.fov = Math.max(0.25, Math.min(1, this.camera.fov)); + this.camera.fov = Math.max(0.25, Math.min(this.fov, this.camera.fov)); } else if (this.scene.activeCamera === this.fixedCamera) { this.fixedCamera.fov += ev.deltaY * 0.001; - this.fixedCamera.fov = Math.max(0.25, Math.min(1, this.fixedCamera.fov)); + this.fixedCamera.fov = Math.max(0.25, Math.min(this.fov, this.fixedCamera.fov)); } } }); @@ -447,7 +450,7 @@ export class RoomEngine extends EngineBase<{ this.changeGrabbingDistance(ev.delta * 0.1); } else { this.camera.fov += -ev.delta * 0.003; - this.camera.fov = Math.max(0.25, Math.min(1, this.camera.fov)); + this.camera.fov = Math.max(0.25, Math.min(this.fov, this.camera.fov)); } }); diff --git a/packages/frontend-misskey-world-engine/src/room/nonWorker.ts b/packages/frontend-misskey-world-engine/src/room/nonWorker.ts index 47a8935fd2..bd8793b5c3 100644 --- a/packages/frontend-misskey-world-engine/src/room/nonWorker.ts +++ b/packages/frontend-misskey-world-engine/src/room/nonWorker.ts @@ -12,7 +12,7 @@ import type { RoomState, RoomAttachments } from 'misskey-world/src/room/type.js' //BABYLON.RegisterCollisionCoordinator(); export async function createRoomEngine(params: { - roomState: RoomState; roomAttachments: RoomAttachments; canvas: HTMLCanvasElement; options: { antialias: boolean; resolution: number }; + roomState: RoomState; roomAttachments: RoomAttachments; canvas: HTMLCanvasElement; options: { antialias: boolean; resolution: number; fov: number; graphicsQuality: number; fps: number | null; useVirtualJoystick?: boolean; }; }) { const babylonEngine = new BABYLON.WebGPUEngine(params.canvas, { doNotHandleContextLost: true, powerPreference: 'high-performance', antialias: params.options.antialias }); babylonEngine.compatibilityMode = false; diff --git a/packages/frontend/src/components/MkWorldAvatarEditDialog.vue b/packages/frontend/src/components/MkWorldAvatarEditDialog.vue index b8eeca315a..f12ed02a07 100644 --- a/packages/frontend/src/components/MkWorldAvatarEditDialog.vue +++ b/packages/frontend/src/components/MkWorldAvatarEditDialog.vue @@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only @close="cancel()" @closed="emit('closed')" > - +
diff --git a/packages/frontend/src/pages/rooms/room.core.vue b/packages/frontend/src/pages/rooms/room.core.vue index 93939ef089..f74dbdb92d 100644 --- a/packages/frontend/src/pages/rooms/room.core.vue +++ b/packages/frontend/src/pages/rooms/room.core.vue @@ -290,6 +290,7 @@ const roomControllerOptions = computed(() => ({ resolution: resolution.value, antialias: antialias.value, useVirtualJoystick, + fov: prefer.s['world.fov'], workerMode: prefer.s['world.separateRenderingThread'], })); @@ -649,7 +650,7 @@ ${url}/rooms/r/${props.room.id}`, ref: graphicsQualityRaw, }, { type: 'radio', - text: i18n.ts._miWorld.frameRate, + text: i18n.ts._miWorld.frameRateLimitation, caption: fpsRaw.value == null ? i18n.ts.auto : fpsRaw.value === 'max' ? 'Max' : `~${fpsRaw.value}fps`, options: [{ label: `${i18n.ts.auto} (${fpsAutoValue.value}fps)`, diff --git a/packages/frontend/src/pages/settings/preferences.vue b/packages/frontend/src/pages/settings/preferences.vue index a3f3fd078b..0e71557d0e 100644 --- a/packages/frontend/src/pages/settings/preferences.vue +++ b/packages/frontend/src/pages/settings/preferences.vue @@ -764,6 +764,19 @@ SPDX-License-Identifier: AGPL-3.0-only
+ + + + + + + + + - + - + + @@ -812,6 +827,7 @@ SPDX-License-Identifier: AGPL-3.0-only ]" > + @@ -1043,6 +1059,7 @@ const worldGraphicsQuality = prefer.model('world.graphicsQuality'); const worldFps = prefer.model('world.fps'); const worldResolution = prefer.model('world.resolution'); const worldAntialias = prefer.model('world.antialias'); +const worldFov = prefer.model('world.fov'); const fontSize = ref(miLocalStorage.getItem('fontSize') as '1' | '2' | '3' | null); const useSystemFont = ref(miLocalStorage.getItem('useSystemFont') != null); @@ -1107,6 +1124,7 @@ watch([ worldFps, worldResolution, worldAntialias, + worldFov, ], () => { suggestReload(); }); diff --git a/packages/frontend/src/preferences/def.ts b/packages/frontend/src/preferences/def.ts index daefded184..e175b94d77 100644 --- a/packages/frontend/src/preferences/def.ts +++ b/packages/frontend/src/preferences/def.ts @@ -545,6 +545,9 @@ export const PREF_DEF = definePreferences({ 'world.antialias': { default: true, }, + 'world.fov': { + default: 1, + }, 'world.separateRenderingThread': { default: true, }, diff --git a/packages/frontend/src/world/room/controller.ts b/packages/frontend/src/world/room/controller.ts index 0dfb2926ec..8c15869656 100644 --- a/packages/frontend/src/world/room/controller.ts +++ b/packages/frontend/src/world/room/controller.ts @@ -21,6 +21,7 @@ export type RoomControllerOptions = { fps: number | null; resolution: number; antialias: boolean; + fov: number; useVirtualJoystick?: boolean; }; diff --git a/packages/i18n/src/autogen/locale.ts b/packages/i18n/src/autogen/locale.ts index 79a19a83cf..c2d77d4b48 100644 --- a/packages/i18n/src/autogen/locale.ts +++ b/packages/i18n/src/autogen/locale.ts @@ -13308,13 +13308,21 @@ export interface Locale extends ILocale { */ "graphicsSettings": string; /** - * フレームレート + * フレームレート制限 */ - "frameRate": string; + "frameRateLimitation": string; + /** + * 高くすると体験が向上しますが、消費電力が増加するなどパフォーマンスに影響を与えます。 + */ + "higherValuePerformanceNote": string; /** * 解像度 */ "resolution": string; + /** + * 視野角 + */ + "fov": string; /** * 初期化に失敗しました */