瀏覽代碼

stuck with MaterialHelper

Andrew V Butt Sr 5 年之前
父節點
當前提交
c7cc1c09b9

+ 5 - 0
Tools/Config/config.json

@@ -231,6 +231,11 @@
                 "output": "babylon.waterMaterial.min.js",
                 "entry": "./legacy/legacy-water.ts",
                 "preventLoadLibrary": true
+            },
+            {
+                "output": "babylon.boneWeightsMaterial.min.js",
+                "entry": "./legacy/legacy-boneWeights.ts",
+                "preventLoadLibrary": true
             }
         ],
         "build": {

+ 14 - 0
materialsLibrary/src/legacy/legacy-boneWeights.ts

@@ -0,0 +1,14 @@
+import * as MatLib from "../boneWeights";
+
+/**
+ * This is the entry point for the UMD module.
+ * The entry point for a future ESM package should be index.ts
+ */
+var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : undefined);
+if (typeof globalObject !== "undefined") {
+    for (var key in MatLib) {
+        (<any>globalObject).BABYLON[key] = (<any>MatLib)[key];
+    }
+}
+
+export * from "../boneWeights";

+ 0 - 2
materialsLibrary/src/skeletonDebug/boneWeights.fragment.fx

@@ -1,6 +1,4 @@
 precision highp float;
