【发布时间】:2023-03-03 01:22:01
【问题描述】:
我有一个包含多个网格的场景,每个网格的形状和大小都不同。
我已经遍历了每个网格并使用 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 的合并几何。右侧的网格是由此产生的结果,而不是将贴图作为一个整体应用到网格上,而是每个几何图形都应用了贴图。
有没有办法屏蔽整个网格而不是每个几何体?
-- 三.js r86
编辑: 我尝试将剪裁平面应用于我的网格,但这不是我正在寻找的效果。我希望能够在整个网格上应用 alphaMask 并显示它,但是我制作了我的蒙版图像。类似这种效果 - https://codepen.io/supah/pen/zwJxdb
这与保留原始几何形状的 UV 有关吗?我需要以某种方式更改这些吗?
【问题讨论】:
-
不太确定您想要实现什么,但您应该了解的一件事是在合并对象时纹理坐标不会改变。如果您希望效果看起来更连续,则需要在合并后手动调整 uv 坐标。此外,合并几何体不会执行任何布尔运算,因此合并后的几何体仍将包含对象联合内的三角形。
-
另一个想法是使用剪切平面来实现“剪切整个对象”的效果。
-
感谢您的回复@Nicholas,基本上我希望纹理覆盖整个合并网格,而不是在我的示例中发生的情况 - 看起来每个球体都应用了纹理。我喜欢剪裁平面的外观,我也许可以使用该技术实现我正在寻找的效果。我不太确定如何在合并后调整 uv 坐标 - 我尝试应用此效果的合并几何体比 3 个球体复杂得多。
-
我尝试了剪裁平面技术,但这不是我想要的效果。谢谢你的建议。正如你所说,我可能需要对紫外线做点什么?
-
另一个想法是创建一个自定义着色器材质,您可以在其中改变不透明度,而不是基于纹理,而是基于模型空间中的位置。基本上在你的片段着色器中你可以有类似的东西: gl_FragColor.a = sin(vPosition.x);先自己试试吧,如果遇到困难我可以给你举个例子。
标签: javascript merge three.js geometry