javascript - 有没有办法在不破坏网格对象的情况下交换与 ThreeJS 网格关联的图像?
问题描述
我有一个 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
推荐阅读
- apache - RewriteRule (contact.php -> contact) + 404 重定向总是给我一个 404 页面
- python - PermissionError: [Errno 13] Permission denied python 错误
- c - 我在做 make 时遇到了这个 C make 文件错误
- c++ - c++:“没有重载函数实例”的原因
- html - 为什么我将更改推送到生产后我的源不可用?
- anylogic - 选择输出 5 块以按顺序释放代理,一旦满足批量大小条件
- javascript - 需要帮助使用 Angular Firebase 进行错误处理
- php - 您好如何修复 XSS 漏洞搜索表单
- avx - 是否有像 _mm256_mulhi_epu16 这样的 AVX、AVX2 或 AVX512 函数,但适用于 8 位?
- c - Go/Cgo:生成没有 Go 运行时函数定义的静态库