Есть ли способ поменять изображение, связанное с Three JS me sh, без необходимости уничтожать меня sh объект? - PullRequest
0 голосов
/ 08 февраля 2020

У меня есть игра Three JS, в которой в качестве игровых фигур используется набор кубиков. Одно лицо на каждом кубе несет пользовательское изображение, загруженное через указанный c JPG URL. Когда пользователь запускает новую игру, я хотел бы иметь возможность просто поменять изображение JPG, назначенное одному лицу каждого куба. Можно ли это как-то сделать? Или мне нужно полностью снести и перестроить каждый куб? Конечно, я бы хотел этого избежать, потому что мой поиск в сети привел меня к выводу, что правильно очистить сцену Three JS и ресурсы GPU, которые она обременяла, непросто (включая необходимость высвободить все ссылки на любая часть меня sh или его составных частей).

Этот код показывает, как я создаю кубы:

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

1 Ответ

2 голосов
/ 08 февраля 2020

Я бы хотел иметь возможность просто поменять изображение 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

...