Selaa lähdekoodia

Fixed shaders support for glTFFileLoader

luaacro 10 vuotta sitten
vanhempi
commit
656b10d3b0

+ 0 - 2
loaders/glTF/README.md

@@ -35,8 +35,6 @@ BABYLON.SceneLoader.Load("./", "duck.gltf", engine, function (scene) {
     * Skeletons
     * Bones
     * Hardware skinning (shaders support)
-* Shaders
-    * Set uniforms with types MAT2 and MAT3
 * Handle dummy nodes (empty nodes)
 
 ## To improve

+ 109 - 66
loaders/glTF/babylon.glTFFileLoader.js

@@ -55,6 +55,14 @@ var BABYLON;
         ETextureFilterType[ETextureFilterType["LINEAR_MIPMAP_LINEAR"] = 9987] = "LINEAR_MIPMAP_LINEAR";
     })(BABYLON.ETextureFilterType || (BABYLON.ETextureFilterType = {}));
     var ETextureFilterType = BABYLON.ETextureFilterType;
+    (function (ETextureFormat) {
+        ETextureFormat[ETextureFormat["ALPHA"] = 6406] = "ALPHA";
+        ETextureFormat[ETextureFormat["RGB"] = 6407] = "RGB";
+        ETextureFormat[ETextureFormat["RGBA"] = 6408] = "RGBA";
+        ETextureFormat[ETextureFormat["LUMINANCE"] = 6409] = "LUMINANCE";
+        ETextureFormat[ETextureFormat["LUMINANCE_ALPHA"] = 6410] = "LUMINANCE_ALPHA";
+    })(BABYLON.ETextureFormat || (BABYLON.ETextureFormat = {}));
+    var ETextureFormat = BABYLON.ETextureFormat;
     /**
     * Tokenizer. Used for shaders compatibility
     * Automatically map world, view, projection, worldViewProjection and attributes
@@ -106,8 +114,8 @@ var BABYLON;
     */
     var glTFTransforms = ["MODEL", "VIEW", "PROJECTION", "MODELVIEW", "MODELVIEWPROJECTION", "JOINTMATRIX"];
     var babylonTransforms = ["world", "view", "projection", "worldView", "worldViewProjection", "mBones"];
-    var glTFAnimationPaths = ["translation", "scale"];
-    var babylonAnimationPaths = ["position", "scaling"];
+    var glTFAnimationPaths = ["translation", "rotation", "scale"];
+    var babylonAnimationPaths = ["position", "rotationQuaternion", "scaling"];
     /**
     * Parse
     */
@@ -192,6 +200,23 @@ var BABYLON;
             default: break;
         }
     };
