David Catuhe 6 năm trước cách đây
mục cha
commit
3b7c0f8d97

+ 23 - 3
src/Bones/skeleton.ts

@@ -74,7 +74,7 @@ export class Skeleton implements IAnimatable {
     private _useTextureToStoreBoneMatrices = true;
     /**
      * Gets or sets a boolean indicating that bone matrices should be stored as a texture instead of using shader uniforms (default is true).
-     * Please note that this option is not available when needInitialSkinMatrix === true or if the hardware does not support it
+     * Please note that this option is not available if the hardware does not support it
      */
     public get useTextureToStoreBoneMatrices(): boolean {
         return this._useTextureToStoreBoneMatrices;
@@ -118,7 +118,7 @@ export class Skeleton implements IAnimatable {
      * Gets a boolean indicating that the skeleton effectively stores matrices into a texture
      */
     public get isUsingTextureForMatrices() {
-        return this.useTextureToStoreBoneMatrices && this._canUseTextureForBones && !this.needInitialSkinMatrix;
+        return this.useTextureToStoreBoneMatrices && this._canUseTextureForBones;
     }
 
     /**
@@ -191,7 +191,11 @@ export class Skeleton implements IAnimatable {
      * Gets the list of transform matrices to send to shaders inside a texture (one matrix per bone)
      * @returns a raw texture containing the data
      */
-    public getTransformMatrixTexture(): Nullable<RawTexture> {
+    public getTransformMatrixTexture(mesh: AbstractMesh): Nullable<RawTexture> {
+        if (this.needInitialSkinMatrix && mesh._transformMatrixTexture) {
+            return mesh._transformMatrixTexture;
+        }
+        
         return this._transformMatrixTexture;
     }
 
@@ -475,9 +479,25 @@ export class Skeleton implements IAnimatable {
                             bone._updateDifferenceMatrix(Tmp.Matrix[1]);
                         }
                     }
+
+                    if (this.isUsingTextureForMatrices) {
+                        const textureWidth = (this.bones.length + 1) * 4;
+                        if (!mesh._transformMatrixTexture || mesh._transformMatrixTexture.getSize().width !== textureWidth) {
+                            
+                            if (mesh._transformMatrixTexture) {
+                                mesh._transformMatrixTexture.dispose();                     
+                            }
+
+                            mesh._transformMatrixTexture = RawTexture.CreateRGBATexture(mesh._bonesTransformMatrices, (this.bones.length + 1) * 4, 1, this._scene, false, false, Constants.TEXTURE_NEAREST_SAMPLINGMODE, Constants.TEXTURETYPE_FLOAT);
+                        }
+                     }
                 }
 
                 this._computeTransformMatrices(mesh._bonesTransformMatrices, poseMatrix);
+
+                if (this.isUsingTextureForMatrices && mesh._transformMatrixTexture) {
+                    mesh._transformMatrixTexture.update(mesh._bonesTransformMatrices);
+                }
             }
         } else {
             if (!this._transformMatrices || this._transformMatrices.length !== 16 * (this.bones.length + 1)) {

+ 1 - 1
src/Lights/Shadows/shadowGenerator.ts

@@ -1001,7 +1001,7 @@ export class ShadowGenerator implements IShadowGenerator {
                 const skeleton = mesh.skeleton;
 
                 if (skeleton.isUsingTextureForMatrices) {
-                    const boneTexture = skeleton.getTransformMatrixTexture();
+                    const boneTexture = skeleton.getTransformMatrixTexture(mesh);
 
                     if (!boneTexture) {
                         return;

+ 1 - 1
src/Materials/materialHelper.ts

@@ -762,7 +762,7 @@ export class MaterialHelper {
             const skeleton = mesh.skeleton;
 
             if (skeleton.isUsingTextureForMatrices && effect.getUniformIndex("boneTextureWidth") > -1) {
-                const boneTexture = skeleton.getTransformMatrixTexture();
+                const boneTexture = skeleton.getTransformMatrixTexture(mesh);
                 effect.setTexture("boneSampler", boneTexture);
                 effect.setFloat("boneTextureWidth", 4.0 * (skeleton.bones.length + 1));
             } else {

+ 9 - 0
src/Meshes/abstractMesh.ts

@@ -23,6 +23,7 @@ import { Constants } from "../Engines/constants";
 import { AbstractActionManager } from '../Actions/abstractActionManager';
 import { _MeshCollisionData } from '../Collisions/meshCollisionData';
 import { _DevTools } from '../Misc/devTools';
+import { RawTexture } from '../Materials/Textures/rawTexture';
 
 declare type Ray = import("../Culling/ray").Ray;
 declare type Collider = import("../Collisions/collider").Collider;
@@ -608,6 +609,9 @@ export class AbstractMesh extends TransformNode implements IDisposable, ICullabl
     /** @hidden */
     public _bonesTransformMatrices: Nullable<Float32Array> = null;
 
+    /** @hidden */
+    public _transformMatrixTexture: Nullable<RawTexture> = null;
+
     /**
      * Gets or sets a skeleton to apply skining transformations
      * @see http://doc.babylonjs.com/how_to/how_to_use_bones_and_skeletons
@@ -1570,6 +1574,11 @@ export class AbstractMesh extends TransformNode implements IDisposable, ICullabl
         // Skeleton
         this._internalAbstractMeshDataInfo._skeleton = null;
 
+        if (this._transformMatrixTexture) {
+            this._transformMatrixTexture.dispose();
+            this._transformMatrixTexture = null;
+        }
+
         // Intersections in progress
         for (index = 0; index < this._intersectionsInProgress.length; index++) {
             var other = this._intersectionsInProgress[index];