Przeglądaj źródła

Making progress

David Catuhe 4 lat temu
rodzic
commit
3f1d209ce3

BIN
Playground/scenes/cubeMorph_8target.glb


+ 2 - 1
src/Materials/Node/nodeMaterial.ts

@@ -81,7 +81,8 @@ export class NodeMaterialDefines extends MaterialDefines implements IImageProces
     public MORPHTARGETS_NORMAL = false;
     public MORPHTARGETS_TANGENT = false;
     public MORPHTARGETS_UV = false;
-    public NUM_MORPH_INFLUENCERS = 0;
+    public NUM_MORPH_INFLUENCERS = 0;    
+    public MORPHTARGETS_TEXTURE = false;
 
     /** IMAGE PROCESSING */
     public IMAGEPROCESSING = false;

+ 4 - 3
src/Materials/PBR/pbrBaseMaterial.ts

@@ -191,7 +191,8 @@ export class PBRMaterialDefines extends MaterialDefines
     public MORPHTARGETS_NORMAL = false;
     public MORPHTARGETS_TANGENT = false;
     public MORPHTARGETS_UV = false;
-    public NUM_MORPH_INFLUENCERS = 0;
+    public NUM_MORPH_INFLUENCERS = 0;    
+    public MORPHTARGETS_TEXTURE = false;
 
     public IMAGEPROCESSING = false;
     public VIGNETTE = false;
@@ -1295,13 +1296,13 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             "vSphericalL2_2", "vSphericalL2_1", "vSphericalL20", "vSphericalL21", "vSphericalL22",
             "vReflectionMicrosurfaceInfos",
             "vTangentSpaceParams", "boneTextureWidth",
-            "vDebugMode"
+            "vDebugMode", "morphTargetTextureInfo"
         ];
 
         var samplers = ["albedoSampler", "reflectivitySampler", "ambientSampler", "emissiveSampler",
             "bumpSampler", "lightmapSampler", "opacitySampler",
             "reflectionSampler", "reflectionSamplerLow", "reflectionSamplerHigh", "irradianceSampler",
-            "microSurfaceSampler", "environmentBrdfSampler", "boneSampler", "metallicReflectanceSampler"];
+            "microSurfaceSampler", "environmentBrdfSampler", "boneSampler", "metallicReflectanceSampler", "morphTargets"];
 
         var uniformBuffers = ["Material", "Scene", "Mesh"];
 

+ 2 - 0
src/Materials/materialHelper.ts

@@ -269,6 +269,8 @@ export class MaterialHelper {
             defines["MORPHTARGETS_NORMAL"] = manager.supportsNormals && defines["NORMAL"];
             defines["MORPHTARGETS"] = (manager.numInfluencers > 0);
             defines["NUM_MORPH_INFLUENCERS"] = manager.numInfluencers;
+
+            defines["MORPHTARGETS_TEXTURE"] = manager.isUsingTextureForTargets;
         } else {
             defines["MORPHTARGETS_UV"] = false;
             defines["MORPHTARGETS_TANGENT"] = false;

+ 4 - 2
src/Materials/standardMaterial.ts

@@ -123,6 +123,7 @@ export class StandardMaterialDefines extends MaterialDefines implements IImagePr
     public MORPHTARGETS_TANGENT = false;
     public MORPHTARGETS_UV = false;
     public NUM_MORPH_INFLUENCERS = 0;
+    public MORPHTARGETS_TEXTURE = false;
     public NONUNIFORMSCALING = false; // https://playground.babylonjs.com#V6DWIH
     public PREMULTIPLYALPHA = false; // https://playground.babylonjs.com#LNVJJ7
     public ALPHATEST_AFTERALLALPHACOMPUTATIONS = false;
@@ -1214,12 +1215,13 @@ export class StandardMaterial extends PushMaterial {
                 "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "vClipPlane5", "vClipPlane6", "diffuseMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "specularMatrix", "bumpMatrix", "normalMatrix", "lightmapMatrix", "refractionMatrix",
                 "diffuseLeftColor", "diffuseRightColor", "opacityParts", "reflectionLeftColor", "reflectionRightColor", "emissiveLeftColor", "emissiveRightColor", "refractionLeftColor", "refractionRightColor",
                 "vReflectionPosition", "vReflectionSize",
-                "logarithmicDepthConstant", "vTangentSpaceParams", "alphaCutOff", "boneTextureWidth"
+                "logarithmicDepthConstant", "vTangentSpaceParams", "alphaCutOff", "boneTextureWidth",
+                "morphTargetTextureInfo"
             ];
 
             var samplers = ["diffuseSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler",
                 "reflection2DSampler", "emissiveSampler", "specularSampler", "bumpSampler", "lightmapSampler",
-                "refractionCubeSampler", "refraction2DSampler", "boneSampler"];
+                "refractionCubeSampler", "refraction2DSampler", "boneSampler", "morphTargets"];
 
             var uniformBuffers = ["Material", "Scene", "Mesh"];
 

