我有一个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;
}
我希望能够交换出分配给每个立方体一个面的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