【问题标题】:three.js: reusing a texture?three.js:重用纹理?
【发布时间】:2016-01-10 20:03:44
【问题描述】:

在我的程序中,我有几个实例化几何图形的位置,每个位置都有自己的几何网格划分方式(双面与否?Lambert 还是基本材料?)。但是,它们都使用相同的纹理。我只想加载这个常见的纹理一次。这给了我一个设计问题:

当使用TextureLoader.load() 加载纹理时,我只能使用一次纹理,即在我传递给load 函数的回调函数中。这意味着我必须在加载我的纹理之前收集我所有的几何实例和它们的每个首选项,这样我就可以在加载开始时(通过闭包)将它们全部提供给我的回调函数。

我在想是否有解决这个问题的规范方法?我猜其他的three.js 用户可能也遇到过类似的情况。我知道如何使用 Promise 解决这个问题:加载函数将返回一个代表纹理的 Promise。然后可以将此纹理传递到需要对几何图形进行网格划分的每个站点。这个解决方案很方便,因为我不必收集大量的几何数据,只是为了能够在稍后的一个步骤中传递它。

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

【问题讨论】:

  • 由于您需要等待纹理加载,因此 Promise 是迄今为止最合适的选择。 Promise 的好处是你可以继续调用 .then() ,这可以保持你的代码非常干净。听起来你不需要承诺的帮助,但我之前回答过一个类似的问题:stackoverflow.com/questions/33283386/…

标签: javascript three.js


【解决方案1】:

我最终选择了 Promise 路线:将 TextureLoader.load() 调用包装在名为 Promise 的 JavaScript 内置 promise-returning 构造函数中:

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 = [];

然后我有一个lambertMesher 函数,我的几何供应商可以调用它:

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
}

最后,我就是这样称呼我的lambertMesher

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 )
);

【讨论】:

    猜你喜欢
    • 2017-08-11
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    • 2017-10-05
    • 1970-01-01
    • 2015-09-06
    • 2013-05-19
    • 2016-02-27
    相关资源
    最近更新 更多