+ 5 - 0
src/Meshes/mesh.ts

@@ -1511,6 +1511,11 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
 
         var engine = this.getScene().getEngine();
 
+        // Morph targets
+        if (this.morphTargetManager && this.morphTargetManager.isUsingTextureForTargets) {
+            this.morphTargetManager._bind(effect);
+        }
+
         // Wireframe
         var indexToBind;
 

+ 34 - 14
src/Morph/morphTargetManager.ts

@@ -8,6 +8,7 @@ import { Mesh } from "../Meshes/mesh";
 import { MorphTarget } from "./morphTarget";
 import { RawTexture } from "../Materials/Textures/rawTexture";
 import { Constants } from "../Engines/constants";
+import { Effect } from "../Materials/effect";
 /**
  * This class is used to deform meshes using morphing between different targets
  * @see https://doc.babylonjs.com/how_to/how_to_use_morphtargets
@@ -23,6 +24,9 @@ export class MorphTargetManager {
     private _supportsTangents = false;
     private _supportsUVs = false;
     private _vertexCount = 0;
+    private _textureVertexStride = 0;
+    private _textureWidth = 0;
+    private _textureHeight = 1;
     private _uniqueId = 0;
     private _tempInfluences = new Array<number>();
     private _canUseTextureForTargets = false;
@@ -190,6 +194,12 @@ export class MorphTargetManager {
         }
     }
 
+    /** @hidden */
+    public _bind(effect: Effect) {
+        effect.setFloat3("morphTargetTextureInfo", this._textureVertexStride, this._textureWidth, this._textureHeight);
+        effect.setTextureArray("morphTargets", this._targetStoreTextures);
+    }
+
     /**
      * Clone the current manager
      * @returns a new MorphTargetManager
@@ -283,29 +293,40 @@ export class MorphTargetManager {
                 return;
             }
 
-            let textureWidth = this._vertexCount * 3;
+            this._textureVertexStride = 1;
 
             if (this._supportsNormals) {
-                textureWidth *= 2;
+                this._textureVertexStride++;
             }
 
             if (this._supportsTangents) {
-                textureWidth += this._vertexCount * 4;
+                this._textureVertexStride++;
             }
 
             if (this._supportsUVs) {
-                textureWidth += this._vertexCount * 2;
+                this._textureVertexStride++;
+            }
+
+            this._textureWidth = this._vertexCount * this._textureVertexStride;
+            this._textureHeight = 1;
+
+            const maxTextureSize = this._scene.getEngine().getCaps().maxTextureSize;
+            if (this._textureWidth > maxTextureSize) {
+                this._textureHeight = Math.ceil(this._textureWidth / maxTextureSize);
+                this._textureWidth = maxTextureSize;
             }
 
             for (var index = 0; index < this._targets.length; index++) {
                 let target = this._targets[index];
 
-                if (!this._targetStoreTextures[index] || this._targetStoreTextures[index].getSize().width !== textureWidth) {
+                if (!this._targetStoreTextures[index]
+                    || this._targetStoreTextures[index].getSize().width !== this._textureWidth * 4
+                    || this._targetStoreTextures[index].getSize().height !== this._textureHeight * 4) {
                     if (this._targetStoreTextures[index]) {
                         this._targetStoreTextures[index].dispose();
                     }
 
-                    let data = new Float32Array(textureWidth);
+                    let data = new Float32Array(this._textureWidth * this._textureHeight * 4);
 
                     let offset = 0;
                     const positions = target.getPositions();
@@ -323,31 +344,30 @@ export class MorphTargetManager {
                         data[offset + 1] = positions[vertex * 3 + 1];
                         data[offset + 2] = positions[vertex * 3 + 2];
 
-                        offset += 3;
+                        offset += 4;
 
                         if (normals) {
                             data[offset] = normals[vertex * 3];
                             data[offset + 1] = normals[vertex * 3 + 1];
                             data[offset + 2] = normals[vertex * 3 + 2];
-                            offset += 3;
+                            offset += 4;
                         }
 
                         if (uvs) {
                             data[offset] = uvs[vertex * 2];
                             data[offset + 1] = uvs[vertex * 2 + 1];
-                            offset += 2;
+                            offset += 4;
                         }
 
                         if (tangents) {
-                            data[offset] = tangents[vertex * 4];
-                            data[offset + 1] = tangents[vertex * 4 + 1];
-                            data[offset + 2] = tangents[vertex * 4 + 2];
-                            data[offset + 3] = tangents[vertex * 4 + 3];
+                            data[offset] = tangents[vertex * 3];
+                            data[offset + 1] = tangents[vertex * 3 + 1];
+                            data[offset + 2] = tangents[vertex * 3 + 2];
                             offset += 4;
                         }
                     }
 
-                    this._targetStoreTextures[index]= RawTexture.CreateRGBATexture(data, textureWidth, 1, 
+                    this._targetStoreTextures[index]= RawTexture.CreateRGBATexture(data, this._textureWidth, this._textureHeight, 
                         this._scene, false, false, Constants.TEXTURE_NEAREST_SAMPLINGMODE, Constants.TEXTURETYPE_FLOAT);
                 }
             }

+ 28 - 9
src/Shaders/ShadersInclude/morphTargetsVertex.fx

@@ -1,15 +1,34 @@
 #ifdef MORPHTARGETS
-	positionUpdated += (position{X} - position) * morphTargetInfluences[{X}];
+	#ifdef MORPHTARGETS_TEXTURE	
+		positionUpdated += (readVector3FromRawSampler(morphTargets[{X}], vertexID) - position) * morphTargetInfluences[{X}];
+		vertexID += 1.0;
 	
-	#ifdef MORPHTARGETS_NORMAL
-	normalUpdated += (normal{X} - normal) * morphTargetInfluences[{X}];
-	#endif
+		#ifdef MORPHTARGETS_NORMAL
+			normalUpdated += (readVector3FromRawSampler(morphTargets[{X}], vertexID)  - normal) * morphTargetInfluences[{X}];
+			vertexID += 1.0;
+		#endif
 
-	#ifdef MORPHTARGETS_TANGENT
-	tangentUpdated.xyz += (tangent{X} - tangent.xyz) * morphTargetInfluences[{X}];
-	#endif
+		#ifdef MORPHTARGETS_UV
+			uvUpdated += (readVector3FromRawSampler(morphTargets[{X}], vertexID).xy - uv) * morphTargetInfluences[{X}];
+			vertexID += 1.0;
+		#endif
+
+		#ifdef MORPHTARGETS_TANGENT
+			tangentUpdated.xyz += (readVector3FromRawSampler(morphTargets[{X}], vertexID)  - tangent.xyz) * morphTargetInfluences[{X}];
+		#endif
+	#else
+		positionUpdated += (position{X} - position) * morphTargetInfluences[{X}];
+		
+		#ifdef MORPHTARGETS_NORMAL
+		normalUpdated += (normal{X} - normal) * morphTargetInfluences[{X}];
+		#endif
+
+		#ifdef MORPHTARGETS_TANGENT
+		tangentUpdated.xyz += (tangent{X} - tangent.xyz) * morphTargetInfluences[{X}];
+		#endif
 
-    #ifdef MORPHTARGETS_UV
-	uvUpdated += (uv_{X} - uv) * morphTargetInfluences[{X}];
+		#ifdef MORPHTARGETS_UV
+		uvUpdated += (uv_{X} - uv) * morphTargetInfluences[{X}];
+		#endif
 	#endif
 #endif

+ 11 - 9
src/Shaders/ShadersInclude/morphTargetsVertexDeclaration.fx

@@ -1,15 +1,17 @@
 #ifdef MORPHTARGETS
-	attribute vec3 position{X};
+	#ifndef MORPHTARGETS_TEXTURE
+		attribute vec3 position{X};
 
-	#ifdef MORPHTARGETS_NORMAL
-	attribute vec3 normal{X};
-	#endif
+		#ifdef MORPHTARGETS_NORMAL
+		attribute vec3 normal{X};
+		#endif
 
-	#ifdef MORPHTARGETS_TANGENT
-	attribute vec3 tangent{X};
-	#endif
+		#ifdef MORPHTARGETS_TANGENT
+		attribute vec3 tangent{X};
+		#endif
 
-    #ifdef MORPHTARGETS_UV
-	attribute vec2 uv_{X};
+		#ifdef MORPHTARGETS_UV
+		attribute vec2 uv_{X};
+		#endif
 	#endif
 #endif

+ 5 - 0
src/Shaders/ShadersInclude/morphTargetsVertexGlobal.fx

@@ -0,0 +1,5 @@
+#ifdef MORPHTARGETS
+	#ifdef MORPHTARGETS_TEXTURE
+		float vertexID = float(gl_VertexID) * morphTargetTextureInfo.x;
+	#endif
+#endif

+ 13 - 0
src/Shaders/ShadersInclude/morphTargetsVertexGlobalDeclaration.fx

@@ -1,3 +1,16 @@
 #ifdef MORPHTARGETS
 	uniform float morphTargetInfluences[NUM_MORPH_INFLUENCERS];
+
+	#ifdef MORPHTARGETS_TEXTURE	
+		uniform vec3 morphTargetTextureInfo;
+		uniform sampler2D morphTargets[NUM_MORPH_INFLUENCERS];
+
+		vec3 readVector3FromRawSampler(sampler2D smp, float vertexIndex)
+		{			
+			float y = floor(vertexIndex / morphTargetTextureInfo.y);
+			float x = vertexIndex - y * morphTargetTextureInfo.y;
+			vec2 textureUV = vec2((x + 0.5) / morphTargetTextureInfo.y, y / morphTargetTextureInfo.z);
+			return texture2D(smp, textureUV).xyz;
+		}
+	#endif
 #endif

+ 1 - 0
src/Shaders/default.vertex.fx

@@ -120,6 +120,7 @@ void main(void) {
 	vec2 uvUpdated = uv;
 #endif
 
+#include<morphTargetsVertexGlobal>
 #include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]
 
 #ifdef REFLECTIONMAP_SKYBOX

+ 2 - 0
src/Shaders/depth.vertex.fx

@@ -30,6 +30,8 @@ void main(void)
 #ifdef UV1
     vec2 uvUpdated = uv;
 #endif
+
+#include<morphTargetsVertexGlobal>
 #include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]
 
 #include<instancesVertex>

+ 2 - 0
src/Shaders/geometry.vertex.fx

@@ -71,6 +71,8 @@ void main(void)
 #ifdef UV1
     vec2 uvUpdated = uv;
 #endif
+
+#include<morphTargetsVertexGlobal>
 #include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]
 
 #include<instancesVertex>

+ 3 - 0
src/Shaders/glowMapGeneration.vertex.fx

@@ -47,7 +47,10 @@ void main(void)
 #ifdef UV1
     vec2 uvUpdated = uv;
 #endif
+
+#include<morphTargetsVertexGlobal>
 #include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]
+
 #include<instancesVertex>
 #include<bonesVertex>
 

+ 1 - 0
src/Shaders/outline.vertex.fx

@@ -33,6 +33,7 @@ void main(void)
 #ifdef UV1
     vec2 uvUpdated = uv;
 #endif    
+    #include<morphTargetsVertexGlobal>
     #include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]
 
 	vec3 offsetPosition = positionUpdated + (normalUpdated * offset);

+ 1 - 0
src/Shaders/pbr.vertex.fx

@@ -173,6 +173,7 @@ void main(void) {
     vec2 uvUpdated = uv;
 #endif  
 
+#include<morphTargetsVertexGlobal>
 #include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]
 
 #ifdef REFLECTIONMAP_SKYBOX

+ 1 - 0
src/Shaders/shadowMap.vertex.fx

@@ -41,6 +41,7 @@ vec3 positionUpdated = position;
 	vec3 normalUpdated = normal;
 #endif
 
+#include<morphTargetsVertexGlobal>
 #include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]
 
 #include<instancesVertex>

+ 2 - 0
src/Shaders/volumetricLightScatteringPass.vertex.fx

@@ -28,6 +28,8 @@ void main(void)
 #if (defined(ALPHATEST) || defined(NEED_UV)) && defined(UV1)
     vec2 uvUpdated = uv;
 #endif
+
+#include<morphTargetsVertexGlobal>
 #include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]
 
 #include<instancesVertex>