THREE.TextureLoader()多次加载相同的纹理(即20次或更多次)

时间:2016-10-02 15:32:54

标签: javascript three.js

THREE.TextureLoader()以意外和错误的方式运行。该类的load()函数多次尝试/加载相同的资产(即20次或更多次)。

下图显示了使用浏览器控制台的此行为:

enter image description here

用于加载和使用纹理的代码如下:

Element.prototype.createShaderMaterial = function (uniforms, vertexShader, fragmentShader) {
    var loader = new THREE.TextureLoader();
    uniforms.texture.value = loader.load(this.texture);

    return new THREE.ShaderMaterial({
        uniforms: uniforms,
        vertexShader: vertexShader,
        fragmentShader: fragmentShader,
        wireframe: true
    });
};

您还可以在此处找到实时预览:https://alexprut.github.io/earth-defender/ 和游戏代码:https://github.com/alexprut/earth-defender/tree/master/client/js

做错了什么?为什么多次加载相同的图像?

1 个答案:

答案 0 :(得分:0)

事实是THREE.TextureLoader()默认情况下不会缓存纹理,但我认为它应该,或者至少要求你不要这样做。 这意味着如果您有400个具有相同纹理的对象,则库将为相同的资产发出400 HTTP请求。

下面是一个简单的解决方案(Singleton模式/模块模式)缓存​​模块:

var TextureLoader = (function () {
    var _instance = null;

    var Loader = function () {
        var _loader = new THREE.TextureLoader();
        var _cache = [];

        function _cachePush(elem, val) {
            _cache.push({
                element: elem,
                value: val
            });
        }

        function _cacheSearch(elem) {
            for (var i = 0; i < _cache.length; i++) {
                if (_cache[i].element === elem) {
                    return _cache[i].value;
                }
            }

            return false;
        }

        function load(texture) {
            var match = _cacheSearch(texture);

            if (match) {
                return match;
            }

            var val = _loader.load(texture);
            _cachePush(texture, val);

            return val;
        }

        return {
            load: load
        }
    };

    function getInstance() {
        return (_instance) ? _instance : _instance = Loader();
    }

    return {
        getInstance: getInstance
    }
})();

使用和缓存需要调用的纹理:

TextureLoader.getInstance().load(texture);