运行时加载和处置纹理

发布于 2025-01-22 07:22:39 字数 3110 浏览 3 评论 0原文

我试图了解如何在三分js中提高内存效率。在我的主要应用程序中,我尝试根据与相机的距离加载和处置纹理,以节省GPU中的内存。由于我在主要应用程序中使用了许多纹理和大纹理,因此我可能无法使用最初加载所有纹理的纹理地图集。在这里,我有一个关于我如何想象的代码示例。加载纹理有效,但不能删除它。但是我不明白为什么那是。根据Three.js Docu的说法,这应该与Dispose()一起使用,但在这里不起作用。我的错误在哪里?

总的来说:如果有人认为我的概念中有一些可以改善的东西,我很高兴听到您的建议。我只在迄今为止我所知道的框架内做我可以想象的事情的框架。我喜欢了解它。例如,我不仅对如何加载和处置纹理感兴趣。同样,我在这里创建的对象应该从整体上有效添加和删除,再次添加并删除,...毕竟,这是类对象的目的,可以随意创建和删除。


var camera, controls, scene, renderer, container, aspect;

var cube;
    
async function main() {
await init();
animate();
}


async function init() {

    renderer = new THREE.WebGLRenderer( { antialias: true } );
    renderer.setPixelRatio( window.devicePixelRatio ); 
    renderer.shadowMap.enabled = true; 
    renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    renderer.setClearColor( 0x000000 );  
    container = document.getElementById('container');
    renderer.setSize(container.clientWidth, container.clientHeight);
    container.appendChild( renderer.domElement );

    aspect = container.clientWidth / container.clientHeight; 
    scene = new THREE.Scene();
    scene.background = new THREE.Color( 0x000000 );
    
    camera = new THREE.PerspectiveCamera( 45, aspect, 1, 1000000 );
    camera.position.set(0, 0, 300);

    controls = new THREE.OrbitControls( camera, renderer.domElement );
    controls.enableZoom = true;
    controls.enabled = true;
    controls.target.set(0, 0, 0);
    
    //------End three.js setup-------
    

    cube = new Cube();
    scene.add(cube.box);

}//-------End init----------


function animate() {

    requestAnimationFrame( animate );  
    render();
    
}//-------End animate----------

function render() {
    
    var distance = camera.position.distanceTo( cube.box.position );
    cube.update(distance);

    
    camera.updateMatrixWorld();
    camera.updateProjectionMatrix(); 
    renderer.render(scene, camera); 

}//-------End render----------



class Cube{
    constructor(){
    
        this.texture;
        this.texstatus = false;
    
        const geometry = new THREE.BoxGeometry( 10, 10, 10 ); 
        const material = new THREE.MeshBasicMaterial( {
            color: 0x00ff00,
            map: null
        } ); 
        this.box = new THREE.Mesh( geometry, material ); 
    
    
    }//end constructor
    
    update(distToCam){
    
        if(distToCam <= 100 && this.texstatus == false){
        
            var loader = new THREE.TextureLoader();
            this.texture = loader.load("grass.jpg");
            this.box.material.map = this.texture;       
            this.texstatus = true;  
        }
        
        if(distToCam > 100 && this.texstatus == true){
        
            //prvious solution deactivated 
            //this.texture.dispose();
            //this.texstatus = false;   

            //new solution
            this.box.material.map = null;
            this.texture.dispose();
            this.texstatus = false; 
            this.texture = undefined;

        }
        
        this.box.material.needsUpdate = true;
        
    }//end update
    

}//end Cube class

I'm trying to understand how to be memory efficient in three.js. In my main application i try to load and dispose textures depending on the distance to the camera to save memory in the gpu. Since i work with a lot of textures and large textures in my main application i can't possibly work with a texture atlas into which i initially load all the textures. Here I have a code example of how i imagine it. Loading the texture works but not deleting it. But i don't see why that is. According to the three.js docu this should work with dispose() but it doesn't work here.Wwhere is my mistake?

In general: If someone thinks there is something in my concept that could be improved, i'd be happy to hear your advice. I only do what i do within the framework of what i can best imagine based on what i know so far. I like to learn about it. For example, i would be interested in how i not only load and dispose textures. Also the object that i have created here should be efficiently added and deleted as a whole, added again and deleted, ... after all, that's the purpose of class objects, being able to be created and deleted again at will.


var camera, controls, scene, renderer, container, aspect;

var cube;
    
async function main() {
await init();
animate();
}


async function init() {

    renderer = new THREE.WebGLRenderer( { antialias: true } );
    renderer.setPixelRatio( window.devicePixelRatio ); 
    renderer.shadowMap.enabled = true; 
    renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    renderer.setClearColor( 0x000000 );  
    container = document.getElementById('container');
    renderer.setSize(container.clientWidth, container.clientHeight);
    container.appendChild( renderer.domElement );

    aspect = container.clientWidth / container.clientHeight; 
    scene = new THREE.Scene();
    scene.background = new THREE.Color( 0x000000 );
    
    camera = new THREE.PerspectiveCamera( 45, aspect, 1, 1000000 );
    camera.position.set(0, 0, 300);

    controls = new THREE.OrbitControls( camera, renderer.domElement );
    controls.enableZoom = true;
    controls.enabled = true;
    controls.target.set(0, 0, 0);
    
    //------End three.js setup-------
    

    cube = new Cube();
    scene.add(cube.box);

}//-------End init----------


function animate() {

    requestAnimationFrame( animate );  
    render();
    
}//-------End animate----------

function render() {
    
    var distance = camera.position.distanceTo( cube.box.position );
    cube.update(distance);

    
    camera.updateMatrixWorld();
    camera.updateProjectionMatrix(); 
    renderer.render(scene, camera); 

}//-------End render----------



class Cube{
    constructor(){
    
        this.texture;
        this.texstatus = false;
    
        const geometry = new THREE.BoxGeometry( 10, 10, 10 ); 
        const material = new THREE.MeshBasicMaterial( {
            color: 0x00ff00,
            map: null
        } ); 
        this.box = new THREE.Mesh( geometry, material ); 
    
    
    }//end constructor
    
    update(distToCam){
    
        if(distToCam <= 100 && this.texstatus == false){
        
            var loader = new THREE.TextureLoader();
            this.texture = loader.load("grass.jpg");
            this.box.material.map = this.texture;       
            this.texstatus = true;  
        }
        
        if(distToCam > 100 && this.texstatus == true){
        
            //prvious solution deactivated 
            //this.texture.dispose();
            //this.texstatus = false;   

            //new solution
            this.box.material.map = null;
            this.texture.dispose();
            this.texstatus = false; 
            this.texture = undefined;

        }
        
        this.box.material.needsUpdate = true;
        
    }//end update
    

}//end Cube class

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文