Updated the webgpu stuff to have webgl as fallback
This commit is contained in:
1 parent
4e24cb5df1
commit
a349f630c6
17 files changed
+1350
-416
No files matched your search
@@ -1,7 +1,8 @@
|
||||
import {AfterViewInit, Component, ElementRef, EventEmitter, inject, Input, NgZone, OnDestroy, Output, ViewChild} from '@angular/core';
|
||||
import {MatSnackBar} from '@angular/material/snack-bar';
|
||||
import {TranslateService} from '@ngx-translate/core';
|
||||
import {ArcRotateCamera, Camera, MeshBuilder, Scene, ShaderLanguage, ShaderMaterial, Vector2, Vector3, WebGPUEngine} from '@babylonjs/core';
|
||||
import {ArcRotateCamera, Camera, Engine, MeshBuilder, Scene, ShaderLanguage, ShaderMaterial, Vector2, Vector3, WebGPUEngine} from '@babylonjs/core';
|
||||
import {GpuCapabilityService, GpuTier} from '../../../service/gpu-capability.service';
|
||||
|
||||
export interface RenderConfig {
|
||||
mode: '2D' | '3D';
|
||||
@@ -17,7 +18,8 @@ export type RenderCallback = (material: ShaderMaterial, camera: Camera, canvas:
|
||||
|
||||
export interface SceneEventData {
|
||||
scene: Scene;
|
||||
engine: WebGPUEngine;
|
||||
engine: WebGPUEngine | Engine;
|
||||
gpuTier: GpuTier;
|
||||
}
|
||||
|
||||
@Component({
|
||||
@@ -30,6 +32,7 @@ export class BabylonCanvas implements AfterViewInit, OnDestroy {
|
||||
readonly ngZone = inject(NgZone);
|
||||
private readonly snackBar = inject(MatSnackBar);
|
||||
private readonly translate = inject(TranslateService);
|
||||
private readonly gpuCapability = inject(GpuCapabilityService);
|
||||
|
||||
@ViewChild('renderCanvas', { static: true }) canvasRef!: ElementRef<HTMLCanvasElement>;
|
||||
|
||||
@@ -38,11 +41,13 @@ export class BabylonCanvas implements AfterViewInit, OnDestroy {
|
||||
|
||||
@Output() sceneReady = new EventEmitter<SceneEventData>();
|
||||
@Output() sceneResized = new EventEmitter<SceneEventData>();
|
||||
@Output() engineUnavailable = new EventEmitter<{ reason: string }>();
|
||||
|
||||
private engine!: WebGPUEngine;
|
||||
private engine!: WebGPUEngine | Engine;
|
||||
private scene!: Scene;
|
||||
private shaderMaterial!: ShaderMaterial;
|
||||
private camera!: Camera;
|
||||
private gpuTier: GpuTier = 'none';
|
||||
|
||||
//Listener
|
||||
private readonly resizeHandler = () => this.handleResize();
|
||||
@@ -63,26 +68,60 @@ export class BabylonCanvas implements AfterViewInit, OnDestroy {
|
||||
|
||||
private async initBabylon(): Promise<void> {
|
||||
const canvas = this.canvasRef.nativeElement;
|
||||
const tmpEngine = new WebGPUEngine(canvas);
|
||||
await tmpEngine.initAsync().then(() => {
|
||||
this.engine = tmpEngine;
|
||||
this.scene = new Scene(this.engine);
|
||||
this.setupCamera(canvas);
|
||||
this.addListener(canvas);
|
||||
this.createShaderMaterial();
|
||||
this.createFullScreenRect();
|
||||
this.sceneReady.emit({
|
||||
scene: this.scene,
|
||||
engine: this.engine
|
||||
});
|
||||
this.addRenderLoop(canvas);
|
||||
const tier = await this.gpuCapability.detect();
|
||||
this.gpuTier = tier;
|
||||
|
||||
})
|
||||
.catch(() => {
|
||||
const message = this.translate.instant('WEBGPU.NOT_SUPPORTED');
|
||||
this.snackBar.open(message, 'OK', { duration: 8000, horizontalPosition: "center", verticalPosition: "top" });
|
||||
this.engine = null!;
|
||||
});
|
||||
if (tier === 'webgpu') {
|
||||
await this.initWebGpuEngine(canvas);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tier === 'webgl') {
|
||||
this.showSnackBar('GPU.WEBGL_FALLBACK');
|
||||
this.initWebGlEngine(canvas);
|
||||
return;
|
||||
}
|
||||
|
||||
this.showSnackBar('GPU.NOT_SUPPORTED');
|
||||
this.engineUnavailable.emit({reason: 'no_gpu'});
|
||||
}
|
||||
|
||||
private async initWebGpuEngine(canvas: HTMLCanvasElement): Promise<void> {
|
||||
const tmpEngine = new WebGPUEngine(canvas);
|
||||
|
||||
try {
|
||||
await tmpEngine.initAsync();
|
||||
this.engine = tmpEngine;
|
||||
this.setupScene(canvas);
|
||||
} catch {
|
||||
this.showSnackBar('GPU.WEBGL_FALLBACK');
|
||||
this.gpuTier = 'webgl';
|
||||
this.initWebGlEngine(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
private initWebGlEngine(canvas: HTMLCanvasElement): void {
|
||||
this.engine = new Engine(canvas, true);
|
||||
this.setupScene(canvas);
|
||||
}
|
||||
|
||||
private setupScene(canvas: HTMLCanvasElement): void {
|
||||
this.scene = new Scene(this.engine);
|
||||
this.setupCamera(canvas);
|
||||
this.addListener(canvas);
|
||||
this.createShaderMaterial();
|
||||
this.createFullScreenRect();
|
||||
this.sceneReady.emit({
|
||||
scene: this.scene,
|
||||
engine: this.engine,
|
||||
gpuTier: this.gpuTier
|
||||
});
|
||||
this.addRenderLoop(canvas);
|
||||
}
|
||||
|
||||
private showSnackBar(translationKey: string): void {
|
||||
const message = this.translate.instant(translationKey);
|
||||
this.snackBar.open(message, 'OK', {duration: 8000, horizontalPosition: 'center', verticalPosition: 'top'});
|
||||
}
|
||||
|
||||
private addListener(canvas: HTMLCanvasElement) {
|
||||
@@ -198,7 +237,8 @@ export class BabylonCanvas implements AfterViewInit, OnDestroy {
|
||||
|
||||
this.sceneResized?.emit({
|
||||
scene: this.scene,
|
||||
engine: this.engine
|
||||
engine: this.engine,
|
||||
gpuTier: this.gpuTier
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user