是否有一种方法可以交换与ThreeJS网格相关的图像而不必破坏网格对象?

问题描述 投票:0回答:1

我有一个ThreeJS游戏,它使用一组多维数据集作为游戏片段。每个立方体上的一个面都带有通过特定JPG URL加载的自定义图像。当用户开始新游戏时,我希望能够交换出分配给每个立方体一个面的JPG图像。有可能做到这一点吗?还是我必须完全拆除并重建每个多维数据集?我当然想避免这种情况,因为我的网络搜索使我得出这样的结论:正确清理ThreeJS场景及其所占用的GPU资源并不是一件容易的事(包括必须释放对任何内容的引用)网格或其组成部分)。

此代码显示了我如何创建多维数据集:

function makeCardCube(cardImageUrl, textureBackSide, locX, locY, locZ, width, height) {
    let thickness = 0.01 * width;
    let cubeGeometry = new THREE.BoxBufferGeometry(width, thickness, height);
    let loader = new THREE.TextureLoader();

    let materialArray = [
        new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
        new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
        // Card face.
        new THREE.MeshBasicMaterial( { map: loader.load(cardImageUrl) } ),
        // Card back side.
        new THREE.MeshBasicMaterial(
            {
                map: textureBackSide
            }
        ),

        new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
        new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
    ];

    cube = new THREE.Mesh( cubeGeometry, materialArray );
    cube.position.set(locX, locY, locZ);
    // Flip the card 90 degrees "up" around the X axis so the card faces the camera.
    cube.rotateX(THREE.Math.degToRad(90));

    return cube;
}
javascript memory-management three.js
1个回答
0
投票

我希望能够交换出分配给每个立方体一个面的JPG图像。

您通常通过创建Texture的新实例并将其分配给Material.map来执行此操作。如果您不再需要以前的纹理,建议通过调用Texture.dispose()释放相关的内存。

这里是一个完整的实时示例,用于说明纹理替换。

var camera, scene, renderer, mesh;

init();
animate();

function init() {

    camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
    camera.position.z = 5;

    scene = new THREE.Scene();

    geometry = new THREE.BoxGeometry();
		
    var loader = new THREE.TextureLoader();
    var texture = loader.load( 'https://threejs.org/examples/textures/crate.gif' );
		
    var material = [
	        new THREE.MeshBasicMaterial( { map: texture } ),
	        new THREE.MeshBasicMaterial( { map: texture } ),
	        new THREE.MeshBasicMaterial( { map: texture } ),
	        new THREE.MeshBasicMaterial( { map: texture } ),
	        new THREE.MeshBasicMaterial( { map: texture } ),
	        new THREE.MeshBasicMaterial( { map: texture } )
    ];

    mesh = new THREE.Mesh( geometry, material );
    scene.add( mesh );

    renderer = new THREE.WebGLRenderer( { antialias: true } );
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );

    // change the material of one cube side by replacing its texture
		
    setTimeout( () => {
		
	        var newTexture = loader.load( 'https://threejs.org/examples/textures/colors.png' );
	        material[ 0 ].map = newTexture;
			
	        // in this case we do not call dispose() because crate.gif is still used by five other sides of the cube 
		
    }, 1000 );

}

function animate() {

    requestAnimationFrame( animate );

    mesh.rotation.x += 0.01;
    mesh.rotation.y += 0.02;

    renderer.render( scene, camera );

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.js"></script>

three.js R113

© www.soinside.com 2019 - 2024. All rights reserved.