gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 01:24:03 29 4
gpt4 key购买 nike

我有一个 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/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com