Jelajahi Sumber

Fix the shadow depth wrapper to work with WebGPU

Popov72 4 tahun lalu
induk
melakukan
cb872f0d78

+ 5 - 3
src/Engines/WebGPU/webgpuPipelineContext.ts

@@ -58,8 +58,10 @@ export class WebGPUPipelineContext implements IPipelineContext {
     public leftOverUniformsByName: { [name: string]: string };
 
     public sources: {
-        vertex: string
+        vertex: string,
         fragment: string,
+        rawVertex: string,
+        rawFragment: string,
     };
 
     public stages: Nullable<IWebGPURenderPipelineStageDescriptor>;
@@ -422,10 +424,10 @@ export class WebGPUPipelineContext implements IPipelineContext {
     }
 
     public _getVertexShaderCode(): string | null {
-        return this.sources?.vertex ?? "<vertex shader code not available>";
+        return this.sources?.vertex;
     }
 
     public _getFragmentShaderCode(): string | null {
-        return this.sources?.fragment ?? "<fragment shader code not available>";
+        return this.sources?.fragment;
     }
 }

+ 1 - 1
src/Engines/nativeEngine.ts

@@ -984,7 +984,7 @@ export class NativeEngine extends Engine {
         return new NativePipelineContext();
     }
 
-    public _preparePipelineContext(pipelineContext: IPipelineContext, vertexSourceCode: string, fragmentSourceCode: string, createAsRaw: boolean, rebuildRebind: any, defines: Nullable<string>, transformFeedbackVaryings: Nullable<string[]>) {
+    public _preparePipelineContext(pipelineContext: IPipelineContext, vertexSourceCode: string, fragmentSourceCode: string, createAsRaw: boolean, rawVertexSourceCode: string, rawFragmentSourceCode: string, rebuildRebind: any, defines: Nullable<string>, transformFeedbackVaryings: Nullable<string[]>) {
         const nativePipelineContext = pipelineContext as NativePipelineContext;
 
         if (createAsRaw) {

+ 1 - 1
src/Engines/thinEngine.ts

@@ -2338,7 +2338,7 @@ export class ThinEngine {
     }
 
     /** @hidden */
-    public _preparePipelineContext(pipelineContext: IPipelineContext, vertexSourceCode: string, fragmentSourceCode: string, createAsRaw: boolean,
+    public _preparePipelineContext(pipelineContext: IPipelineContext, vertexSourceCode: string, fragmentSourceCode: string, createAsRaw: boolean, rawVertexSourceCode: string, rawFragmentSourceCode: string,
         rebuildRebind: any,
         defines: Nullable<string>,
         transformFeedbackVaryings: Nullable<string[]>,

+ 15 - 7
src/Engines/webgpuEngine.ts

@@ -197,8 +197,10 @@ export class WebGPUEngine extends Engine {
         leftOverUniforms: { name: string, type: string, length: number }[],
         leftOverUniformsByName: { [name: string]: string },
         sources: {
-            vertex: string
+            vertex: string,
             fragment: string,
+            rawVertex: string,
+            rawFragment: string,
         }
     } } = {};
 
@@ -881,7 +883,7 @@ export class WebGPUEngine extends Engine {
     }
 
     /** @hidden */
-    public _preparePipelineContext(pipelineContext: IPipelineContext, vertexSourceCode: string, fragmentSourceCode: string, createAsRaw: boolean,
+    public _preparePipelineContext(pipelineContext: IPipelineContext, vertexSourceCode: string, fragmentSourceCode: string, createAsRaw: boolean, rawVertexSourceCode: string, rawFragmentSourceCode: string,
         rebuildRebind: any,
         defines: Nullable<string>,
         transformFeedbackVaryings: Nullable<string[]>,
@@ -910,7 +912,9 @@ export class WebGPUEngine extends Engine {
 
             webGpuContext.sources = {
                 fragment: fragmentSourceCode,
-                vertex: vertexSourceCode
+                vertex: vertexSourceCode,
+                rawVertex: rawVertexSourceCode,
+                rawFragment: rawFragmentSourceCode,
             };
 
             if (createAsRaw) {
@@ -1498,14 +1502,15 @@ export class WebGPUEngine extends Engine {
                 return false;
             }
 
-            let internalTexture: InternalTexture;
+            let internalTexture: Nullable<InternalTexture> = null;
             if (depthStencilTexture) {
                 internalTexture = (<RenderTargetTexture>texture).depthStencilTexture!;
             }
             else if (texture.isReady()) {
                 internalTexture = <InternalTexture>texture.getInternalTexture();
             }
-            else if (texture.isCube) {
+            // TODO WEBGPU uncomment when raw textures are handled
+            /*!else if (texture.isCube) {
                 internalTexture = this.emptyCubeTexture;
             }
             else if (texture.is3D) {
@@ -1516,7 +1521,7 @@ export class WebGPUEngine extends Engine {
             }
             else {
                 internalTexture = this.emptyTexture;
-            }
+            }*/
 
             if (internalTexture && !internalTexture.isMultiview) {
                 // CUBIC_MODE and SKYBOX_MODE both require CLAMP_TO_EDGE.  All other modes use REPEAT.
@@ -1538,7 +1543,7 @@ export class WebGPUEngine extends Engine {
             }
 
             // TODO WEBGPU remove debug code
-            if ((internalTexture as any)._released) {
+            if (internalTexture && (internalTexture as any)._released) {
                 console.error("using a released texture in engine.setTexture!", internalTexture);
                 debugger;
             }
@@ -2065,6 +2070,8 @@ export class WebGPUEngine extends Engine {
         const depthStencilTexture = internalTexture._depthStencilTexture;
         const gpuDepthStencilTexture = depthStencilTexture?._hardwareTexture?.underlyingResource;
 
+        this._renderTargetEncoder.pushDebugGroup("start render target rendering");
+
         const renderPass = this._renderTargetEncoder.beginRenderPass({
             colorAttachments: [{
                 attachment: colorTextureView,
@@ -2190,6 +2197,7 @@ export class WebGPUEngine extends Engine {
 
         if (this._currentRenderPass && this._currentRenderPass !== this._mainRenderPass) {
             this._currentRenderPass.endPass();
+            this._renderTargetEncoder.popDebugGroup();
         }
 
         if (texture.generateMipMaps && !disableGenerateMipMaps && !texture.isCube) {

+ 30 - 5
src/Materials/effect.ts

@@ -182,6 +182,11 @@ export class Effect implements IDisposable {
     /** @hidden */
     public _fragmentSourceCode: string = "";
 
+    /** @hidden */
+    private _rawVertexSourceCode: string = "";
+    /** @hidden */
+    private _rawFragmentSourceCode: string = "";
+
     private static _baseCache: { [key: number]: DataBuffer } = {};
     private _processingContext: Nullable<ShaderProcessingContext>;
 
@@ -205,8 +210,10 @@ export class Effect implements IDisposable {
         engine?: ThinEngine, defines: Nullable<string> = null,
         fallbacks: Nullable<IEffectFallbacks> = null, onCompiled: Nullable<(effect: Effect) => void> = null, onError: Nullable<(effect: Effect, errors: string) => void> = null, indexParameters?: any, key: string = "",
         sources?: {
-            vertex: string
+            vertex: string,
             fragment: string,
+            rawVertex: string,
+            rawFragment: string,
         }) {
         this.name = baseName;
         this._key = key;
@@ -258,6 +265,8 @@ export class Effect implements IDisposable {
         if (sources) {
             this._fragmentSourceCode = sources.fragment;
             this._vertexSourceCode = sources.vertex;
+            this._rawFragmentSourceCode = sources.rawFragment;
+            this._rawVertexSourceCode = sources.rawVertex;
             this._prepareEffect();
             return;
         }
@@ -324,6 +333,7 @@ export class Effect implements IDisposable {
         };
         this._loadShader(vertexSource, "Vertex", "", (vertexCode) => {
             ShaderProcessor.Process(vertexCode, processorOptions, (migratedVertexCode) => {
+                this._rawVertexSourceCode = vertexCode;
                 if (processFinalCode) {
                     migratedVertexCode = processFinalCode("vertex", migratedVertexCode);
                 }
@@ -332,6 +342,7 @@ export class Effect implements IDisposable {
             });
         });
         this._loadShader(fragmentSource, "Fragment", "Pixel", (fragmentCode) => {
+            this._rawFragmentSourceCode = fragmentCode;
             shaderCodes[1] = fragmentCode;
             shadersLoaded();
         });
@@ -583,14 +594,28 @@ export class Effect implements IDisposable {
      * Gets the vertex shader source code of this effect
      */
     public get vertexSourceCode(): string {
-        return this._vertexSourceCodeOverride && this._fragmentSourceCodeOverride ? this._vertexSourceCodeOverride : this._vertexSourceCode;
+        return this._vertexSourceCodeOverride && this._fragmentSourceCodeOverride ? this._vertexSourceCodeOverride : (this._pipelineContext?._getVertexShaderCode() ?? this._vertexSourceCode);
     }
 
     /**
      * Gets the fragment shader source code of this effect
      */
     public get fragmentSourceCode(): string {
-        return this._vertexSourceCodeOverride && this._fragmentSourceCodeOverride ? this._fragmentSourceCodeOverride : this._fragmentSourceCode;
+        return this._vertexSourceCodeOverride && this._fragmentSourceCodeOverride ? this._fragmentSourceCodeOverride : (this._pipelineContext?._getFragmentShaderCode() ?? this._fragmentSourceCode);
+    }
+
+    /**
+     * Gets the vertex shader source code before it has been processed by the preprocessor
+     */
+    public get rawVertexSourceCode(): string {
+        return this._rawVertexSourceCode;
+    }
+
+    /**
+     * Gets the fragment shader source code before it has been processed by the preprocessor
+     */
+    public get rawFragmentSourceCode(): string {
+        return this._rawFragmentSourceCode;
     }
 
     /**
@@ -642,10 +667,10 @@ export class Effect implements IDisposable {
 
             let rebuildRebind = this._rebuildProgram.bind(this);
             if (this._vertexSourceCodeOverride && this._fragmentSourceCodeOverride) {
-                engine._preparePipelineContext(this._pipelineContext, this._vertexSourceCodeOverride, this._fragmentSourceCodeOverride, true, rebuildRebind, null, this._transformFeedbackVaryings, this._key);
+                engine._preparePipelineContext(this._pipelineContext, this._vertexSourceCodeOverride, this._fragmentSourceCodeOverride, true, this._rawVertexSourceCode, this._rawFragmentSourceCode, rebuildRebind, null, this._transformFeedbackVaryings, this._key);
             }
             else {
-                engine._preparePipelineContext(this._pipelineContext, this._vertexSourceCode, this._fragmentSourceCode, false, rebuildRebind, defines, this._transformFeedbackVaryings, this._key);
+                engine._preparePipelineContext(this._pipelineContext, this._vertexSourceCode, this._fragmentSourceCode, false, this._rawVertexSourceCode, this._rawFragmentSourceCode, rebuildRebind, defines, this._transformFeedbackVaryings, this._key);
             }
 
             engine._executeWhenRenderingStateIsCompiled(this._pipelineContext, () => {

+ 2 - 2
src/Materials/shadowDepthWrapper.ts

@@ -199,8 +199,8 @@ export class ShadowDepthWrapper {
         params.depthDefines = join;
 
         // the depth effect is either out of date or has not been created yet
-        let vertexCode = origEffect.vertexSourceCode,
-            fragmentCode = origEffect.fragmentSourceCode;
+        let vertexCode = origEffect.rawVertexSourceCode,
+            fragmentCode = origEffect.rawFragmentSourceCode;
 
         // vertex code
         const vertexNormalBiasCode = this._options && this._options.remappedVariables ? `#include<shadowMapVertexNormalBias>(${this._options.remappedVariables.join(",")})` : Effect.IncludesShadersStore["shadowMapVertexNormalBias"],