javascript - Three.js - 将多个图像映射到一个球体并控制每个图像

标签 javascript three.js

我有一个 3D 球体,我想将一组图像映射到该球体上,并且我希望能够控制每个单独的图像,即独立地淡出/淡入每个图像。我将提供一个示例图片来说明我想要实现的目标,因为我觉得这是解释它的最佳方式。

enter image description here

正如您在上面看到的,每列 8 个图像,每行 16(?)。

我已经能够通过简单地将图像映射到 SphereGeometry 来重新创建上面的图像,但是我希望能够动态交换图像,并在不同时间淡入它们。

到目前为止我尝试过的/我的想法:

  • 我尝试将 8 个测试图像推送到一个数组并将其用作 Material 贴图,然后循环遍历 SphereGeometry 的每个面并分配 1 到 8 的 Material 索引,然后使用模数每 8 后重置一次,但这不起作用:

    function createGlobe() {
    
        var geomGlobe = new THREE.SphereGeometry(40, 32, 16);
    
        var l = geomGlobe.faces.length;
    
        imageArray.push(new THREE.MeshBasicMaterial({map: texture1}));
        imageArray.push(new THREE.MeshBasicMaterial({map: texture2}));
        imageArray.push(new THREE.MeshBasicMaterial({map: texture3}));
        imageArray.push(new THREE.MeshBasicMaterial({map: texture4}));
        imageArray.push(new THREE.MeshBasicMaterial({map: texture5}));
        imageArray.push(new THREE.MeshBasicMaterial({map: texture6}));
        imageArray.push(new THREE.MeshBasicMaterial({map: texture7}));
        imageArray.push(new THREE.MeshBasicMaterial({map: texture8}));
    
        for (var i = 0; i < l; i++) {
            geomGlobe.faces[i].materialIndex = i % 8;
        }
    
        Globe = new THREE.Mesh(geomGlobe, imageArray);
    
        scene.add(Globe);
    }
    
  • 我想我需要每4或8个面数一下,然后设置 Material 这些面孔中的每一张的索引都相同,以便它们都使用 同一张图片,但我不确定面孔是否正确排列 就这样。

基本上我需要的是:

一种以每列 8 个、每行 16 个方式将图像动态添加到球体的方法,并且能够单独操作每个图像。

非常感谢任何帮助,因为我很困难!

最佳答案

我建议制作一个大 Canvas 并将其用作纹理,然后将过渡动画设置到 Canvas 中,然后设置texture.needsUpdate = true以在GPU上更新它。

您可能会发现纹理更新花费太多时间..在这种情况下,您可以尝试制作2个 Canvas +球体..并通过更改最前面的不透明度在它们之间进行交叉淡入淡出。

下面的代码片段展示了一种通过一些随机填充的 Canvas 将一个球体淡入另一个球体的方法。

var renderer = new THREE.WebGLRenderer();
var w = 300;
var h = 200;
renderer.setSize(w, h);
document.body.appendChild(renderer.domElement);

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
  45, // Field of view
  w / h, // Aspect ratio
  0.1, // Near
  10000 // Far
);
camera.position.set(15, 10, 15);
camera.lookAt(scene.position);
controls = new THREE.OrbitControls(camera, renderer.domElement);

var light = new THREE.PointLight(0xFFFF00);
light.position.set(20, 20, 20);
scene.add(light);
var light1 = new THREE.AmbientLight(0x808080);
light1.position.set(20, 20, 20);
scene.add(light1);
var light2 = new THREE.PointLight(0x00FFFF);
light2.position.set(-20, 20, -20);
scene.add(light2);
var light3 = new THREE.PointLight(0xFF00FF);
light3.position.set(-20, -20, -20);
scene.add(light3);

var sphereGeom = new THREE.SphereGeometry(5, 16, 16);

function rnd(rng) {
  return (Math.random() * rng)
}

function irnd(rng) {
  return rnd(rng) | 0
}

function randomCanvasTexture(sz) {
  var canv = document.createElement('canvas');
  canv.width = canv.height = sz;
  var ctx = canv.getContext('2d')
  for (var i = 0; i < 100; i++) {
    ctx.fillStyle = `rgb(${irnd(256)},${irnd(256)},${irnd(256)})`
    ctx.fillRect(irnd(sz), irnd(sz), 32, 32)
  }
  var tex = new THREE.Texture(canv);
  tex.needsUpdate = true;
  return tex;
}

var material = new THREE.MeshLambertMaterial({
  color: 0x808080,
  map: randomCanvasTexture(256)
});
var mesh = new THREE.Mesh(sphereGeom, material);

var mesh1 = mesh.clone()
mesh1.material = mesh.material.clone()
mesh1.material.transparent = true;
mesh1.material.opacity = 0.5;
mesh1.material.map = randomCanvasTexture(256)
scene.add(mesh);
scene.add(mesh1);

renderer.setClearColor(0xdddddd, 1);

(function animate() {
  mesh1.material.opacity = (Math.sin(performance.now() * 0.001) + 1) * 0.5
  requestAnimationFrame(animate);
  controls.update();
  renderer.render(scene, camera);
})();
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>

关于javascript - Three.js - 将多个图像映射到一个球体并控制每个图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51631632/

相关文章:

javascript - 使函数成为路由中的快速中间件

javascript - 按值访问 XML 节点

javascript - 可以将draw_buffer扩展与THREE.js一起使用吗?

javascript - THREE.js 对象不会旋转

javascript - 获取几何面上点的颜色

javascript - HTML 动态内容神秘消失

javascript - 使用 Ajax 从 JSON 文件加载内容时,不会对 div 产生影响。

javascript - 使用模块全局范围来定义可从原型(prototype)访问的私有(private)类字段

three.js - 模拟曝光控制

javascript - GLSL:将可变数量的纹理发送到sampler2D