在three.js中合并几何体

3

我有一个场景,其中包含多个网格,每个网格形状和大小都不同。

我已经循环遍历了每个网格,并使用geometry.merge()将场景中的几何体创建为一个新的网格。

我想要用alphaMask对整个网格进行遮罩,但是每个几何体都单独应用了材质。

可以在这里看到一个示例 - https://codepen.io/danlong/pen/KXOObr

    function addObjects(scene) {

    // merged geomoetry & material
    var mergedGeometry = new THREE.Geometry();
    var mergedMaterial = new THREE.MeshStandardMaterial({ color: "#444", transparent: true, side: THREE.DoubleSide, alphaTest: 0.5, opacity: 1, roughness: 1 });


    // multiple meshes
    var geometry = new THREE.IcosahedronGeometry(30, 5);
    var material = new THREE.MeshStandardMaterial({ color: "#444" });

    var geo1 = new THREE.IcosahedronGeometry(30, 5);
    var mesh1 = new THREE.Mesh( geo1, material );
    mesh1.position.x = 10;
    mesh1.position.y = 10;
    mesh1.position.z = 0;

    var geo2 = new THREE.IcosahedronGeometry(30, 5);
    var mesh2 = new THREE.Mesh( geo2, material );
    mesh2.position.x = 20;
    mesh2.position.y = 20;
    mesh2.position.z = 0;

    var geo3 = new THREE.IcosahedronGeometry(30, 5);
    var mesh3 = new THREE.Mesh( geo3, material );
    mesh3.position.x = 30;
    mesh3.position.y = 30;
    mesh3.position.z = 0;

    // scene.add(mesh1, mesh2, mesh3);
    mesh1.updateMatrix();
    mergedGeometry.merge(mesh1.geometry, mesh1.matrix);

    mesh2.updateMatrix();
    mergedGeometry.merge(mesh2.geometry, mesh2.matrix);

    mesh3.updateMatrix();
    mergedGeometry.merge(mesh3.geometry, mesh3.matrix);

    // alpha texture 
    var image = document.createElement('img');
    var alphaMap = new THREE.Texture(image);
    image.onload = function()  {
        alphaMap.needsUpdate = true;
    };
    image.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAGUlEQVQoU2NkYGD4z4AHMP7//x+/gmFhAgCXphP14bko/wAAAABJRU5ErkJggg==';
    mergedMaterial.alphaMap = alphaMap;
    mergedMaterial.alphaMap.magFilter = THREE.NearestFilter;
    mergedMaterial.alphaMap.wrapT = THREE.RepeatWrapping;
    mergedMaterial.alphaMap.repeat.y = 1;

    // merged geometry with alpha mask
    merge1 = new THREE.Mesh(mergedGeometry, mergedMaterial);
        merge1.rotation.z = -Math.PI/4;

    // merge geometry without alpha mask
    var merge2 = new THREE.Mesh(mergedGeometry, material);
    merge2.position.x = -100;
        merge2.rotation.z = -Math.PI/4;

    scene.add(merge1, merge2);
    return mesh;
}

左边的网格是合并后的几何体,我想将alphaMask应用于它。右边的网格是这样做的结果,每个几何体都应用了地图,而不是整个网格应用地图。有没有一种方法可以遮盖整个网格而不是每个几何体?
- three.js r86
编辑: 我尝试将裁剪平面应用于我的网格,但这不是我要寻找的效果。我想能够在整个网格上应用alphaMask,并根据我制作的遮罩图像显示它。类似于这种效果-https://codepen.io/supah/pen/zwJxdb 这与原始几何体中保留UV有关吗?我需要以某种方式更改它们吗?

不太确定您想要实现什么,但您应该明白的一件事是,当合并对象时纹理坐标不会改变。如果您希望效果看起来更连续,您需要在合并后手动调整UV坐标。此外,合并几何图形不执行任何布尔运算,因此合并后的几何图形仍将包含联合中的三角形。 - Nicholas
另一个想法是使用剪裁平面来实现“切割整个对象”的效果。 - Nicholas
感谢您的回复@Nicholas,本质上我希望纹理覆盖整个合并网格,而不是在我的示例中发生的情况 - 看起来每个球体都应用了纹理。 我喜欢剪辑平面的外观,也许我可以用那种技术实现我正在寻找的效果。 我不太确定如何在合并后调整UV坐标 - 我正在尝试将此效果应用于更复杂的几何体,而不仅仅是3个球体。 - danlong
我尝试了裁剪平面技术,但这不是我想要的效果。感谢您的建议。我可能需要像您提到的那样对UV进行一些处理? - danlong
另一个想法是创建一个自定义着色器材质,在其中根据模型空间中的位置而不是纹理来变化不透明度。基本上在你的片段着色器中,你可以像这样写:gl_FragColor.a = sin(vPosition.x); 先自己尝试一下,如果卡住了我可以提供一个示例给你。 - Nicholas
好的,我明白你的意思。我会调查一下这个选项,看看能达到什么效果。再次感谢! - danlong
1个回答

0

我认为你真正想要的是一个叠加的遮罩。这可以通过渲染应用了 Alpha Map 的单个平面,在场景渲染的顶部完成。使用正交相机,并控制某些渲染器设置,例如禁用自动清除颜色。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接