Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/424.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript three.js:重用纹理?_Javascript_Three.js - Fatal编程技术网

Javascript three.js:重用纹理?

Javascript three.js:重用纹理?,javascript,three.js,Javascript,Three.js,在我的程序中,我有几个地方实例化几何体,每个地方都有自己的偏好,以确定如何对其几何体进行网格划分(双面还是非双面?Lambert还是基本材质?)。但是,它们都使用相同的纹理。我只想加载这个普通纹理一次。这给了我一个设计问题: 当使用TextureLoader.load()加载纹理时,我只能使用一次纹理,也就是说,在传递给load函数的回调函数中。这意味着,在加载纹理之前,我必须收集所有几何体实例及其每个首选项,以便在启动加载时(通过闭包)使其可用于回调函数 我在想是否有一个标准的方法来解决这个问

在我的程序中,我有几个地方实例化几何体,每个地方都有自己的偏好,以确定如何对其几何体进行网格划分(双面还是非双面?Lambert还是基本材质?)。但是,它们都使用相同的纹理。我只想加载这个普通纹理一次。这给了我一个设计问题:

当使用
TextureLoader.load()
加载纹理时,我只能使用一次纹理,也就是说,在传递给
load
函数的回调函数中。这意味着,在加载纹理之前,我必须收集所有几何体实例及其每个首选项,以便在启动加载时(通过闭包)使其可用于回调函数

我在想是否有一个标准的方法来解决这个问题?我想其他3.js用户可能也遇到过类似的情况。我知道如何使用承诺来解决这个问题:load函数将返回表示纹理的承诺。然后,可以将该纹理传递到需要网格几何体的每个站点。这个解决方案很方便,因为我不必收集大量的几何数据,只需在稍后的一个步骤中传递


但是,对于这个问题,有没有一个类似的、或者几乎同样方便的解决方案,仍然停留在回调语义的领域呢?

我最终选择了承诺路线:包装
TextureLoader.load()
调用Javascripts内置的承诺返回构造函数,名为
Promise

var loadTexture_promise = ( texture_path, texture_loader ) => {
    var texture_promise;

    if (       loadTexture_promise.texturePromises_cache[texture_path] !== undefined ) {
        return loadTexture_promise.texturePromises_cache[texture_path]
    }

    texture_promise = new Promise(
        function( resolve, reject )
        {
            texture_loader.load(
                texture_path,
                function (texture) {
                    // Success callback of TextureLoader
                    // We're done, so tell the promise it is complete
                    resolve(texture);
                },
                function (XmlHttpRequest_instance) {
                    // Progress callback of TextureLoader
                },
                function (unknown_parameter) {
                    // Failure callback of TextureLoader
                    // Reject the promise with the failure
                    reject(new Error('Could not load texture ' + texture_path));
                }
            );
        }
    );

    // add texture_promise to cache:
    loadTexture_promise.texturePromises_cache[texture_path] = texture_promise;

    return texture_promise;
};
// establish cache object on the loadTexture_promise function:
loadTexture_promise.texturePromises_cache = [];
然后,我有一个
lambertmasher
函数,几何体供应商可以调用该函数:

function lambertMesher ( aGeometry, aTexture_promise, doubleSided, debug ) {
    var aMesh_promise = aTexture_promise.then(
        ( resolved_texture ) =>
        {
            var material, mesh;

            if ( debug ) {
                console.log("resolved_texture: ", resolved_texture);
                console.log("aGeometry: ", aGeometry);
            }

            resolved_texture.minFilter = THREE.NearestFilter;

            if (doubleSided) {
                material = new THREE.MeshLambertMaterial( { map: resolved_texture, side: THREE.DoubleSide } );
            } else {
                material = new THREE.MeshLambertMaterial( { map: resolved_texture, emissive: 0xffffff } );
            }

            mesh = new THREE.Mesh(aGeometry, material);
            if ( debug ) {
                console.log("mesh: ", mesh);
            }
            return mesh

        },
        ( reason_of_textureLoading_failure ) =>
        {
            console.log( "meshing failed. Also: " + reason_of_textureLoading_failure )
        }
    );

    return aMesh_promise
}
最后,我这样称呼我的
lambertmasher

var myPlateGeom = new THREE.PlateGeometry( myPlatePolygonSet, true );
var myPlateMesh_promise = utils_meshers.lambertMesher( myPlateGeom, myRobinieTexture_promise, true, false );
最后,我将网格添加到场景中,如下所示:

myPlateMesh_promise.then(
    (myPlateMesh) => { myScene.add( myPlateMesh ) },
    (reason)     =>   console.log( "failed to add myPlateMesh. Also: " + reason )
);

因为您需要等待纹理加载,所以承诺是最适合这里的。承诺的好处在于,您可以继续调用
。然后()
,这样可以保持代码的整洁。听起来你不需要承诺方面的帮助,但我以前也回答过类似的问题: