Add optional WebGPU engine support via ?webGPU=true query parameter
Allows launching the game with WebGPU rendering by passing ?webGPU=true in the URL. Defaults to WebGL engine when the parameter is absent. Logs a warning that WebXR/VR is not yet supported with WebGPU. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
208d735ef4
commit
53388c8193
@ -1,11 +1,11 @@
|
||||
import { Engine } from "@babylonjs/core";
|
||||
import { AbstractEngine } from "@babylonjs/core";
|
||||
import { DefaultScene } from "./defaultScene";
|
||||
import { RockFactory } from "../environment/asteroids/rockFactory";
|
||||
import log from './logger';
|
||||
import Level from "../levels/level";
|
||||
|
||||
export interface CleanupContext {
|
||||
getEngine(): Engine;
|
||||
getEngine(): AbstractEngine;
|
||||
getCurrentLevel(): Level | null;
|
||||
setCurrentLevel(level: Level | null): void;
|
||||
resetState(): void;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { AudioEngineV2, Engine, ParticleHelper } from "@babylonjs/core";
|
||||
import { AbstractEngine, AudioEngineV2, ParticleHelper } from "@babylonjs/core";
|
||||
import { DefaultScene } from "../defaultScene";
|
||||
import { Level1 } from "../../levels/level1";
|
||||
import Level from "../../levels/level";
|
||||
@ -20,7 +20,7 @@ export interface LevelSelectedContext {
|
||||
initializeEngine(): Promise<void>;
|
||||
initializeXR(): Promise<void>;
|
||||
getAudioEngine(): AudioEngineV2;
|
||||
getEngine(): Engine;
|
||||
getEngine(): AbstractEngine;
|
||||
setCurrentLevel(level: Level): void;
|
||||
setProgressCallback(callback: (percent: number, message: string) => void): void;
|
||||
play(): Promise<void>;
|
||||
@ -169,7 +169,7 @@ function attachAudioListener(audioEngine: AudioEngineV2): void {
|
||||
|
||||
async function finalizeLevelStart(
|
||||
level: Level1,
|
||||
engine: Engine,
|
||||
engine: AbstractEngine,
|
||||
preloader: Preloader,
|
||||
context: LevelSelectedContext
|
||||
): Promise<void> {
|
||||
@ -188,7 +188,7 @@ async function finalizeLevelStart(
|
||||
await context.play();
|
||||
}
|
||||
|
||||
function showCanvasForFlatMode(engine: Engine): void {
|
||||
function showCanvasForFlatMode(engine: AbstractEngine): void {
|
||||
const canvas = document.getElementById('gameCanvas');
|
||||
if (canvas) canvas.style.display = 'block';
|
||||
engine.stopRenderLoop();
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Engine, FreeCamera, Vector3 } from "@babylonjs/core";
|
||||
import { AbstractEngine, FreeCamera, Vector3 } from "@babylonjs/core";
|
||||
import { DefaultScene } from "../defaultScene";
|
||||
import { LevelConfig } from "../../levels/config/levelConfig";
|
||||
import log from '../logger';
|
||||
@ -9,7 +9,7 @@ import log from '../logger';
|
||||
*/
|
||||
export async function enterXRMode(
|
||||
config: LevelConfig,
|
||||
engine: Engine
|
||||
engine: AbstractEngine
|
||||
): Promise<any> {
|
||||
if (!DefaultScene.XR) {
|
||||
return startFlatMode(engine);
|
||||
@ -39,7 +39,7 @@ function prePositionCamera(config: LevelConfig): void {
|
||||
log.debug('[XR] Camera pre-positioned at cockpit:', cockpitPosition.toString());
|
||||
}
|
||||
|
||||
function startFlatMode(engine: Engine): null {
|
||||
function startFlatMode(engine: AbstractEngine): null {
|
||||
const canvas = document.getElementById('gameCanvas');
|
||||
if (canvas) canvas.style.display = 'block';
|
||||
engine.stopRenderLoop();
|
||||
|
||||
3
src/core/queryParams.ts
Normal file
3
src/core/queryParams.ts
Normal file
@ -0,0 +1,3 @@
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
|
||||
export const useWebGPU = urlParams.get('webGPU') === 'true';
|
||||
@ -1,18 +1,22 @@
|
||||
import {
|
||||
AbstractEngine,
|
||||
AudioEngineV2,
|
||||
Color3,
|
||||
CreateAudioEngineAsync,
|
||||
Engine,
|
||||
HavokPlugin,
|
||||
Scene,
|
||||
Vector3
|
||||
Vector3,
|
||||
WebGPUEngine,
|
||||
} from "@babylonjs/core";
|
||||
import HavokPhysics from "@babylonjs/havok";
|
||||
import { DefaultScene } from "./defaultScene";
|
||||
import { ProgressReporter } from "./xrSetup";
|
||||
import { useWebGPU } from "./queryParams";
|
||||
import log from './logger';
|
||||
|
||||
export interface SceneSetupResult {
|
||||
engine: Engine;
|
||||
engine: AbstractEngine;
|
||||
audioEngine: AudioEngineV2;
|
||||
}
|
||||
|
||||
@ -24,7 +28,7 @@ export async function setupScene(
|
||||
reporter: ProgressReporter
|
||||
): Promise<SceneSetupResult> {
|
||||
reporter.reportProgress(5, 'Creating rendering engine...');
|
||||
const engine = createEngine(canvas);
|
||||
const engine = await createEngine(canvas);
|
||||
|
||||
reporter.reportProgress(10, 'Creating scene...');
|
||||
createMainScene(engine);
|
||||
@ -44,14 +48,22 @@ export async function setupScene(
|
||||
return { engine, audioEngine };
|
||||
}
|
||||
|
||||
function createEngine(canvas: HTMLCanvasElement): Engine {
|
||||
const engine = new Engine(canvas, true);
|
||||
async function createEngine(canvas: HTMLCanvasElement): Promise<AbstractEngine> {
|
||||
let engine: AbstractEngine;
|
||||
if (useWebGPU) {
|
||||
log.info('[Engine] Creating WebGPU engine');
|
||||
log.warn('[Engine] WebXR/VR is still experimental');
|
||||
engine = await WebGPUEngine.CreateAsync(canvas, { antialias: true });
|
||||
} else {
|
||||
log.info('[Engine] Creating WebGL engine');
|
||||
engine = new Engine(canvas, true);
|
||||
}
|
||||
engine.setHardwareScalingLevel(1 / window.devicePixelRatio);
|
||||
window.onresize = () => engine.resize();
|
||||
return engine;
|
||||
}
|
||||
|
||||
function createMainScene(engine: Engine): void {
|
||||
function createMainScene(engine: AbstractEngine): void {
|
||||
// Dispose old scene if it exists (prevents doubling on reload)
|
||||
if (DefaultScene.MainScene && !DefaultScene.MainScene.isDisposed) {
|
||||
DefaultScene.MainScene.dispose();
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { AudioEngineV2, Engine } from "@babylonjs/core";
|
||||
import { AbstractEngine, AudioEngineV2 } from "@babylonjs/core";
|
||||
import '@babylonjs/loaders';
|
||||
|
||||
import { DefaultScene } from "./core/defaultScene";
|
||||
@ -20,7 +20,7 @@ const canvas = document.querySelector('#gameCanvas') as HTMLCanvasElement;
|
||||
|
||||
export class Main implements LevelSelectedContext, CleanupContext {
|
||||
private _currentLevel: Level | null = null;
|
||||
private _engine: Engine;
|
||||
private _engine: AbstractEngine;
|
||||
private _audioEngine: AudioEngineV2;
|
||||
private _initialized: boolean = false;
|
||||
private _assetsLoaded: boolean = false;
|
||||
@ -43,7 +43,7 @@ export class Main implements LevelSelectedContext, CleanupContext {
|
||||
areAssetsLoaded(): boolean { return this._assetsLoaded; }
|
||||
setAssetsLoaded(value: boolean): void { this._assetsLoaded = value; }
|
||||
getAudioEngine(): AudioEngineV2 { return this._audioEngine; }
|
||||
getEngine(): Engine { return this._engine; }
|
||||
getEngine(): AbstractEngine { return this._engine; }
|
||||
setCurrentLevel(level: Level): void { this._currentLevel = level; }
|
||||
setProgressCallback(cb: (percent: number, message: string) => void): void {
|
||||
this._progressCallback = cb;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user