+    var setUniform = function (shaderMaterial, uniform, value, type) {
+        switch (type) {
+            case EParameterType.FLOAT:
+                shaderMaterial.setFloat(uniform, value);
+                return true;
+            case EParameterType.FLOAT_VEC2:
+                shaderMaterial.setVector2(uniform, BABYLON.Vector2.FromArray(value));
+                return true;
+            case EParameterType.FLOAT_VEC3:
+                shaderMaterial.setVector3(uniform, BABYLON.Vector3.FromArray(value));
+                return true;
+            case EParameterType.FLOAT_VEC4:
+                shaderMaterial.setVector4(uniform, BABYLON.Vector4.FromArray(value));
+                return true;
+            default: return false;
+        }
+    };
     var getWrapMode = function (mode) {
         switch (mode) {
             case ETextureWrapMode.CLAMP_TO_EDGE: return BABYLON.Texture.CLAMP_ADDRESSMODE;
@@ -260,6 +285,15 @@ var BABYLON;
     var isBase64 = function (uri) {
         return uri.length < 5 ? false : uri.substr(0, 5) === "data:";
     };
+    var getTextureFromName = function (gltfRuntime, name) {
+        var textures = gltfRuntime.scene.textures;
+        for (var i = 0; i < textures.length; i++) {
+            if (textures[i].name === name) {
+                return textures[i];
+            }
+        }
+        return null;
+    };
     /**
     * Load animations
     */
@@ -300,21 +334,26 @@ var BABYLON;
                     targetPath = babylonAnimationPaths[targetPathIndex];
                 }
                 // Create key frames and animation
-                var babylonAnimation = new BABYLON.Animation(anim, targetPath, 1, BABYLON.Animation.ANIMATIONTYPE_VECTOR3, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
+                var animationType = BABYLON.Animation.ANIMATIONTYPE_VECTOR3;
+                if (targetPath === "rotationQuaternion") {
+                    animationType = BABYLON.Animation.ANIMATIONTYPE_QUATERNION;
+                    targetNode.rotationQuaternion = new BABYLON.Quaternion();
+                }
+                var babylonAnimation = new BABYLON.Animation(anim, targetPath, 1, animationType, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
                 var keys = [];
                 for (var i = 0; i < bufferInput.length; i++) {
-                    var vector = null;
-                    if (targetPath === "rotation") {
-                        vector = BABYLON.Vector3.FromArray([bufferOutput[i * 4 + 3], bufferOutput[i * 4 + 1], bufferOutput[i * 4 + 2]]);
+                    var value = null;
+                    if (targetPath === "rotationQuaternion") {
+                        value = BABYLON.Quaternion.RotationAxis(BABYLON.Vector3.FromArray([bufferOutput[i * 4], bufferOutput[i * 4 + 1], bufferOutput[i * 4 + 2]]).normalize(), bufferOutput[i * 4 + 3]);
                     }
                     else {
-                        vector = BABYLON.Vector3.FromArray([bufferOutput[i * 3], bufferOutput[i * 3 + 1], bufferOutput[i * 3 + 2]]);
+                        value = BABYLON.Vector3.FromArray([bufferOutput[i * 3], bufferOutput[i * 3 + 1], bufferOutput[i * 3 + 2]]);
                         // Y is up
-                        vector.z *= -1;
+                        value.z *= -1;
                     }
                     keys.push({
                         frame: bufferInput[i],
-                        value: vector
+                        value: value
                     });
                 }
                 // Finish
@@ -379,7 +418,6 @@ var BABYLON;
                 accessor = gltfRuntime.accessors[attributes[semantic]];
                 buffer = getBufferFromAccessor(gltfRuntime, accessor);
                 if (semantic === "NORMAL") {
-                    //normalizeBuffer(buffer);
                     tempVertexData.set(buffer, BABYLON.VertexBuffer.NormalKind);
                 }
                 else if (semantic === "POSITION") {
@@ -394,11 +432,9 @@ var BABYLON;
                     tempVertexData.set(buffer, uvKind);
                 }
                 else if (semantic === "JOINT") {
-                    //normalizeBuffer(buffer);
                     tempVertexData.set(buffer, BABYLON.VertexBuffer.MatricesIndicesKind);
                 }
                 else if (semantic === "WEIGHT") {
-                    //normalizeBuffer(buffer);
                     tempVertexData.set(buffer, BABYLON.VertexBuffer.MatricesWeightsKind);
                 }
             }
@@ -413,8 +449,8 @@ var BABYLON;
             var material = gltfRuntime.scene.getMaterialByID(primitive.material);
             multiMat.subMaterials.push(material === null ? gltfRuntime.scene.defaultMaterial : material);
             // Update vertices start and index start
-            verticesStarts.push(verticesStarts.length === 0 ? 0 : verticesStarts[verticesStarts.length - 1] + verticesCounts[verticesCounts.length - 1]);
-            indexStarts.push(indexStarts.length === 0 ? 0 : indexStarts[indexStarts.length - 1] + indexCounts[indexCounts.length - 1]);
+            verticesStarts.push(verticesStarts.length === 0 ? 0 : verticesStarts[verticesStarts.length - 1] + verticesCounts[verticesCounts.length - 2]);
+            indexStarts.push(indexStarts.length === 0 ? 0 : indexStarts[indexStarts.length - 1] + indexCounts[indexCounts.length - 2]);
         }
         // Apply geometry
         geometry.setAllVerticesData(vertexData);
@@ -659,22 +695,40 @@ var BABYLON;
     /**
     * Load shaders
     */
-    var onBindShaderMaterial = function (mesh, gltfRuntime, unTreatedUniforms, shaderMaterial) {
+    var onBindShaderMaterial = function (mesh, gltfRuntime, unTreatedUniforms, shaderMaterial, pass, material) {
         for (var unif in unTreatedUniforms) {
             var uniform = unTreatedUniforms[unif];
             var type = uniform.type;
-            if (uniform.semantic && !uniform.source && !uniform.node) {
-                setMatrix(gltfRuntime.scene, mesh, uniform, unif, shaderMaterial);
-            }
-            else if (uniform.semantic && (uniform.source || uniform.node)) {
-                var source = gltfRuntime.scene.getNodeByName(uniform.source || uniform.node);
-                if (source === null) {
-                    source = gltfRuntime.scene.getNodeByID(uniform.source || uniform.node);
+            if (type === EParameterType.FLOAT_MAT2 || type === EParameterType.FLOAT_MAT3 || type === EParameterType.FLOAT_MAT4) {
+                if (uniform.semantic && !uniform.source && !uniform.node) {
+                    setMatrix(gltfRuntime.scene, mesh, uniform, unif, shaderMaterial.getEffect());
                 }
-                if (source === null) {
+                else if (uniform.semantic && (uniform.source || uniform.node)) {
+                    var source = gltfRuntime.scene.getNodeByName(uniform.source || uniform.node);
+                    if (source === null) {
+                        source = gltfRuntime.scene.getNodeByID(uniform.source || uniform.node);
+                    }
+                    if (source === null) {
+                        continue;
+                    }
+                    setMatrix(gltfRuntime.scene, source, uniform, unif, shaderMaterial.getEffect());
+                }
+            }
+            else {
+                var value = material.instanceTechnique.values[pass.instanceProgram.uniforms[unif]];
+                if (!value) {
                     continue;
                 }
-                setMatrix(gltfRuntime.scene, source, uniform, unif, shaderMaterial);
+                if (type === EParameterType.SAMPLER_2D) {
+                    var texture = getTextureFromName(gltfRuntime, value);
+                    if (texture === null) {
+                        continue;
+                    }
+                    shaderMaterial.getEffect().setTexture(unif, texture);
+                }
+                else {
+                    setUniform(shaderMaterial.getEffect(), unif, value, type);
+                }
             }
         }
     };
@@ -688,48 +742,38 @@ var BABYLON;
             var uniform = unTreatedUniforms[unif];
             var type = uniform.type;
             var value = materialValues[instanceProgramUniforms[unif]] || uniform.value;
-            if (value) {
-                // Texture (sampler2D)
-                if (type === EParameterType.SAMPLER_2D) {
-                    var texture = gltfRuntime.textures[value];
-                    var sampler = gltfRuntime.samplers[texture.sampler];
-                    if (texture && texture.source) {
-                        var source = gltfRuntime.images[texture.source];
-                        var newTexture = null;
-                        if (isBase64(source.uri)) {
-                            newTexture = BABYLON.Texture.CreateFromBase64String(source.uri, gltfRuntime.rootUrl + source.name, gltfRuntime.scene);
-                        }
-                        else {
-                            newTexture = new BABYLON.Texture(gltfRuntime.rootUrl + source.uri, gltfRuntime.scene);
-                        }
-                        if (sampler) {
-                            newTexture.wrapU = getWrapMode(sampler.wrapS);
-                            newTexture.wrapV = getWrapMode(sampler.wrapT);
-                        }
-                        shaderMaterial.setTexture(unif, newTexture);
-                        delete unTreatedUniforms[unif];
-                    }
+            if (!value) {
+                continue;
+            }
+            // Texture (sampler2D)
+            if (type === EParameterType.SAMPLER_2D) {
+                var texture = gltfRuntime.textures[value];
+                var sampler = gltfRuntime.samplers[texture.sampler];
+                if (!texture || !texture.source) {
+                    continue;
+                }
+                var source = gltfRuntime.images[texture.source];
+                var newTexture = null;
+                if (isBase64(source.uri)) {
+                    newTexture = new BABYLON.Texture(source.uri, gltfRuntime.scene, true, undefined, undefined, undefined, undefined, source.uri, true);
                 }
                 else {
-                    switch (type) {
-                        case EParameterType.FLOAT:
-                            shaderMaterial.setFloat(unif, value);
-                            delete unTreatedUniforms[unif];
-                            break;
-                        case EParameterType.FLOAT_VEC2:
-                            shaderMaterial.setVector2(unif, BABYLON.Vector2.FromArray(value));
-                            delete unTreatedUniforms[unif];
-                            break;
-                        case EParameterType.FLOAT_VEC3:
-                            shaderMaterial.setVector3(unif, BABYLON.Vector3.FromArray(value));
-                            delete unTreatedUniforms[unif];
-                            break;
-                        case EParameterType.FLOAT_VEC4:
-                            shaderMaterial.setVector4(unif, BABYLON.Vector4.FromArray(value));
-                            delete unTreatedUniforms[unif];
-                            break;
-                        default: break;
-                    }
+                    newTexture = new BABYLON.Texture(gltfRuntime.rootUrl + source.uri, gltfRuntime.scene, true);
+                }
+                newTexture.name = value;
+                if (texture.internalFormat && (texture.internalFormat === ETextureFormat.ALPHA || texture.internalFormat === ETextureFormat.RGBA)) {
+                    newTexture.hasAlpha = true;
+                }
+                if (uniform.value) {
+                    // Static uniform
+                    shaderMaterial.setTexture(unif, newTexture);
+                    delete unTreatedUniforms[unif];
+                }
+            }
+            else {
+                if (uniform.value && setUniform(shaderMaterial, unif, value, type)) {
+                    // Static uniform
+                    delete unTreatedUniforms[unif];
                 }
             }
         }
@@ -744,12 +788,11 @@ var BABYLON;
         return function (_) {
             prepareShaderMaterialUniforms(gltfRuntime, shaderMaterial, pass, material, unTreatedUniforms);
             shaderMaterial.onBind = function (mat, mesh) {
-                onBindShaderMaterial(mesh, gltfRuntime, unTreatedUniforms, shaderMaterial);
+                onBindShaderMaterial(mesh, gltfRuntime, unTreatedUniforms, shaderMaterial, pass, material);
             };
         };
     };
     var parseShaderUniforms = function (tokenizer, instanceProgram, technique, unTreatedUniforms) {
-        var foundUniform = false;
         for (var unif in instanceProgram.uniforms) {
             var uniform = instanceProgram.uniforms[unif];
             var uniformParameter = technique.parameters[uniform];

+ 119 - 61
loaders/glTF/babylon.glTFFileLoader.ts

@@ -54,6 +54,14 @@
         LINEAR_MIPMAP_LINEAR = 9987
     }
 
+    export enum ETextureFormat {
+        ALPHA = 6406,
+        RGB = 6407,
+        RGBA = 6408,
+        LUMINANCE = 6409,
+        LUMINANCE_ALPHA = 6410 
+    }
+
     /**
     * Tokenizer. Used for shaders compatibility
     * Automatically map world, view, projection, worldViewProjection and attributes
@@ -121,8 +129,8 @@
     var glTFTransforms =    ["MODEL", "VIEW", "PROJECTION", "MODELVIEW", "MODELVIEWPROJECTION", "JOINTMATRIX"];
     var babylonTransforms = ["world", "view", "projection", "worldView", "worldViewProjection", "mBones"];
 
-    var glTFAnimationPaths =    ["translation", "scale"];
-    var babylonAnimationPaths = ["position",    "scaling"];
+    var glTFAnimationPaths =    ["translation", "rotation",           "scale"];
+    var babylonAnimationPaths = ["position",    "rotationQuaternion", "scaling"];
 
     /**
     * Parse
@@ -168,7 +176,7 @@
         }
     };
 
-    var setMatrix = (scene: Scene, source: Node, parameter: IGLTFTechniqueParameter, uniformName: string, shaderMaterial: ShaderMaterial) => {
+    var setMatrix = (scene: Scene, source: Node, parameter: IGLTFTechniqueParameter, uniformName: string, shaderMaterial: any) => {
         var mat: Matrix = null;
 
         if (parameter.semantic === "MODEL") {
@@ -210,6 +218,16 @@
         }
     };
 
+    var setUniform = (shaderMaterial: any, uniform: string, value: any, type: number): boolean => {
+        switch (type) {
+            case EParameterType.FLOAT: shaderMaterial.setFloat(uniform, value); return true;
+            case EParameterType.FLOAT_VEC2: shaderMaterial.setVector2(uniform, Vector2.FromArray(value)); return true;
+            case EParameterType.FLOAT_VEC3: shaderMaterial.setVector3(uniform, Vector3.FromArray(value)); return true;
+            case EParameterType.FLOAT_VEC4: shaderMaterial.setVector4(uniform, Vector4.FromArray(value)); return true;
+            default: return false;
+        }
+    };
+
     var getWrapMode = (mode: number): ETextureWrapMode => {
         switch (mode) {
             case ETextureWrapMode.CLAMP_TO_EDGE: return Texture.CLAMP_ADDRESSMODE;
@@ -289,6 +307,18 @@
         return uri.length < 5 ? false : uri.substr(0, 5) === "data:";
     };
 
+    var getTextureFromName = (gltfRuntime: IGLTFRuntime, name: string): BaseTexture => {
+        var textures = gltfRuntime.scene.textures;
+
+        for (var i = 0; i < textures.length; i++) {
+            if (textures[i].name === name) {
+                return textures[i];
+            }
+        }
+
+        return null;
+    };
+
     /**
     * Load animations
     */
@@ -322,7 +352,7 @@
                 var bufferOutput = getBufferFromAccessor(gltfRuntime, gltfRuntime.accessors[outputData]);
 
                 var targetID = channel.target.id;
-                var targetNode = gltfRuntime.scene.getNodeByID(targetID);
+                var targetNode: any = gltfRuntime.scene.getNodeByID(targetID);
 
                 if (targetNode === null) {
                     targetNode = gltfRuntime.scene.getNodeByName(targetID);
@@ -341,23 +371,30 @@
                 }
 
                 // Create key frames and animation
-                var babylonAnimation = new Animation(anim, targetPath, 1, Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CYCLE);
+                var animationType = Animation.ANIMATIONTYPE_VECTOR3;
+                if (targetPath === "rotationQuaternion") {
+                    animationType = Animation.ANIMATIONTYPE_QUATERNION;
+                    targetNode.rotationQuaternion = new Quaternion();
+                }
+
+                var babylonAnimation = new Animation(anim, targetPath, 1, animationType, Animation.ANIMATIONLOOPMODE_CYCLE);
                 var keys = [];
 
                 for (var i = 0; i < bufferInput.length; i++) {
-                    var vector: Vector3 = null;
-                    if (targetPath === "rotation") { // VEC4
-                        vector = Vector3.FromArray([bufferOutput[i * 4 + 3], bufferOutput[i * 4 + 1], bufferOutput[i * 4 + 2]]);
+                    var value: any = null;
+
+                    if (targetPath === "rotationQuaternion") { // VEC4
+                        value = Quaternion.RotationAxis(Vector3.FromArray([bufferOutput[i * 4], bufferOutput[i * 4 + 1], bufferOutput[i * 4 + 2]]).normalize(), bufferOutput[i * 4 + 3]);
                     }
                     else { // Position and scaling are VEC3
-                        vector = Vector3.FromArray([bufferOutput[i * 3], bufferOutput[i * 3 + 1], bufferOutput[i * 3 + 2]]);
+                        value = Vector3.FromArray([bufferOutput[i * 3], bufferOutput[i * 3 + 1], bufferOutput[i * 3 + 2]]);
                         // Y is up
-                        vector.z *= -1;
+                        value.z *= -1;
                     }
 
                     keys.push({
                         frame: bufferInput[i],
-                        value: vector
+                        value: value
                     });
                 }
                 
@@ -441,7 +478,6 @@
                 buffer = getBufferFromAccessor(gltfRuntime, accessor);
 
                 if (semantic === "NORMAL") {
-                    //normalizeBuffer(buffer);
                     tempVertexData.set(buffer, VertexBuffer.NormalKind);
                 }
                 else if (semantic === "POSITION") {
@@ -456,11 +492,9 @@
                     tempVertexData.set(buffer, uvKind);
                 }
                 else if (semantic === "JOINT") {
-                    //normalizeBuffer(buffer);
                     tempVertexData.set(buffer, VertexBuffer.MatricesIndicesKind);
                 }
                 else if (semantic === "WEIGHT") {
-                    //normalizeBuffer(buffer);
                     tempVertexData.set(buffer, VertexBuffer.MatricesWeightsKind);
                 }
             }
@@ -479,8 +513,8 @@
             multiMat.subMaterials.push(material === null ? gltfRuntime.scene.defaultMaterial : material);
 
             // Update vertices start and index start
-            verticesStarts.push(verticesStarts.length === 0 ? 0 : verticesStarts[verticesStarts.length - 1] + verticesCounts[verticesCounts.length - 1]);
-            indexStarts.push(indexStarts.length === 0 ? 0 : indexStarts[indexStarts.length - 1] + indexCounts[indexCounts.length - 1]);
+            verticesStarts.push(verticesStarts.length === 0 ? 0 : verticesStarts[verticesStarts.length - 1] + verticesCounts[verticesCounts.length - 2]);
+            indexStarts.push(indexStarts.length === 0 ? 0 : indexStarts[indexStarts.length - 1] + indexCounts[indexCounts.length - 2]);
         }
 
         // Apply geometry
@@ -783,24 +817,45 @@
     /**
     * Load shaders
     */
-    var onBindShaderMaterial = (mesh: Mesh, gltfRuntime: IGLTFRuntime, unTreatedUniforms: Object, shaderMaterial: ShaderMaterial) => {
+    var onBindShaderMaterial = (mesh: Mesh, gltfRuntime: IGLTFRuntime, unTreatedUniforms: Object, shaderMaterial: ShaderMaterial, pass: IGLTFTechniquePass, material: IGLTFMaterial) => {
         for (var unif in unTreatedUniforms) {
             var uniform: IGLTFTechniqueParameter = unTreatedUniforms[unif];
             var type = uniform.type;
 
-            if (uniform.semantic && !uniform.source && !uniform.node) {
-                setMatrix(gltfRuntime.scene, mesh, uniform, unif, shaderMaterial);
-            }
-            else if (uniform.semantic && (uniform.source || uniform.node)) {
-                var source = gltfRuntime.scene.getNodeByName(uniform.source || uniform.node);
-                if (source === null) {
-                    source = gltfRuntime.scene.getNodeByID(uniform.source || uniform.node);
+            if (type === EParameterType.FLOAT_MAT2 || type === EParameterType.FLOAT_MAT3 || type === EParameterType.FLOAT_MAT4) {
+                if (uniform.semantic && !uniform.source && !uniform.node) {
+                    setMatrix(gltfRuntime.scene, mesh, uniform, unif, shaderMaterial.getEffect());
+                }
+                else if (uniform.semantic && (uniform.source || uniform.node)) {
+                    var source = gltfRuntime.scene.getNodeByName(uniform.source || uniform.node);
+                    if (source === null) {
+                        source = gltfRuntime.scene.getNodeByID(uniform.source || uniform.node);
+                    }
+                    if (source === null) {
+                        continue;
+                    }
+
+                    setMatrix(gltfRuntime.scene, source, uniform, unif, shaderMaterial.getEffect());
                 }
-                if (source === null) {
+            }
+            else {
+                var value = material.instanceTechnique.values[pass.instanceProgram.uniforms[unif]];
+                if (!value) {
                     continue;
                 }
 
-                setMatrix(gltfRuntime.scene, source, uniform, unif, shaderMaterial);
+                if (type === EParameterType.SAMPLER_2D) {
+                    var texture = getTextureFromName(gltfRuntime, value);
+
+                    if (texture === null) {
+                        continue;
+                    }
+
+                    shaderMaterial.getEffect().setTexture(unif, texture);
+                }
+                else {
+                    setUniform(shaderMaterial.getEffect(), unif, value, type);
+                }
             }
         }
     };
@@ -817,40 +872,45 @@
             var type = uniform.type;
             var value = materialValues[instanceProgramUniforms[unif]] || uniform.value;
 
-            if (value) {
-                // Texture (sampler2D)
-                if (type === EParameterType.SAMPLER_2D) {
-                    var texture: IGLTFTexture = gltfRuntime.textures[value];
-                    var sampler: IGLTFSampler = gltfRuntime.samplers[texture.sampler];
-
-                    if (texture && texture.source) {
-                        var source: IGLTFImage = gltfRuntime.images[texture.source];
-                        var newTexture = null;
-
-                        if (isBase64(source.uri)) {
-                            newTexture = Texture.CreateFromBase64String(source.uri, gltfRuntime.rootUrl + source.name, gltfRuntime.scene);
-                        }
-                        else {
-                            newTexture = new Texture(gltfRuntime.rootUrl + source.uri, gltfRuntime.scene);
-                        }
-                        if (sampler) {
-                            newTexture.wrapU = getWrapMode(sampler.wrapS);
-                            newTexture.wrapV = getWrapMode(sampler.wrapT);
-                        }
-
-                        shaderMaterial.setTexture(unif, newTexture);
-                        delete unTreatedUniforms[unif];
-                    }
+            if (!value) {
+                continue;
+            }
+
+            // Texture (sampler2D)
+            if (type === EParameterType.SAMPLER_2D) {
+                var texture: IGLTFTexture = gltfRuntime.textures[value];
+                var sampler: IGLTFSampler = gltfRuntime.samplers[texture.sampler];
+
+                if (!texture || !texture.source) {
+                    continue;
+                }
+
+                var source: IGLTFImage = gltfRuntime.images[texture.source];
+                var newTexture: Texture = null;
+
+                if (isBase64(source.uri)) {
+                    newTexture = new Texture(source.uri, gltfRuntime.scene, true, undefined, undefined, undefined, undefined, source.uri, true);
                 }
-                // Others
                 else {
-                    switch (type) {
-                        case EParameterType.FLOAT: shaderMaterial.setFloat(unif, value); delete unTreatedUniforms[unif]; break;
-                        case EParameterType.FLOAT_VEC2: shaderMaterial.setVector2(unif, Vector2.FromArray(value)); delete unTreatedUniforms[unif]; break;
-                        case EParameterType.FLOAT_VEC3: shaderMaterial.setVector3(unif, Vector3.FromArray(value)); delete unTreatedUniforms[unif]; break;
-                        case EParameterType.FLOAT_VEC4: shaderMaterial.setVector4(unif, Vector4.FromArray(value)); delete unTreatedUniforms[unif]; break;
-                        default: break;
-                    }
+                    newTexture = new Texture(gltfRuntime.rootUrl + source.uri, gltfRuntime.scene, true);
+                }
+                newTexture.name = value;
+
+                if (texture.internalFormat && (texture.internalFormat === ETextureFormat.ALPHA || texture.internalFormat === ETextureFormat.RGBA)) {
+                    newTexture.hasAlpha = true;
+                }
+
+                if (uniform.value) {
+                    // Static uniform
+                    shaderMaterial.setTexture(unif, newTexture);
+                    delete unTreatedUniforms[unif];
+                }
+            }
+            // Others
+            else {
+                if (uniform.value && setUniform(shaderMaterial, unif, value, type)) {
+                    // Static uniform
+                    delete unTreatedUniforms[unif];
                 }
             }
         }
@@ -868,14 +928,12 @@
             prepareShaderMaterialUniforms(gltfRuntime, shaderMaterial, pass, material, unTreatedUniforms);
 
             shaderMaterial.onBind = (mat: Material, mesh: Mesh) => {
-                onBindShaderMaterial(mesh, gltfRuntime, unTreatedUniforms, shaderMaterial);
+                onBindShaderMaterial(mesh, gltfRuntime, unTreatedUniforms, shaderMaterial, pass, material);
             };
         };
     };
 
     var parseShaderUniforms = (tokenizer: Tokenizer, instanceProgram: IGLTFTechniquePassInstanceProgram, technique: IGLTFTechnique, unTreatedUniforms: Object): string => {
-        var foundUniform = false;
-
         for (var unif in instanceProgram.uniforms) {
             var uniform = instanceProgram.uniforms[unif];
             var uniformParameter: IGLTFTechniqueParameter = technique.parameters[uniform];

+ 2 - 2
loaders/glTF/babylon.glTFFileLoaderInterfaces.ts

@@ -128,8 +128,8 @@
         sampler: string;
         source: string;
 
-        format?: number;
-        internalFormat?: number;
+        format?: ETextureFormat;
+        internalFormat?: ETextureFormat;
         target?: number;
         type?: number;
     }