Three.js: JSON Loader callback is fired before textures are mapped to model

Created on 3 Apr 2017  ·  15Comments  ·  Source: mrdoob/three.js

i am using JSONLoader to load 3d models to my scene .. then i stop the rendering loop to avoid cpu overhead while the scene is stand still,

the problem is when i stop the rendering loop the textures are not loaded yet so the model appear without texture,

i viewd some previous simillar issues and it led me to use LoadingManager with json loader and i stop the rendering loop in the LoadingManager callback not the JSONLoader but nothing changes

Three.js version r84

the problem happens with all browsers

i am using windows 7

code sample is attached with a screenshot

screenshot1

issue.txt

Loaders

Most helpful comment

I prefer to use JSONLoader too. Its more flexible for me.

@mahmoudsoliman As you know, load callback is only for JSON. But you can also detect texture loaded see: https://github.com/mrdoob/three.js/pull/10829 (still only in dev tho)

Plus, packing all assets in one zip file might be also helpful for you
https://yomotsu.github.io/ZipLoader/examples/Alicia.html

All 15 comments

I don't know about you, but I see it as a plus rather than a minus. You can always hook texture load status, or pre-load them. What you are reporting is a feature request and not a "problem".

@Usnul
i used the solution in #10287 and it works now when i used JSONLoader.parse instead of JSONLoader.load , i think what we need is a similar callback in JSONLoader.load

How come you're using JSONLoader? (Instead of ObjectLoader)

@mrdoob i tried to use ObjectLoader at first but it didn't work with me producing this error :
THREE.ObjectLoader: Can't load ../../robot.js. Use THREE.JSONLoader instead.
so i used JSONLoader , and that is what is used in most of the tutorials i have seen.

