diff --git a/packages/dev/core/src/FrameGraph/Node/nodeRenderGraphBlock.ts b/packages/dev/core/src/FrameGraph/Node/nodeRenderGraphBlock.ts index 20c8a529e77..3b17f97676a 100644 --- a/packages/dev/core/src/FrameGraph/Node/nodeRenderGraphBlock.ts +++ b/packages/dev/core/src/FrameGraph/Node/nodeRenderGraphBlock.ts @@ -299,6 +299,10 @@ export class NodeRenderGraphBlock { NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer | NodeRenderGraphBlockConnectionPointTypes.ResourceContainer | NodeRenderGraphBlockConnectionPointTypes.ShadowGenerator | + NodeRenderGraphBlockConnectionPointTypes.ObjectList | + NodeRenderGraphBlockConnectionPointTypes.ShadowLight | + NodeRenderGraphBlockConnectionPointTypes.Camera | + NodeRenderGraphBlockConnectionPointTypes.Object | additionalAllowedTypes ); diff --git a/packages/dev/core/src/FrameGraph/Tasks/Misc/lightingVolumeTask.ts b/packages/dev/core/src/FrameGraph/Tasks/Misc/lightingVolumeTask.ts index 369a818bea5..5b3dd5efa72 100644 --- a/packages/dev/core/src/FrameGraph/Tasks/Misc/lightingVolumeTask.ts +++ b/packages/dev/core/src/FrameGraph/Tasks/Misc/lightingVolumeTask.ts @@ -14,6 +14,7 @@ export class FrameGraphLightingVolumeTask extends FrameGraphTask { /** * The output object list containing the lighting volume mesh. + * You can get the mesh by doing outputMeshLightingVolume.meshes[0] */ public readonly outputMeshLightingVolume: FrameGraphObjectList; diff --git a/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/volumetricLightingBlendVolumeTask.ts b/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/volumetricLightingBlendVolumeTask.ts index cd48ea49233..028db381e7f 100644 --- a/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/volumetricLightingBlendVolumeTask.ts +++ b/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/volumetricLightingBlendVolumeTask.ts @@ -4,9 +4,6 @@ import { Constants } from "core/Engines/constants"; import { ThinPassPostProcess } from "core/PostProcesses/thinPassPostProcess"; import { FrameGraphPostProcessTask } from "./postProcessTask"; -import "core/Shaders/volumetricLightingBlendVolume.fragment"; -import "core/ShadersWGSL/volumetricLightingBlendVolume.fragment"; - /** * @internal */ @@ -23,6 +20,17 @@ class VolumetricLightingBlendVolumeThinPostProcess extends ThinPassPostProcess { private _invProjection: Matrix; + protected override _gatherImports(useWebGPU: boolean, list: Promise[]) { + if (useWebGPU) { + this._webGPUReady = true; + list.push(Promise.all([import("../../../ShadersWGSL/pass.fragment"), import("../../../ShadersWGSL/volumetricLightingBlendVolume.fragment")])); + } else { + list.push(Promise.all([import("../../../Shaders/pass.fragment"), import("../../../Shaders/volumetricLightingBlendVolume.fragment")])); + } + + super._gatherImports(useWebGPU, list); + } + constructor(name: string, engine: Nullable = null, enableExtinction = false, options?: EffectWrapperCreationOptions) { super(name, engine, { ...options, diff --git a/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/volumetricLightingTask.ts b/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/volumetricLightingTask.ts index 8a5a1192685..db2f5b03ac0 100644 --- a/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/volumetricLightingTask.ts +++ b/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/volumetricLightingTask.ts @@ -9,11 +9,6 @@ import { FrameGraphObjectRendererTask } from "../Rendering/objectRendererTask"; import { ShaderMaterial } from "core/Materials/shaderMaterial"; import { ShaderLanguage } from "core/Materials/shaderLanguage"; -import "core/Shaders/volumetricLightingRenderVolume.vertex"; -import "core/Shaders/volumetricLightingRenderVolume.fragment"; -import "core/ShadersWGSL/volumetricLightingRenderVolume.vertex"; -import "core/ShadersWGSL/volumetricLightingRenderVolume.fragment"; - const InvViewProjectionMatrix = new Matrix(); /** @@ -187,6 +182,15 @@ export class FrameGraphVolumetricLightingTask extends FrameGraphTask { this.lightPower = this._lightPower; } + // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax + public override initAsync(): Promise { + if (this._frameGraph.engine.isWebGPU) { + return Promise.all([import("../../../ShadersWGSL/volumetricLightingRenderVolume.vertex"), import("../../../ShadersWGSL/volumetricLightingRenderVolume.fragment")]); + } + + return Promise.all([import("../../../Shaders/volumetricLightingRenderVolume.vertex"), import("../../../Shaders/volumetricLightingRenderVolume.fragment")]); + } + public override isReady() { return ( this._renderLightingVolumeMaterial.isReady() && diff --git a/packages/dev/core/src/FrameGraph/frameGraph.ts b/packages/dev/core/src/FrameGraph/frameGraph.ts index eb99a524ce5..e1c61af8843 100644 --- a/packages/dev/core/src/FrameGraph/frameGraph.ts +++ b/packages/dev/core/src/FrameGraph/frameGraph.ts @@ -10,9 +10,6 @@ import { _RetryWithInterval } from "core/Misc/timingTools"; import { Logger } from "core/Misc/logger"; import { UniqueIdGenerator } from "core/Misc/uniqueIdGenerator"; -import "core/Engines/Extensions/engine.multiRender"; -import "core/Engines/WebGPU/Extensions/engine.multiRender"; - enum FrameGraphPassType { Normal = 0, Render = 1, @@ -34,9 +31,10 @@ export class FrameGraph implements IDisposable { private readonly _tasks: FrameGraphTask[] = []; private readonly _passContext: FrameGraphContext; private readonly _renderContext: FrameGraphRenderContext; - private readonly _initAsyncPromises: Promise[] = []; + private readonly _initAsyncPromises: Promise[] = []; private _currentProcessedTask: FrameGraphTask | null = null; private _whenReadyAsyncCancel: Nullable<() => void> = null; + private _importPromise: Promise; /** * Name of the frame graph @@ -105,6 +103,7 @@ export class FrameGraph implements IDisposable { ) { this._scene = scene; this._engine = scene.getEngine(); + this._importPromise = this._engine.isWebGPU ? import("../Engines/WebGPU/Extensions/engine.multiRender") : import("../Engines/Extensions/engine.multiRender"); this.textureManager = new FrameGraphTextureManager(this._engine, debugTextures, scene); this._passContext = new FrameGraphContext(this._engine, this.textureManager, scene); this._renderContext = new FrameGraphRenderContext(this._engine, this.textureManager, scene); @@ -234,6 +233,8 @@ export class FrameGraph implements IDisposable { this._built = false; try { + await this._importPromise; + await this._whenAsynchronousInitializationDoneAsync(); for (const task of this._tasks) { diff --git a/packages/dev/core/src/FrameGraph/frameGraphTask.ts b/packages/dev/core/src/FrameGraph/frameGraphTask.ts index cf26ee4cbbd..7b0f28410c6 100644 --- a/packages/dev/core/src/FrameGraph/frameGraphTask.ts +++ b/packages/dev/core/src/FrameGraph/frameGraphTask.ts @@ -80,7 +80,7 @@ export abstract class FrameGraphTask { * @returns A promise that resolves when the initialization is complete. */ // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax - public initAsync(): Promise { + public initAsync(): Promise { return Promise.resolve(); } diff --git a/packages/dev/core/src/Lights/lightingVolume.ts b/packages/dev/core/src/Lights/lightingVolume.ts index e329035345f..7d088cab400 100644 --- a/packages/dev/core/src/Lights/lightingVolume.ts +++ b/packages/dev/core/src/Lights/lightingVolume.ts @@ -65,11 +65,7 @@ export class LightingVolume { this._createFallbackTextures(); } - const depthTexture = this._shadowGenerator.getShadowMap()?.depthStencilTexture; - if (this._engine.isWebGPU && depthTexture) { - this._cs!.setInternalTexture("shadowMap", depthTexture); - this._cs2!.setInternalTexture("shadowMap", depthTexture); - } + this._setComputeShaderInputs(); } private _tesselation = 0; @@ -300,21 +296,29 @@ export class LightingVolume { entryPoint: "updatePlaneVertices", }); + this._setComputeShaderInputs(); + } + + private _setComputeShaderInputs() { + if (!this._engine.isWebGPU) { + return; + } + if (this._shadowGenerator) { const depthTexture = this._shadowGenerator.getShadowMap()?.depthStencilTexture; if (depthTexture) { - this._cs.setInternalTexture("shadowMap", depthTexture); - this._cs2.setInternalTexture("shadowMap", depthTexture); + this._cs?.setInternalTexture("shadowMap", depthTexture); + this._cs2?.setInternalTexture("shadowMap", depthTexture); } } if (this._uBuffer) { - this._cs.setUniformBuffer("params", this._uBuffer); - this._cs2.setUniformBuffer("params", this._uBuffer); + this._cs?.setUniformBuffer("params", this._uBuffer); + this._cs2?.setUniformBuffer("params", this._uBuffer); } if (this._storageBuffer) { - this._cs.setStorageBuffer("positions", this._storageBuffer); - this._cs2.setStorageBuffer("positions", this._storageBuffer); + this._cs?.setStorageBuffer("positions", this._storageBuffer); + this._cs2?.setStorageBuffer("positions", this._storageBuffer); } } @@ -490,8 +494,7 @@ export class LightingVolume { this._mesh.setVerticesBuffer(new VertexBuffer(webGPUEngine, this._storageBuffer.getBuffer(), "position", { takeBufferOwnership: false }), true, vertexNumber); - this._cs!.setStorageBuffer("positions", this._storageBuffer); - this._cs2!.setStorageBuffer("positions", this._storageBuffer); + this._setComputeShaderInputs(); this._cs!.triggerContextRebuild = true; this._cs2!.triggerContextRebuild = true;