Add WebGPU XR rendering pipeline via XRGPUBinding
All checks were successful
Build / build (push) Successful in 1m42s
All checks were successful
Build / build (push) Successful in 1m42s
Create a parallel WebGPU XR path that uses XRGPUBinding and XRProjectionLayer instead of the WebGL-only XRWebGLLayer, while preserving the existing WebGL XR path as the default fallback. New files in src/core/xr-webgpu/: - xrGpuTypes.ts: TypeScript declarations for XRGPUBinding spec types - xrGpuSessionSetup.ts: GPUDevice access and session init helpers - xrGpuTextureProvider.ts: Per-frame GPUTexture swap via hwTex.set() - xrGpuLayerWrapper.ts: WebXRLayerWrapper subclass for projection layers - xrGpuRenderTarget.ts: WebXRRenderTarget using XRGPUBinding - xrGpuEntryPoint.ts: Public API for availability check and creation Modified xrEntryHandler.ts to conditionally route through WebGPU or WebGL XR entry based on XRGPUBinding availability. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
25286c56b0
commit
0bb27691fe
@ -1,6 +1,7 @@
|
|||||||
import { AbstractEngine, FreeCamera, Vector3 } from "@babylonjs/core";
|
import { AbstractEngine, FreeCamera, Vector3, WebGPUEngine } from "@babylonjs/core";
|
||||||
import { DefaultScene } from "../defaultScene";
|
import { DefaultScene } from "../defaultScene";
|
||||||
import { LevelConfig } from "../../levels/config/levelConfig";
|
import { LevelConfig } from "../../levels/config/levelConfig";
|
||||||
|
import { isWebGPUXRAvailable, createWebGPURenderTarget, getWebGPUSessionInit } from "../xr-webgpu/xrGpuEntryPoint";
|
||||||
import log from '../logger';
|
import log from '../logger';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -17,10 +18,9 @@ export async function enterXRMode(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
prePositionCamera(config);
|
prePositionCamera(config);
|
||||||
const session = await DefaultScene.XR.baseExperience.enterXRAsync(
|
const session = isWebGPUXRAvailable(engine)
|
||||||
'immersive-vr',
|
? await enterWebGPUXR(engine as WebGPUEngine)
|
||||||
'local-floor'
|
: await enterWebGLXR();
|
||||||
);
|
|
||||||
log.debug('XR session started successfully');
|
log.debug('XR session started successfully');
|
||||||
return session;
|
return session;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -30,6 +30,16 @@ export async function enterXRMode(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function enterWebGPUXR(engine: WebGPUEngine): Promise<any> {
|
||||||
|
const base = DefaultScene.XR!.baseExperience;
|
||||||
|
const gpuTarget = createWebGPURenderTarget(base.sessionManager, engine, DefaultScene.MainScene);
|
||||||
|
return base.enterXRAsync('immersive-vr', 'local-floor', gpuTarget, getWebGPUSessionInit());
|
||||||
|
}
|
||||||
|
|
||||||
|
async function enterWebGLXR(): Promise<any> {
|
||||||
|
return DefaultScene.XR!.baseExperience.enterXRAsync('immersive-vr', 'local-floor');
|
||||||
|
}
|
||||||
|
|
||||||
function prePositionCamera(config: LevelConfig): void {
|
function prePositionCamera(config: LevelConfig): void {
|
||||||
const spawnPos = config.ship?.position || [0, 0, 0];
|
const spawnPos = config.ship?.position || [0, 0, 0];
|
||||||
const cockpitPosition = new Vector3(spawnPos[0], spawnPos[1] + 1.2, spawnPos[2]);
|
const cockpitPosition = new Vector3(spawnPos[0], spawnPos[1] + 1.2, spawnPos[2]);
|
||||||
|
|||||||
@ -49,18 +49,40 @@ export async function setupScene(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function createEngine(canvas: HTMLCanvasElement): Promise<AbstractEngine> {
|
async function createEngine(canvas: HTMLCanvasElement): Promise<AbstractEngine> {
|
||||||
let engine: AbstractEngine;
|
const engine = useWebGPU
|
||||||
if (useWebGPU) {
|
? await tryCreateWebGPUEngine(canvas)
|
||||||
log.info('[Engine] Creating WebGPU engine');
|
: null;
|
||||||
log.warn('[Engine] WebXR/VR is still experimental with WebGPU engine');
|
const finalEngine = engine ?? createWebGLEngine(canvas);
|
||||||
engine = await WebGPUEngine.CreateAsync(canvas, { antialias: true });
|
finalEngine.setHardwareScalingLevel(1 / window.devicePixelRatio);
|
||||||
} else {
|
window.onresize = () => finalEngine.resize();
|
||||||
log.info('[Engine] Creating WebGL engine');
|
return finalEngine;
|
||||||
engine = new Engine(canvas, true);
|
}
|
||||||
|
|
||||||
|
async function tryCreateWebGPUEngine(canvas: HTMLCanvasElement): Promise<AbstractEngine | null> {
|
||||||
|
if (!navigator.gpu) {
|
||||||
|
log.warn('[Engine] WebGPU requested but navigator.gpu not available');
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
engine.setHardwareScalingLevel(1 / window.devicePixelRatio);
|
const adapter = await navigator.gpu.requestAdapter();
|
||||||
window.onresize = () => engine.resize();
|
if (!adapter) {
|
||||||
return engine;
|
log.warn('[Engine] No WebGPU adapter found');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
log.info(`[Engine] WebGPU adapter: ${adapter.info?.vendor ?? 'unknown'}`);
|
||||||
|
try {
|
||||||
|
const gpuEngine = new WebGPUEngine(canvas, { antialias: true });
|
||||||
|
await gpuEngine.initAsync();
|
||||||
|
log.info('[Engine] WebGPU engine ready — WebXR will use XRGPUBinding if available');
|
||||||
|
return gpuEngine;
|
||||||
|
} catch (e) {
|
||||||
|
log.error('[Engine] WebGPU initialization failed', e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createWebGLEngine(canvas: HTMLCanvasElement): AbstractEngine {
|
||||||
|
log.info('[Engine] Creating WebGL engine');
|
||||||
|
return new Engine(canvas, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createMainScene(engine: AbstractEngine): void {
|
function createMainScene(engine: AbstractEngine): void {
|
||||||
|
|||||||
28
src/core/xr-webgpu/xrGpuEntryPoint.ts
Normal file
28
src/core/xr-webgpu/xrGpuEntryPoint.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Public API for WebGPU XR support.
|
||||||
|
* Consumed by xrEntryHandler.ts to conditionally use the WebGPU XR path.
|
||||||
|
*/
|
||||||
|
import { WebGPUEngine } from "@babylonjs/core";
|
||||||
|
import type { AbstractEngine, Scene, WebXRSessionManager } from "@babylonjs/core";
|
||||||
|
import { XRGPURenderTarget } from "./xrGpuRenderTarget";
|
||||||
|
import { buildWebGPUSessionInit } from "./xrGpuSessionSetup";
|
||||||
|
import "./xrGpuTypes"; // ensure global XRGPUBinding augmentation is loaded
|
||||||
|
|
||||||
|
export function isWebGPUXRAvailable(engine: AbstractEngine): boolean {
|
||||||
|
return (
|
||||||
|
engine instanceof WebGPUEngine &&
|
||||||
|
typeof globalThis.XRGPUBinding !== 'undefined'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createWebGPURenderTarget(
|
||||||
|
sessionManager: WebXRSessionManager,
|
||||||
|
engine: WebGPUEngine,
|
||||||
|
scene: Scene
|
||||||
|
): XRGPURenderTarget {
|
||||||
|
return new XRGPURenderTarget(sessionManager, engine, scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getWebGPUSessionInit(): XRSessionInit {
|
||||||
|
return buildWebGPUSessionInit();
|
||||||
|
}
|
||||||
32
src/core/xr-webgpu/xrGpuLayerWrapper.ts
Normal file
32
src/core/xr-webgpu/xrGpuLayerWrapper.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* WebXRLayerWrapper subclass for XRProjectionLayer created via XRGPUBinding.
|
||||||
|
*/
|
||||||
|
import { WebGPUEngine } from "@babylonjs/core";
|
||||||
|
import { WebXRLayerWrapper } from "@babylonjs/core/XR/webXRLayerWrapper";
|
||||||
|
import type { Scene } from "@babylonjs/core";
|
||||||
|
import { XRGPUTextureProvider } from "./xrGpuTextureProvider";
|
||||||
|
import type { XRGPUBinding } from "./xrGpuTypes";
|
||||||
|
|
||||||
|
export class XRGPUProjectionLayerWrapper extends WebXRLayerWrapper {
|
||||||
|
constructor(
|
||||||
|
public override readonly layer: XRProjectionLayer,
|
||||||
|
private readonly _gpuBinding: XRGPUBinding,
|
||||||
|
private readonly _gpuEngine: WebGPUEngine,
|
||||||
|
private readonly _scene: Scene
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
() => layer.textureWidth,
|
||||||
|
() => layer.textureHeight,
|
||||||
|
layer,
|
||||||
|
"XRProjectionLayer",
|
||||||
|
(sessionManager) =>
|
||||||
|
new XRGPUTextureProvider(
|
||||||
|
sessionManager.scene,
|
||||||
|
this,
|
||||||
|
_gpuBinding,
|
||||||
|
layer,
|
||||||
|
_gpuEngine
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
54
src/core/xr-webgpu/xrGpuRenderTarget.ts
Normal file
54
src/core/xr-webgpu/xrGpuRenderTarget.ts
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* WebXRRenderTarget implementation for WebGPU.
|
||||||
|
* Creates XRGPUBinding + projection layer instead of XRWebGLLayer.
|
||||||
|
*/
|
||||||
|
import { WebGPUEngine } from "@babylonjs/core";
|
||||||
|
import type { Scene, Nullable, WebXRSessionManager, WebXRRenderTarget } from "@babylonjs/core";
|
||||||
|
import { XRGPUProjectionLayerWrapper } from "./xrGpuLayerWrapper";
|
||||||
|
import { getGpuDeviceFromEngine } from "./xrGpuSessionSetup";
|
||||||
|
import type { XRGPUBinding, XRGPUBindingConstructor } from "./xrGpuTypes";
|
||||||
|
import log from '../logger';
|
||||||
|
|
||||||
|
export class XRGPURenderTarget implements WebXRRenderTarget {
|
||||||
|
/** Unused in WebGPU path — required by interface */
|
||||||
|
public canvasContext: WebGLRenderingContext = null as any;
|
||||||
|
/** Unused in WebGPU path — required by interface */
|
||||||
|
public xrLayer: Nullable<XRWebGLLayer> = null;
|
||||||
|
|
||||||
|
private _sessionManager: WebXRSessionManager;
|
||||||
|
private _engine: WebGPUEngine;
|
||||||
|
private _scene: Scene;
|
||||||
|
|
||||||
|
constructor(sessionManager: WebXRSessionManager, engine: WebGPUEngine, scene: Scene) {
|
||||||
|
this._sessionManager = sessionManager;
|
||||||
|
this._engine = engine;
|
||||||
|
this._scene = scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async initializeXRLayerAsync(xrSession: XRSession): Promise<XRWebGLLayer> {
|
||||||
|
const device = getGpuDeviceFromEngine(this._engine);
|
||||||
|
const Binding = globalThis.XRGPUBinding as XRGPUBindingConstructor;
|
||||||
|
const gpuBinding: XRGPUBinding = new Binding(xrSession, device);
|
||||||
|
|
||||||
|
const projectionLayer = gpuBinding.createProjectionLayer({
|
||||||
|
textureFormat: 'rgba8unorm',
|
||||||
|
depthStencilFormat: 'depth24plus-stencil8',
|
||||||
|
});
|
||||||
|
|
||||||
|
log.info('[XR-WebGPU] Projection layer created:', projectionLayer.textureWidth, 'x', projectionLayer.textureHeight);
|
||||||
|
|
||||||
|
xrSession.updateRenderState({ layers: [projectionLayer] } as any);
|
||||||
|
|
||||||
|
const wrapper = new XRGPUProjectionLayerWrapper(
|
||||||
|
projectionLayer, gpuBinding, this._engine, this._scene
|
||||||
|
);
|
||||||
|
this._sessionManager._setBaseLayerWrapper(wrapper);
|
||||||
|
|
||||||
|
log.info('[XR-WebGPU] Layer wrapper set on session manager');
|
||||||
|
return null as any;
|
||||||
|
}
|
||||||
|
|
||||||
|
public dispose(): void {
|
||||||
|
/* nothing to clean up — layer lifetime is tied to XR session */
|
||||||
|
}
|
||||||
|
}
|
||||||
30
src/core/xr-webgpu/xrGpuSessionSetup.ts
Normal file
30
src/core/xr-webgpu/xrGpuSessionSetup.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Helpers for accessing the GPUDevice from WebGPUEngine
|
||||||
|
* and building XR session init options for WebGPU.
|
||||||
|
*/
|
||||||
|
import { WebGPUEngine } from "@babylonjs/core";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the GPUDevice from a WebGPUEngine instance.
|
||||||
|
* WebGPUEngine stores _device privately; this accessor is stable across versions.
|
||||||
|
*/
|
||||||
|
export function getGpuDeviceFromEngine(engine: WebGPUEngine): GPUDevice {
|
||||||
|
const device = (engine as any)._device as GPUDevice | undefined;
|
||||||
|
if (!device) {
|
||||||
|
throw new Error('[XR-WebGPU] Could not access GPUDevice from engine');
|
||||||
|
}
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build XRSessionInit that adds 'webgpu' to requiredFeatures.
|
||||||
|
*/
|
||||||
|
export function buildWebGPUSessionInit(
|
||||||
|
baseInit: XRSessionInit = {}
|
||||||
|
): XRSessionInit {
|
||||||
|
const existing = baseInit.requiredFeatures ?? [];
|
||||||
|
return {
|
||||||
|
...baseInit,
|
||||||
|
requiredFeatures: [...existing, 'webgpu'],
|
||||||
|
};
|
||||||
|
}
|
||||||
85
src/core/xr-webgpu/xrGpuTextureProvider.ts
Normal file
85
src/core/xr-webgpu/xrGpuTextureProvider.ts
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/**
|
||||||
|
* WebGPU XR texture provider — gets GPUTexture per-view from XRGPUBinding
|
||||||
|
* and swaps it into the cached RenderTargetTexture each frame.
|
||||||
|
*/
|
||||||
|
import { RenderTargetTexture, WebGPUEngine, WebXRLayerRenderTargetTextureProvider } from "@babylonjs/core";
|
||||||
|
import type { Viewport, Scene, Nullable } from "@babylonjs/core";
|
||||||
|
import type { WebXRLayerWrapper } from "@babylonjs/core/XR/webXRLayerWrapper";
|
||||||
|
import type { XRGPUBinding, XRGPUSubImage } from "./xrGpuTypes";
|
||||||
|
import log from '../logger';
|
||||||
|
|
||||||
|
export class XRGPUTextureProvider extends WebXRLayerRenderTargetTextureProvider {
|
||||||
|
private _gpuBinding: XRGPUBinding;
|
||||||
|
private _projLayer: XRProjectionLayer;
|
||||||
|
private _gpuEngine: WebGPUEngine;
|
||||||
|
private _xrScene: Scene;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
scene: Scene,
|
||||||
|
layerWrapper: WebXRLayerWrapper,
|
||||||
|
gpuBinding: XRGPUBinding,
|
||||||
|
projectionLayer: XRProjectionLayer,
|
||||||
|
gpuEngine: WebGPUEngine
|
||||||
|
) {
|
||||||
|
super(scene, layerWrapper);
|
||||||
|
this._gpuBinding = gpuBinding;
|
||||||
|
this._projLayer = projectionLayer;
|
||||||
|
this._gpuEngine = gpuEngine;
|
||||||
|
this._xrScene = scene;
|
||||||
|
this._framebufferDimensions = {
|
||||||
|
framebufferWidth: projectionLayer.textureWidth,
|
||||||
|
framebufferHeight: projectionLayer.textureHeight,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public getRenderTargetTextureForView(view: XRView): Nullable<RenderTargetTexture> {
|
||||||
|
const subImage = this._gpuBinding.getViewSubImage(this._projLayer, view);
|
||||||
|
const idx = view.eye === "right" ? 1 : 0;
|
||||||
|
if (!this._renderTargetTextures[idx]) {
|
||||||
|
this._renderTargetTextures[idx] = this._createGpuRTT(subImage);
|
||||||
|
} else {
|
||||||
|
this._swapGpuTexture(this._renderTargetTextures[idx], subImage);
|
||||||
|
}
|
||||||
|
return this._renderTargetTextures[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
public getRenderTargetTextureForEye(eye: XREye): Nullable<RenderTargetTexture> {
|
||||||
|
return this._renderTargetTextures[eye === "right" ? 1 : 0] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public trySetViewportForView(viewport: Viewport, view: XRView): boolean {
|
||||||
|
const sub = this._gpuBinding.getViewSubImage(this._projLayer, view);
|
||||||
|
if (!sub) return false;
|
||||||
|
const w = this._projLayer.textureWidth;
|
||||||
|
const h = this._projLayer.textureHeight;
|
||||||
|
viewport.x = sub.viewport.x / w;
|
||||||
|
viewport.y = sub.viewport.y / h;
|
||||||
|
viewport.width = sub.viewport.width / w;
|
||||||
|
viewport.height = sub.viewport.height / h;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _createGpuRTT(subImage: XRGPUSubImage): RenderTargetTexture {
|
||||||
|
const w = this._projLayer.textureWidth;
|
||||||
|
const h = this._projLayer.textureHeight;
|
||||||
|
const internalTex = this._gpuEngine.wrapWebGPUTexture(subImage.colorTexture);
|
||||||
|
internalTex.width = w;
|
||||||
|
internalTex.height = h;
|
||||||
|
const rtt = new RenderTargetTexture("xrGpuRTT", { width: w, height: h }, this._xrScene);
|
||||||
|
const origTex = rtt._texture;
|
||||||
|
rtt._texture = internalTex;
|
||||||
|
rtt.renderTarget!.setTexture(internalTex, 0);
|
||||||
|
origTex?.dispose();
|
||||||
|
rtt.disableRescaling();
|
||||||
|
log.debug(`[XR-WebGPU] Created RTT ${w}x${h}`);
|
||||||
|
return rtt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _swapGpuTexture(rtt: RenderTargetTexture, subImage: XRGPUSubImage): void {
|
||||||
|
const hwTex = rtt._texture?._hardwareTexture as any;
|
||||||
|
if (!hwTex?.set) return;
|
||||||
|
hwTex.set(subImage.colorTexture);
|
||||||
|
hwTex.view = null;
|
||||||
|
hwTex.viewForWriting = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
33
src/core/xr-webgpu/xrGpuTypes.ts
Normal file
33
src/core/xr-webgpu/xrGpuTypes.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* TypeScript declarations for WebXR-WebGPU Binding spec types.
|
||||||
|
* These are not yet in lib.dom or BabylonJS type definitions.
|
||||||
|
* @see https://github.com/immersive-web/WebXR-WebGPU-Binding/blob/main/explainer.md
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface XRGPUProjectionLayerInit {
|
||||||
|
textureFormat?: GPUTextureFormat;
|
||||||
|
depthStencilFormat?: GPUTextureFormat;
|
||||||
|
scaleFactor?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface XRGPUSubImage {
|
||||||
|
colorTexture: GPUTexture;
|
||||||
|
depthStencilTexture?: GPUTexture;
|
||||||
|
imageIndex: number;
|
||||||
|
viewport: { x: number; y: number; width: number; height: number };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface XRGPUBinding {
|
||||||
|
createProjectionLayer(init?: XRGPUProjectionLayerInit): XRProjectionLayer;
|
||||||
|
getViewSubImage(layer: XRProjectionLayer, view: XRView): XRGPUSubImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface XRGPUBindingConstructor {
|
||||||
|
new (session: XRSession, device: GPUDevice): XRGPUBinding;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Global augmentation for XRGPUBinding constructor */
|
||||||
|
declare global {
|
||||||
|
// eslint-disable-next-line no-var
|
||||||
|
var XRGPUBinding: XRGPUBindingConstructor | undefined;
|
||||||
|
}
|
||||||
@ -26,21 +26,21 @@ export default defineConfig({
|
|||||||
// Shaders must be explicitly included to avoid dynamic import failures through CloudFlare proxy
|
// Shaders must be explicitly included to avoid dynamic import failures through CloudFlare proxy
|
||||||
include: [
|
include: [
|
||||||
'@babylonjs/core',
|
'@babylonjs/core',
|
||||||
// Core shaders
|
// Core shaders (WebGL)
|
||||||
'@babylonjs/core/Shaders/default.vertex',
|
'@babylonjs/core/Shaders/default.vertex',
|
||||||
'@babylonjs/core/Shaders/default.fragment',
|
'@babylonjs/core/Shaders/default.fragment',
|
||||||
'@babylonjs/core/Shaders/rgbdDecode.fragment',
|
'@babylonjs/core/Shaders/rgbdDecode.fragment',
|
||||||
'@babylonjs/core/Shaders/procedural.vertex',
|
'@babylonjs/core/Shaders/procedural.vertex',
|
||||||
// PBR shaders
|
// PBR shaders (WebGL)
|
||||||
'@babylonjs/core/Shaders/pbr.vertex',
|
'@babylonjs/core/Shaders/pbr.vertex',
|
||||||
'@babylonjs/core/Shaders/pbr.fragment',
|
'@babylonjs/core/Shaders/pbr.fragment',
|
||||||
'@babylonjs/core/Shaders/pbrDebug.fragment',
|
'@babylonjs/core/Shaders/pbrDebug.fragment',
|
||||||
// Particle shaders
|
// Particle shaders (WebGL)
|
||||||
'@babylonjs/core/Shaders/particles.vertex',
|
'@babylonjs/core/Shaders/particles.vertex',
|
||||||
'@babylonjs/core/Shaders/particles.fragment',
|
'@babylonjs/core/Shaders/particles.fragment',
|
||||||
'@babylonjs/core/Shaders/gpuRenderParticles.vertex',
|
'@babylonjs/core/Shaders/gpuRenderParticles.vertex',
|
||||||
'@babylonjs/core/Shaders/gpuRenderParticles.fragment',
|
'@babylonjs/core/Shaders/gpuRenderParticles.fragment',
|
||||||
// Other common shaders
|
// Other common shaders (WebGL)
|
||||||
'@babylonjs/core/Shaders/standard.fragment',
|
'@babylonjs/core/Shaders/standard.fragment',
|
||||||
'@babylonjs/core/Shaders/postprocess.vertex',
|
'@babylonjs/core/Shaders/postprocess.vertex',
|
||||||
'@babylonjs/core/Shaders/pass.fragment',
|
'@babylonjs/core/Shaders/pass.fragment',
|
||||||
@ -48,6 +48,21 @@ export default defineConfig({
|
|||||||
'@babylonjs/core/Shaders/shadowMap.fragment',
|
'@babylonjs/core/Shaders/shadowMap.fragment',
|
||||||
'@babylonjs/core/Shaders/depth.vertex',
|
'@babylonjs/core/Shaders/depth.vertex',
|
||||||
'@babylonjs/core/Shaders/depth.fragment',
|
'@babylonjs/core/Shaders/depth.fragment',
|
||||||
|
// WGSL shaders (WebGPU equivalents)
|
||||||
|
'@babylonjs/core/ShadersWGSL/default.vertex',
|
||||||
|
'@babylonjs/core/ShadersWGSL/default.fragment',
|
||||||
|
'@babylonjs/core/ShadersWGSL/rgbdDecode.fragment',
|
||||||
|
'@babylonjs/core/ShadersWGSL/procedural.vertex',
|
||||||
|
'@babylonjs/core/ShadersWGSL/pbr.vertex',
|
||||||
|
'@babylonjs/core/ShadersWGSL/pbr.fragment',
|
||||||
|
'@babylonjs/core/ShadersWGSL/particles.vertex',
|
||||||
|
'@babylonjs/core/ShadersWGSL/particles.fragment',
|
||||||
|
'@babylonjs/core/ShadersWGSL/postprocess.vertex',
|
||||||
|
'@babylonjs/core/ShadersWGSL/pass.fragment',
|
||||||
|
'@babylonjs/core/ShadersWGSL/shadowMap.vertex',
|
||||||
|
'@babylonjs/core/ShadersWGSL/shadowMap.fragment',
|
||||||
|
'@babylonjs/core/ShadersWGSL/depth.vertex',
|
||||||
|
'@babylonjs/core/ShadersWGSL/depth.fragment',
|
||||||
'@babylonjs/loaders',
|
'@babylonjs/loaders',
|
||||||
'@babylonjs/havok',
|
'@babylonjs/havok',
|
||||||
'@babylonjs/materials',
|
'@babylonjs/materials',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user