Browse Source

Merge pull request #9793 from Popov72/fix-webgpu-morphtarget

Fix WebGPU morph targets
David Catuhe 4 years ago
parent
commit
24b3356939

+ 2 - 0
src/Engines/WebGPU/webgpuShaderProcessors.ts

@@ -31,6 +31,7 @@ const _knownSamplers: { [key: string]: WebGPUTextureSamplerBindingDescription }
 // TODO WEBGPU. sampler3D
 const _samplerFunctionByWebGLSamplerType: { [key: string]: string } = {
     "sampler2D": "sampler2D",
+    "sampler2DArray": "sampler2DArray",
     "sampler2DShadow": "sampler2DShadow",
     "sampler2DArrayShadow": "sampler2DArrayShadow",
     "samplerCube": "samplerCube"
@@ -38,6 +39,7 @@ const _samplerFunctionByWebGLSamplerType: { [key: string]: string } = {
 
 const _textureTypeByWebGLSamplerType: { [key: string]: string } = {
     "sampler2D": "texture2D",
+    "sampler2DArray": "texture2DArray",
     "sampler2DShadow": "texture2D",
     "sampler2DArrayShadow": "texture2DArray",
     "samplerCube": "textureCube",

+ 4 - 2
src/Engines/WebGPU/webgpuTextureHelper.ts

@@ -1031,7 +1031,8 @@ export class WebGPUTextureHelper {
                 commandEncoder!.copyBufferToTexture({
                     buffer: buffer,
                     offset: 0,
-                    bytesPerRow
+                    bytesPerRow,
+                    rowsPerImage: height,
                 }, textureCopyView, textureExtent);
 
                 if (useOwnCommandEncoder) {
@@ -1043,7 +1044,8 @@ export class WebGPUTextureHelper {
             } else {
                 this._device.defaultQueue.writeTexture(textureCopyView, imageBitmap, {
                     offset: 0,
-                    bytesPerRow
+                    bytesPerRow,
+                    rowsPerImage: height,
                 }, textureExtent);
             }
 

+ 44 - 7
src/Engines/webgpuEngine.ts

@@ -232,8 +232,6 @@ export class WebGPUEngine extends Engine {
     public dbgVerboseLogsForFirstFrames = false;
     /** @hidden */
     public dbgVerboseLogsNumFrames = 10;
-    /** @hidden */
-    public dbgShowWarningsNotImplemented = false;
 
     /**
      * Sets this to true to disable the cache for the samplers. You should do it only for testing purpose!
@@ -1677,10 +1675,28 @@ export class WebGPUEngine extends Engine {
         var source = InternalTextureSource.Raw2DArray;
         var texture = new InternalTexture(this, source);
 
-        if (this.dbgShowWarningsNotImplemented) {
-            console.warn("createRawTexture2DArray not implemented yet in WebGPU");
+        texture.baseWidth = width;
+        texture.baseHeight = height;
+        texture.baseDepth = depth;
+        texture.width = width;
+        texture.height = height;
+        texture.depth = depth;
+        texture.format = format;
+        texture.type = textureType;
+        texture.generateMipMaps = generateMipMaps;
+        texture.samplingMode = samplingMode;
+        texture.is2DArray = true;
+
+        if (!this._doNotHandleContextLost) {
+            texture._bufferView = data;
         }
 
+        this._textureHelper.createGPUTextureForInternalTexture(texture, width, height, depth);
+
+        this.updateRawTexture2DArray(texture, data, format, invertY, compression, textureType);
+
+        this._internalTexturesCache.push(texture);
+
         return texture;
     }
 
@@ -2224,9 +2240,30 @@ export class WebGPUEngine extends Engine {
      * @param textureType defines the texture Type (Engine.TEXTURETYPE_UNSIGNED_INT, Engine.TEXTURETYPE_FLOAT...)
      */
     public updateRawTexture2DArray(texture: InternalTexture, bufferView: Nullable<ArrayBufferView>, format: number, invertY: boolean, compression: Nullable<string> = null, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT): void {
-        if (this.dbgShowWarningsNotImplemented) {
-            console.warn("updateRawTexture2DArray not implemented yet in WebGPU");
+        if (!this._doNotHandleContextLost) {
+            texture._bufferView = bufferView;
+            texture.format = format;
+            texture.invertY = invertY;
+            texture._compression = compression;
         }
+
+        if (bufferView) {
+            const gpuTextureWrapper = texture._hardwareTexture as WebGPUHardwareTexture;
+            const needConversion = format === Constants.TEXTUREFORMAT_RGB;
+
+            if (needConversion) {
+                bufferView = _convertRGBtoRGBATextureData(bufferView, texture.width, texture.height, textureType);
+            }
+
+            const data = new Uint8Array(bufferView.buffer, bufferView.byteOffset, bufferView.byteLength);
+
+            this._textureHelper.updateTexture(data, gpuTextureWrapper.underlyingResource!, texture.width, texture.height, texture.depth, gpuTextureWrapper.format, 0, 0, invertY, false, 0, 0, this._uploadEncoder);
+            if (texture.generateMipMaps) {
+                this._generateMipmaps(texture, this._uploadEncoder);
+            }
+        }
+
+        texture.isReady = true;
     }
 
     /**
@@ -2239,7 +2276,7 @@ export class WebGPUEngine extends Engine {
      * @param textureType defines the texture Type (Engine.TEXTURETYPE_UNSIGNED_INT, Engine.TEXTURETYPE_FLOAT...)
      */
     public updateRawTexture3D(texture: InternalTexture, bufferView: Nullable<ArrayBufferView>, format: number, invertY: boolean, compression: Nullable<string> = null, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT): void {
-    if (!this._doNotHandleContextLost) {
+        if (!this._doNotHandleContextLost) {
             texture._bufferView = bufferView;
             texture.format = format;
             texture.invertY = invertY;

+ 4 - 4
src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts

@@ -188,7 +188,7 @@ export class MorphTargetsBlock extends NodeMaterialBlock {
         for (var index = 0; index < repeatCount; index++) {
             injectionCode += `#ifdef MORPHTARGETS\r\n`;
             if (manager?.isUsingTextureForTargets) {
-                injectionCode += `${positionOutput.associatedVariableName} += (readVector3FromRawSampler(morphTargets[${index}], vertexID) - ${position.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
+                injectionCode += `${positionOutput.associatedVariableName} += (readVector3FromRawSampler(${index}., vertexID) - ${position.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
                 injectionCode += `vertexID += 1.0;\r\n`;
             } else {
                 injectionCode += `${positionOutput.associatedVariableName} += (position${index} - ${position.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
@@ -197,7 +197,7 @@ export class MorphTargetsBlock extends NodeMaterialBlock {
             if (hasNormals) {
                 injectionCode += `#ifdef MORPHTARGETS_NORMAL\r\n`;
                 if (manager?.isUsingTextureForTargets) {
-                    injectionCode += `${normalOutput.associatedVariableName} += (readVector3FromRawSampler(morphTargets[${index}], vertexID) - ${normal.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
+                    injectionCode += `${normalOutput.associatedVariableName} += (readVector3FromRawSampler(${index}., vertexID) - ${normal.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
                     injectionCode += `vertexID += 1.0;\r\n`;
                 } else {
                     injectionCode += `${normalOutput.associatedVariableName} += (normal${index} - ${normal.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
@@ -208,7 +208,7 @@ export class MorphTargetsBlock extends NodeMaterialBlock {
             if (hasUVs) {
                 injectionCode += `#ifdef MORPHTARGETS_UV\r\n`;
                 if (manager?.isUsingTextureForTargets) {
-                    injectionCode += `${uvOutput.associatedVariableName} += (readVector3FromRawSampler(morphTargets[${index}], vertexID).xy - ${uv.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
+                    injectionCode += `${uvOutput.associatedVariableName} += (readVector3FromRawSampler(${index}., vertexID).xy - ${uv.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
                     injectionCode += `vertexID += 1.0;\r\n`;
                 } else {
                     injectionCode += `${uvOutput.associatedVariableName}.xy += (uv_${index} - ${uv.associatedVariableName}.xy) * morphTargetInfluences[${index}];\r\n`;
@@ -219,7 +219,7 @@ export class MorphTargetsBlock extends NodeMaterialBlock {
             if (hasTangents) {
                 injectionCode += `#ifdef MORPHTARGETS_TANGENT\r\n`;
                 if (manager?.isUsingTextureForTargets) {
-                    injectionCode += `${tangentOutput.associatedVariableName} += (readVector3FromRawSampler(morphTargets[${index}], vertexID) - ${tangent.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
+                    injectionCode += `${tangentOutput.associatedVariableName} += (readVector3FromRawSampler(${index}., vertexID) - ${tangent.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`;
                 } else {
                     injectionCode += `${tangentOutput.associatedVariableName}.xyz += (tangent${index} - ${tangent.associatedVariableName}.xyz) * morphTargetInfluences[${index}];\r\n`;
                 }

+ 1 - 1
src/Shaders/ShadersInclude/morphTargetsVertexGlobalDeclaration.fx

@@ -10,7 +10,7 @@
 		{			
 			float y = floor(vertexIndex / morphTargetTextureInfo.y);
 			float x = vertexIndex - y * morphTargetTextureInfo.y;
-			vec3 textureUV = vec3((x + 0.5) / morphTargetTextureInfo.y, y / morphTargetTextureInfo.z, targetIndex);
+			vec3 textureUV = vec3((x + 0.5) / morphTargetTextureInfo.y, (y + 0.5) / morphTargetTextureInfo.z, targetIndex);
 			return texture(morphTargets, textureUV).xyz;
 		}
 	#endif

+ 2 - 1
tests/validation/config.json

@@ -679,7 +679,8 @@
         {
             "title": "GLTF Buggy with Meshopt Compression",
             "playgroundId": "#CIYTF6#0",
-            "referenceImage": "gltfBuggyMeshopt.png"
+            "referenceImage": "gltfBuggyMeshopt.png",
+            "excludedEngines": ["webgpu"]
         },
         {
             "title": "GLTF BoomBox with Unlit Material",