Three.js 运行时纹理/图像更新
Posted
技术标签:
【中文标题】Three.js 运行时纹理/图像更新【英文标题】:Three.js texture / image update at runtime 【发布时间】:2013-04-10 14:14:53 【问题描述】:我正在尝试通过从“选择表单”元素中选择一个选项来在运行时更改立方体图像。运行代码时,选择后图像会发生变化,但之前的立方体和图像会留在场景中。
更改材质/图像/纹理时如何正确清除/刷新/更新场景。
<div id = "container"></div>
<form id = "changesForm">
Cube Image:
<br>
<select id = "cubeImage">
<option value = "random">Random</option>
<option value = "image1">First Image</option>
<option value = "Image2">Second Image</option>
</select>
<br>
</form>
<script type = "text/javascript">
window.onload = windowLoaded;
function windowLoaded()
if (window.addEventListener)
init();
animate();
//document.getElementById('container').addEventListener('mousemove', containerMouseover, false);
window.addEventListener( 'resize', onWindowResize, false );
var cubeImage = document.getElementById('cubeImage');
cubeImage.addEventListener("change", changeCubeImage, false);
else if (window.attachEvent)
//init();
//animate();
//document.getElementById('container').attachEvent('onmousemove', containerMouseover);
//window.attachEvent( 'onresize', onWindowResize);
function changeCubeImage(e)
//e.preventDefault();
var target = e.target;
cubeImageCheck = target.value;
createCube();
// rest code .....
function createCube()
//image
var cubeImg;
switch (cubeImageCheck)
case 'random':
// should load the 2 images random - to do
cubeImg = new THREE.ImageUtils.loadTexture("img1.jpg");
break;
case 'image1':
cubeImg = new THREE.ImageUtils.loadTexture("image1.jpg");
break;
case 'image2':
cubeImg = new THREE.ImageUtils.loadTexture("image2.jpg");
break;
cubeImg.needsUpdate = true;
// geometry
var cubeGeometry = new THREE.CubeGeometry(200,200,200);;
// material
var cubeMaterial = new THREE.MeshPhongMaterial(
map: cubeImg,
side:THREE.DoubleSide,
transparent: true,
opacity:1,
shading: THREE.SmoothShading,
shininess: 90,
specular: 0xFFFFFF
);
cubeMaterial.map.needsUpdate = true;
//mesh
cubeMesh = new THREE.Mesh(cubeGeometry, cubeMaterial);
cubeMesh.needsUpdate = true;
scene.add(cubeMesh);
// rest ....
【问题讨论】:
【参考方案1】:选择更改后,您可以更新现有网格纹理,无需删除或创建新网格:
mesh.material.map = THREE.ImageUtils.loadTexture( src );
mesh.material.needsUpdate = true;
【讨论】:
如果您之前已将所有纹理预加载到不可见的img
元素中,则此方法显然会检索浏览器缓存的图像。因此无需担心从服务器重新加载图像。
由于之前的纹理没有被释放,这不会导致内存泄漏吗?
Kahless - 可能吗?我不确定如何“处置”(也就是摆脱所有引用)在三个中的材质贴图【参考方案2】:
带加载器的完整示例:
首先,创建您的网格并应用任何材料
//Add SPHERE
this.earthMesh = new THREE.Mesh(
new THREE.SphereBufferGeometry(3, 35, 35),
new THREE.MeshPhongMaterial()
);
this.scene.add(this.earthMesh);
现在加载您的纹理图像并将其应用到网格材质上
//LOAD TEXTURE and on completion apply it on SPHERE
new THREE.TextureLoader().load(
"https://images.pexels.com/photos/1089438/pexels-photo-1089438.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
texture =>
//Update Texture
this.earthMesh.material.map = texture;
this.earthMesh.material.needsUpdate = true;
,
xhr =>
//Download Progress
console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
,
error =>
//Error CallBack
console.log("An error happened" + error);
);
进度和错误回调是可选的
【讨论】:
以上是关于Three.js 运行时纹理/图像更新的主要内容,如果未能解决你的问题,请参考以下文章
在运行时使用 Three.js 将文本/图像添加到 Canvas 中呈现的 3D 立方体/模型