-varying vec3 vPosition;
-
 varying vec3 vColor;
 
 void main() {

+ 256 - 98
materialsLibrary/src/skeletonDebug/boneWeightsMaterial.ts

@@ -1,127 +1,285 @@
+import { Nullable } from "babylonjs/types";
+import { serialize,  serializeAsColor3, SerializationHelper } from "babylonjs/Misc/decorators";
+import { Matrix } from "babylonjs/Maths/math.vector";
+import { Color3 } from "babylonjs/Maths/math.color";
+import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
+import { IEffectCreationOptions } from "babylonjs/Materials/effect";
+import { MaterialDefines } from "babylonjs/Materials/materialDefines";
+import { MaterialHelper } from "babylonjs/Materials/materialHelper";
+import { PushMaterial } from "babylonjs/Materials/pushMaterial";
+
+import { VertexBuffer } from "babylonjs/Meshes/buffer";
+import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
+import { SubMesh } from "babylonjs/Meshes/subMesh";
+import { Mesh } from "babylonjs/Meshes/mesh";
 import { Scene } from "babylonjs/scene";
 import { _TypeStore } from 'babylonjs/Misc/typeStore';
-//import "./boneWeights.fragment";
-//import "./boneWeights.vertex";
+import { IAnimatable } from 'babylonjs/Animations/animatable.interface';
+import { EffectFallbacks } from 'babylonjs/Materials/effectFallbacks';
+
+import "./boneWeights.fragment";
+import "./boneWeights.vertex";
 
 import { IBoneWeightsMaterialOptions } from "./IBoneWeightsMaterial";
-import { Skeleton, Color3, ShaderMaterial, Material } from 'babylonjs';
+import { Skeleton } from 'babylonjs';
+
+class BoneWeightsMaterialDefines extends MaterialDefines {
+    public DIFFUSE = false;
+    public HEIGHTMAP = false;
+    public CLIPPLANE = false;
+    public CLIPPLANE2 = false;
+    public CLIPPLANE3 = false;
+    public CLIPPLANE4 = false;
+    public CLIPPLANE5 = false;
+    public CLIPPLANE6 = false;
+    public ALPHATEST = false;
+    public DEPTHPREPASS = false;
+    public POINTSIZE = false;
+    public FOG = false;
+    public NORMAL = false;
+    public UV1 = false;
+    public UV2 = false;
+    public VERTEXCOLOR = false;
+    public VERTEXALPHA = false;
+    public NUM_BONE_INFLUENCERS = 0;
+    public BonesPerMesh = 0;
+    public INSTANCES = false;
+    public HIGHLEVEL = false;
+    constructor() {
+        super();
+        this.rebuild();
+    }
+}
 
-export class BoneWeightsMaterial extends ShaderMaterial{   
 
+export class BoneWeightsMaterial extends PushMaterial{
+    @serialize('skeleton')
     public skeleton: Skeleton;
+    @serializeAsColor3('colorBase')
     public colorBase: Color3;
+    @serializeAsColor3('colorZero')
     public colorZero: Color3;
+    @serializeAsColor3('colorQuarter')
     public colorQuarter: Color3;
+    @serializeAsColor3('colorHalf')
     public colorHalf: Color3;
+    @serializeAsColor3('colorFull')
     public colorFull: Color3;
+    @serialize('targetBoneIndex')
     public targetBoneIndex: number; 
-    private _shader: ShaderMaterial;
-
-    get shader(){
-        return this._shader
-    }
    
     constructor(name: string, options:IBoneWeightsMaterialOptions, scene: Scene) {
-        super(name, scene,
-            {
-            vertexSource:
-            `precision highp float;
-
-            attribute vec3 position;
-            attribute vec2 uv;
-
-            uniform mat4 view;
-            uniform mat4 projection;
-            uniform mat4 worldViewProjection;
-
-            #include<bonesDeclaration>
-            #include<instancesDeclaration>
-
-            varying vec3 vColor;
-
-            uniform vec3 colorBase;
-            uniform vec3 colorZero;
-            uniform vec3 colorQuarter;
-            uniform vec3 colorHalf;
-            uniform vec3 colorFull;
-
-            uniform float targetBoneIndex;
-
-            void main() {
-                vec3 positionUpdated = position;
-
-                #include<instancesVertex>
-                #include<bonesVertex>
-
-                vec4 worldPos = finalWorld * vec4(positionUpdated, 1.0);
-
-                vec3 color = colorBase;
-                float totalWeight = 0.;
-                if(matricesIndices[0] == targetBoneIndex && matricesWeights[0] > 0.){
-                    totalWeight += matricesWeights[0];
-                }
-                if(matricesIndices[1] == targetBoneIndex && matricesWeights[1] > 0.){
-                    totalWeight += matricesWeights[1];
-                }
-                if(matricesIndices[2] == targetBoneIndex && matricesWeights[2] > 0.){
-                    totalWeight += matricesWeights[2];
-                }
-                if(matricesIndices[3] == targetBoneIndex && matricesWeights[3] > 0.){
-                    totalWeight += matricesWeights[3];
-                }
-
-                color = mix(color, colorZero, smoothstep(0., 0.25, totalWeight));
-                color = mix(color, colorQuarter, smoothstep(0.25, 0.5, totalWeight));
-                color = mix(color, colorHalf, smoothstep(0.5, 0.75, totalWeight));
-                color = mix(color, colorFull, smoothstep(0.75, 1.0, totalWeight));
-
-
-                gl_Position = projection * view * worldPos;
-            }`,
-            fragmentSource:
-            `
-            precision highp float;
-            varying vec3 vPosition;
-
-            varying vec3 vColor;
-
-            void main() {
-                vec4 color = vec4(vColor, 1.0);
-                gl_FragColor = color;
-            }
-            `
-        },
-        {
-            attributes: ['position', 'normal'],
-            uniforms: [
-                'world', 'worldView', 'worldViewProjection', 'view', 'projection', 'viewProjection',
-                'colorBase', 'colorZero', 'colorQuarter', 'colorHalf', 'colorFull', 'targetBoneIndex'
-            ]
-        })
+        super(name, scene);
         this.skeleton = options.skeleton;
         this.colorBase = options.colorBase ?? Color3.Black();
         this.colorZero = options.colorZero ?? Color3.Blue();
         this.colorQuarter = options.colorQuarter ?? Color3.Green();
         this.colorHalf = options.colorHalf ?? Color3.Yellow();
         this.colorFull = options.colorFull ?? Color3.Red();
-        this.targetBoneIndex = options.targetBoneIndex ?? 0;        
-
-        this.setColor3('colorBase', this.colorBase);
-        this.setColor3('colorZero', this.colorZero);
-        this.setColor3('colorQuarter', this.colorQuarter);
-        this.setColor3('colorHalf', this.colorHalf);
-        this.setColor3('colorFull', this.colorFull);
-        this.setFloat('targetBoneIndex', this.targetBoneIndex);
-        this.transparencyMode = Material.MATERIAL_OPAQUE;
+        this.targetBoneIndex = options.targetBoneIndex ?? 0;
+    }
+
+    public needAlphaBlending(): boolean {
+        return false;
+    }
+
+    public needAlphaTesting(): boolean {
+        return false;
+    }
+
+    public getAlphaTestTexture(): Nullable<BaseTexture> {
+        return null;
+    }
+
+  // Methods
+  public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+    if (this.isFrozen) {
+        if (subMesh.effect && subMesh.effect._wasPreviouslyReady) {
+            return true;
+        }
+    }
+
+    if (!subMesh._materialDefines) {
+        subMesh._materialDefines = new BoneWeightsMaterialDefines();
+    }
+
+    var defines = <BoneWeightsMaterialDefines>subMesh._materialDefines;
+    var scene = this.getScene();
+
+    if (this._isReadyForSubMesh(subMesh)) {
+        return true;
+    }
+
+    var engine = scene.getEngine();
+
+    // Misc.
+    MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
+
+    // Lights
+    //defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, 0, true);
+
+    // Values that need to be evaluated on every frame
+    MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+
+    // Attribs
+    MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
+    //console.log(defines)
+
+    // Get correct effect
+    if (defines.isDirty) {
+        defines.markAsProcessed();
+        scene.resetCachedMaterial();
+
+        // Fallbacks
+        var fallbacks = new EffectFallbacks(); 
+        if (defines.FOG) {
+            fallbacks.addFallback(1, "FOG");
+        }  
+
+        MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, 0);
+
+        if (defines.NUM_BONE_INFLUENCERS > 0) {
+            fallbacks.addCPUSkinningFallback(0, mesh);
+        }
+
+        //Attributes
+        var attribs = [VertexBuffer.PositionKind];
+
+        if (defines.NORMAL) {
+            attribs.push(VertexBuffer.NormalKind);
+        } 
+
+        MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+        //console.log(attribs)
+        MaterialHelper.PrepareAttributesForInstances(attribs, defines);
+
+        var shaderName = "boneWeights";
+        var join = defines.toString();
+        var uniforms = ["world", "view", "viewProjection", 'projection', 'viewProjection',
+            'colorBase', 'colorZero', 'colorQuarter', 'colorHalf', 'colorFull', 'targetBoneIndex'           
+        ];
+        var samplers:string[] = [];
+        var uniformBuffers = new Array<string>();
+
+        MaterialHelper.PrepareUniformsAndSamplersList(<IEffectCreationOptions>{
+            uniformsNames: uniforms,
+            uniformBuffersNames: uniformBuffers,
+            samplers: samplers,
+            defines: defines,
+            maxSimultaneousLights: 0
+        });
+        console.log(uniforms)
+        let effect = scene.getEngine().createEffect(shaderName,
+            <IEffectCreationOptions>{
+                attributes: attribs,
+                uniformsNames: uniforms,
+                uniformBuffersNames: uniformBuffers,
+                samplers: samplers,
+                defines: join,
+                fallbacks: fallbacks,
+                onCompiled: this.onCompiled,
+                onError: this.onError,
+                indexParameters: { maxSimultaneousLights: 0 }
+            }, engine);
+        
+        effect.onBindObservable.add(()=>{
+            effect.setColor3('colorBase', this.colorBase);
+            effect.setColor3('colorZero', this.colorZero);
+            effect.setColor3('colorQuarter', this.colorQuarter);
+            effect.setColor3('colorHalf', this.colorHalf);
+            effect.setColor3('colorFull', this.colorFull);
+            effect.setFloat('targetBoneIndex', this.targetBoneIndex);
+            //subMesh.transparencyMode = Material.MATERIAL_OPAQUE;
+        })
+        subMesh.setEffect(effect, defines);
+
+    }
+    if (!subMesh.effect || !subMesh.effect.isReady()) {
+        return false;
+    }
+
+    defines._renderId = scene.getRenderId();
+    subMesh.effect._wasPreviouslyReady = true;
+
+    return true;
+}
+
+public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+    var scene = this.getScene();
+
+    var defines = <BoneWeightsMaterialDefines>subMesh._materialDefines;
+    if (!defines) {
+        return;
     }
 
-    public dispose(): void {
-        this.shader.dispose()
+    var effect = subMesh.effect;
+    if (!effect) {
+        return;
     }
+    this._activeEffect = effect;
+
+    // Matrices
+    this.bindOnlyWorldMatrix(world);
+    this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
 
-    public getClassName(): string {
-        return "BoneWeightsMaterial";
+    // Bones
+    MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
+
+    if (this._mustRebind(scene, effect)) {
+        MaterialHelper.BindEyePosition(effect, scene);
     }
+  
+    this._afterBind(mesh, this._activeEffect);
+}
+
+public getAnimatables(): IAnimatable[] {
+    return []
+}
+
+public getActiveTextures(): BaseTexture[] {
+    return []
+}
+
+public hasTexture(texture: BaseTexture): boolean {
+    return false;    
+}
+
+public dispose(forceDisposeEffect?: boolean): void {
+    super.dispose(forceDisposeEffect);
+}
+
+public getClassName(): string {
+    return "BoneWeightsMaterial";
+}
+
+public clone(name: string): BoneWeightsMaterial {
+    return SerializationHelper.Clone<BoneWeightsMaterial>(() => new BoneWeightsMaterial(name, {
+        skeleton:this.skeleton,
+        colorBase:this.colorBase,
+        colorZero:this.colorZero,
+        colorQuarter:this.colorQuarter,
+        colorHalf:this.colorHalf,
+        colorFull:this.colorFull
+    }, this.getScene()), this);
+}
+
+public serialize(): any {
+    var serializationObject = SerializationHelper.Serialize(this);
+    serializationObject.customType = "BABYLON.BoneWeightsMaterial";
+    return serializationObject;
+}
+
+// Statics
+public static Parse(source: any, scene: Scene, rootUrl: string): BoneWeightsMaterial {
+    return SerializationHelper.Parse(() => new BoneWeightsMaterial(source.name, {
+        skeleton:source.skeleton,
+        colorBase:source.colorBase,
+        colorZero:source.colorZero,
+        colorQuarter:source.colorQuarter,
+        colorHalf:source.colorHalf,
+        colorFull:source.colorFull
+    }, scene), source, scene, rootUrl);
+}
 
 }