travnik
travnik

Reputation: 730

Material does not display properly when loading json model in Three.js r69

Exporting model from Blender in json format using Three.js plugin. Loading it using JSONLoader, standard things with:

  var loader = new THREE.JSONLoader();
  loader.load(path, function (geometry, materials) {
  materials.forEach(function (material) {
       material.skinning = true;
  });
  var material = new THREE.MeshFaceMaterial(materials);
  var mesh = new THREE.SkinnedMesh(geometry, material);

now the problem manifests itself in model not being displayed at all. If i change the material:

  var loader = new THREE.JSONLoader();
  loader.load(path, function (geometry, materials) {
  materials.forEach(function (material) {
       material.skinning = true;
  });
  var material = new THREE.MeshLambertMaterial();
  var mesh = new THREE.SkinnedMesh(geometry, material);

things work, and mesh is displayed as intended.

here's the contents of JSON file with uvs,vertices, faces and normals omitted:

{

    "metadata": {
        "formatVersion" : 3.1,
        "generatedBy"   : "Blender 2.7 Exporter",
        "vertices"      : 774,
        "faces"         : 691,
        "normals"       : 751,
        "colors"        : 0,
        "uvs"           : [404],
        "materials"     : 2,
        "morphTargets"  : 0,
        "bones"         : 0
    },

        "scale" : 1.000000,

        "vertices" : ...,
        "faces"    : ...,
        "uvs"      : ...,
        "normals"  : ...,
        "skinIndices"  : [],
        "skinWeights"  : [],
        "morphTargets" : [],

        "bones"      : [],
        "animations" : [],

        "colors"    : [],
        "materials" : [
            {
                "DbgColor": 15658734,
                "DbgIndex": 0,
                "DbgName": "Crystal",
                "blending": "NormalBlending",
                "colorAmbient": [0.800000011920929, 0.800000011920929, 0.800000011920929],
                "colorDiffuse": [0.800000011920929, 0.800000011920929, 0.800000011920929],
                "colorEmissive": [0.0, 0.0, 0.0],
                "colorSpecular": [0.25, 0.25, 0.25],
                "depthTest": true,
                "depthWrite": true,
                "mapDiffuse": "Cristal_C_CM.png",
                "mapDiffuseWrap": ["repeat", "repeat"],
                "shading": "Lambert",
                "specularCoef": 33,
                "transparency": 1.0,
                "transparent": false,
                "vertexColors": false
            },
            {
                "DbgColor": 15597568,
                "DbgIndex": 1,
                "DbgName": "tower",
                "blending": "NormalBlending",
                "colorAmbient": [0.800000011920929, 0.800000011920929, 0.800000011920929],
                "colorDiffuse": [0.800000011920929, 0.800000011920929, 0.800000011920929],
                "colorEmissive": [0.0, 0.0, 0.0],
                "colorSpecular": [0.4180000126361847, 0.31944116950035095, 0.1504800170660019],
                "depthTest": true,
                "depthWrite": true,
                "mapDiffuse": "rock_CM_01.png",
                "mapDiffuseWrap": ["repeat", "repeat"],
                "mapNormal": "rock_NM_02.png",
                "mapNormalFactor": 0.3500420153141022,
                "mapNormalWrap": ["repeat", "repeat"],
                "shading": "Phong",
                "specularCoef": 511,
                "transparency": 1.0,
                "transparent": false,
                "vertexColors": false
            }
        ]


}

any ideas would be much appreciated.

Upvotes: 1

Views: 830

Answers (1)

travnik
travnik

Reputation: 730

Turns out the problem is in setting

material.skinning = true;

removing this line model is properly displayed. This looks like a bug.

for anyone who runs into the same problem, there are 2 simple ways to solve it: - use different code for loading skinned/static assets - use a piece of code which generates different materials and mesh types based on what's loaded.

for second, here's a snippet i use:

        assetManager.registerLoader("three.js", function (path, callback) {
            var loader = new THREE.JSONLoader();
            loader.load(path, function (geometry, materials) {
                //is it skinned?
                var isSkinned = geometry.skinIndices !== void 0 && geometry.skinIndices.length > 0;
                if (isSkinned) {
                    materials.forEach(function (material) {
                        material.skinning = true;
                    });
                }
                var faceMaterial = new THREE.MeshFaceMaterial(materials);
                var asset = {
                    material: faceMaterial,
                    geometry: geometry,
                    create: function () {
                        var mesh;
                        if (isSkinned) {
                            mesh = new THREE.SkinnedMesh(geometry, faceMaterial);
                        } else {
                            mesh = new THREE.Mesh(geometry, faceMaterial);
                        }
                        mesh.castShadow = true;
                        mesh.receiveShadow = false;
                        //
                        return mesh;
                    }
                };
                callback(asset);
            });
        });

Upvotes: 0

Related Questions