Do you know resp. did you try, which of the three conditions in ObjectLoader
(https://github.com/mrdoob/three.js/blob/master/src/loaders/ObjectLoader.js#L95-#L102)
causes this error?

How come you're using JSONLoader? (Instead of ObjectLoader)

@mrdoob I think the documentation is currently very unclear as to why these both exist and when to use each. It's something I intended to update when I was going over the docs, however I'm not sure myself the difference between these.

Currently the only thing the docs say about the difference, rather cryptically, is

Unlike the JSONLoader, this one (_ObjectLoader_) make use of the .type attributes of objects to map them to their original classes.

@jostschmithals i traced the error and i found that metadata.type is undefined
however, this is the metadata of my object as exported from 3dmax via threejs exporter :
"metadata":
{
"sourceFile": "robot.max",
"generatedBy": "3ds max ThreeJSExporter",
"formatVersion": 3.1,
"vertices": 2524,
"normals": 4598,
"colors": 0,
"uvs": 3418,
"triangles": 4598,
"materials": 1
},

@looeee I agree and had already similar thoughts; but there is one additional hint in the line after the one you quoted:

Note that this loader can't load Geometries. Use JSONLoader instead for that.

@mahmoudsoliman For comparison:

In this example a mesh is loaded with the ObjectLoader. (There are some bugs in this demo, but loading works fine). In this demo you can see that the model file contains two different metadata objects:

  • line 51554 metadata of the model (with type property)
"metadata":{
    "sourceFile":"marine_anims_core.blend",
    "generator":"io_three",
    "type":"Object",
    "version":4.4
}
  • line 51163 metadata of the model's geometry (without type property)
"metadata":{
    "uvs":1,
    "version":3,
    "faces":5704,
    "generator":"io_three",
    "normals":5736,
    "bones":57,
    "vertices":5736
}

@jostschmithals and is that a problem with my model or with the 3dmax exporter?
and is there a problem if i continued using JSONLoader the way i mentioned above?

Sorry - I can’t answer your questions directly (I am new to three.js and just learning all these things). I only wanted to give some hints for further considerations.

I prefer to use JSONLoader too. Its more flexible for me.

@mahmoudsoliman As you know, load callback is only for JSON. But you can also detect texture loaded see: https://github.com/mrdoob/three.js/pull/10829 (still only in dev tho)

Plus, packing all assets in one zip file might be also helpful for you
https://yomotsu.github.io/ZipLoader/examples/Alicia.html

@looeee wrote (concerning JSONLoader/ObjectLoader):

@mrdoob I think the documentation is currently very unclear as to why these both exist and when to use each. It's something I intended to update when I was going over the docs, however I'm not sure myself the difference between these.

@looeee In the meantime I have been digging in the source code because I wanted to understand completely how the different loaders/parsers (Objectloader, JSONLoader, BufferGeometryLoader, MaterialLoader, Loader, TextureLoader, ImageLoader, FileLoader) work together, and currently I am preparing an extra page for the docs explaining it (after I realized that several statements in the docs are rather misleading).

Here only a “short” version:

Below is a JSON structure - containing nested Object3D structures - that can be parsed by ObjectLoader (which uses JSONLoader and all the other loaders internally. - Note: a materials property nested in geometries - data is parsed by JSONLoader, but ignored by ObjectLoader).

JSONLoader can only load/parse a single (non buffered) geometry with associated materials - like the part in the middle of the graph, between the === lines (using FileLoader, Loader, MaterialLoader, TextureLoader and ImageLoader).

In this graph there should be all currently supported properties, which of course doesn’t mean that they always have to occur all together in the same JSON file. 😉

{
    ▼ metadata: {
        type
    },
    ▼ object: {
        children: [
            {
                uuid,
                type,
                geometry (uuid),
                material (uuid),
                ....,
                children: [
                    {
                        uuid,
                        type,
                        geometry (uuid),
                        material (uuid),
                        ....
                        children: [
                            {
                            ...
                            }
                        ]
                    }
                ]
            }
        ],
        uuid,
        type,
        geometry (uuid),
        material (uuid),
        matrix,
        position,
        rotation,
        quaternion,
        scale,
        visible,
        castShadow,
        receiveShadow,
        userData,
        background,
        fog: {
            type,
            color,
            near,
            far,
            density
        },
        fov,
        aspect,
        near,
        far,
        focus,
        zoom,
        filmGauge,
        filmOffset,
        view,
        left,
        right,
        top,
        bottom,
        color,
        intensity,
        distance,
        decay,
        width,
        height,
        angle,
        penumbra,
        groundColor,
        shadow: {
            bias,
            radius,
            mapSize,
            camera
        },
        mode
        levels
    },
    ▼ geometries: [
        {
            uuid,
            type,
            data: {
                name,
                index: {
                    type,
                    array
                },
                attributes: {
                    ...: {
                        type,
                        array,
                        itemSize,
                        normalized
                    },
                    ...
                },
                groups: [
                    {
                        start,
                        count,
                        materialIndex
                    },
                    ...
                ],
                boundingSphere: {
                    center,
                    radius
                },
=============================================================================
                metadata: {
                    type
                }
                materials: [
                    {
                        DbgName,
                        blending,
                        colorDiffuse,
                        colorSpecular,
                        colorEmissive,
                        specularCoef,
                        shading,
                        flipSided,
                        doubleSided,
                        transparency,
                        depthTest,
                        depthWrite,
                        colorWrite,
                        opacity,
                        reflectivity,
                        transparent,
                        visible,
                        wireframe,
                        vertexColors,
                        mapDiffuse, (path)
                        mapDiffuseRepeat,
                        mapDiffuseOffset,
                        mapDiffuseWrap,
                        mapDiffuseAnisotropy,
                        mapEmissive, (path)
                        mapEmissiveRepeat,
                        mapEmissiveOffset,
                        mapEmissiveWrap,
                        mapEmissiveAnisotropy,
                        mapLight, (path)
                        mapLightRepeat,
                        mapLightOffset,
                        mapLightWrap,
                        mapLightAnisotropy,
                        mapAO, (path)
                        mapAORepeat,
                        mapAOOffset,
                        mapAOWrap,
                        mapAOAnisotropy,
                        mapBump, (path)
                        mapBumpScale,
                        mapBumpRepeat,
                        mapBumpOffset,
                        mapBumpWrap,
                        mapBumpAnisotropy,
                        mapNormal, (path)
                        mapNormalFactor,
                        mapNormalRepeat,
                        mapNormalOffset,
                        mapNormalWrap,
                        mapNormalAnisotropy,
                        mapSpecular, (path)
                        mapSpecularRepeat,
                        mapSpecularOffset,
                        mapSpecularWrap,
                        mapSpecularAnisotropy,
                        mapMetalness, (path)
                        mapMetalnessRepeat,
                        mapMetalnessOffset,
                        mapMetalnessWrap,
                        mapMetalnessAnisotropy,
                        mapRoughness, (path)
                        mapRoughnessRepeat,
                        mapRoughnessOffset,
                        mapRoughnessWrap,
                        mapRoughnessAnisotropy,
                        mapAlpha, (path)
                        mapAlphaRepeat,
                        mapAlphaOffset,
                        mapAlphaWrap,
                        mapAlphaAnisotropy
                    },
                    ...
                ],
                scale,
                vertices,
                colors,
                uvs: [
                    [...],
                ...
                ],
                normals,
                faces,
                skinWeights,
                skinIndices,
                influencesPerVertex,
                bones: [
                    {
                        name,
                        parent,
                        pos,
                        scl,
                        rotq,
                    },
                    ...
                ],
                animation: {
                    name,
                    length,
                    fps,
                    hierarchy: {
                        parent,
                        keys: {
                            time,
                            pos,
                            scl,
                            rot
                        },
                    },
                },
                animations: [
                    {
                        name,
                        length,
                        fps,
                        hierarchy: {
                            parent,
                            keys: {
                                time,
                                pos,
                                scl,
                                rot
                            },
                        },
                    },
                    ...
                ],
                morphTargets: [
                    {
                        name,
                        vertices
                    },
                    ...
                ],
=============================================================================
            },
            width,
            height,
            widthSegments,
            heightSegments,
            depth,
            depthSegments,
            radius,
            segments,
            thetaStart,
            thetaLength,
            radiusTop,
            radiusBottom,
            radialSegments,
            openEnded,
            phiStart,
            phiLength,
            detail,
            innerRadius,
            outerRadius,
            phiSegments,
            tube,
            tubularSegments,
            p,
            q,
            points
        },
        ...,
    ],
    ▼ materials: [
        {
            type,
            uuid,
            name,
            color,
            roughness,
            metalness,
            emissive,
            specular,
            shininess,
            clearCoat,
            clearCoatRoughness,
            uniforms,
            vertexShader,
            fragmentShader,
            vertexColors,
            fog,
            shading,
            blending,
            side,
            opacity,
            transparent,
            alphaTest,
            depthTest,
            depthWrite,
            colorWrite,
            wireframe,
            wireframeLinewidth,
            wireframeLinecap,
            wireframeLinejoin,
            skinning,
            morphTargets,
            size,
            sizeAttenuation,
            map (uuid),
            alphaMap (uuid),
            bumpMap (uuid),
            bumpScale,
            normalMap (uuid),
            normalScale,
            displacementMap (uuid),
            displacementScale,
            displacementBias,
            roughnessMap (uuid),
            metalnessMap (uuid),
            emissiveMap (uuid),
            emissiveIntensity,
            specularMap (uuid),
            envMap (uuid),
            reflectivity,
            lightMap (uuid),
            lightMapIntensity,
            aoMap (uuid),
            aoMapIntensity,
            gradientMap (uuid)
        },
        ...,
    ],
    ▼ textures: [
        {
            uuid,
            image (uuid),
            name,
            repeat,
            offset,
            wrap,
            anisotropy,
            mapping,
            minFilter,
            magFilter,
            flipY
        },
        ...,
    ],
    ▼ images: [
        {
            uuid,
            name,
            url
        },
        ...,
    ],
    ▼ animations: [
        {
            name,
            tracks,
            fps
        },
        ...,
    ]

}

@mrdoob I think the documentation is currently very unclear as to why these both exist and when to use each. It's something I intended to update when I was going over the docs, however I'm not sure myself the difference between these.

JSONLoader was the first format/loader we did. Basically this spec:

https://github.com/mrdoob/three.js/wiki/JSON-Model-format-3

Calling it JSONLoader was definitely a bad decision, GeometryLoader would have been more appropriate, as that what it produced. Then we started adding material properties and became a sort of MeshLoader.

I've been trying to deprecate it for a while but the new loaders lacked features. I think one missing piece was MultiMaterial. JSONLoader was able to handle MultiMaterial better than ObjectLoader. This is something that has been solved in this dev cycle #10931

Closing. JSONLoader has been removed from core, see #15310.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fuzihaofzh picture fuzihaofzh  ·  3Comments

danieljack picture danieljack  ·  3Comments

Horray picture Horray  ·  3Comments

akshaysrin picture akshaysrin  ·  3Comments

yqrashawn picture yqrashawn  ·  3Comments