我在 THREE.js 中有一个球体(我将其称为主球体)。我的用户能够单击球体上的多个点来标记多边形的角点。这些点本身在 3D 空间中表示为球体,并位于主球体的表面上。一旦放置了三个或更多点,用户就可以关闭它们并构建多边形。
此时,我想在主球体表面上方创建一个多边形。该多边形的形状应与用户刚刚构建的多边形相同,并且略高于主球体的表面。
我认为我能够在球体的表面创建一个多边形,然后使用顶点着色器在其法线上替换每个顶点,因此我使用 THREE.Shape 和 THREE.ShapeGeometry 构建了一个形状。这会在 z 轴上产生 2D 形状,因此我接下来将形状转换到曲面,然后使用 THREE.SubdivisionModifier 和 THREE.TessellateModifier 的不同组合来尝试构建着色器要替换的顶点。另外,如果我不使用修改器,翻译后形状甚至不可见。
我目前正在使用以下两者的组合,但这会导致形状非常扭曲。
// Create a new instance of the modifier and pass the number of divisions.
var subdivisionModifier = new THREE.SubdivisionModifier(3);
var tessellateModifier = new THREE.TessellateModifier(8);
// Apply the modifier to our cloned geometry.
for(var x=0; x<6; x++) {
tessellateModifier.modify(polyGeometry);
}
subdivisionModifier.modify(polyGeometry);
结果如下: 黄色轮廓是所需的形状,而蓝色轮廓是创建的形状。绿色线框是主球体。
我在这里为我的项目构建了一个 JSFiddle: 具有高架多边形的地球仪
如您所见,生成的多边形没有达到所需的形状。最后,我想我需要知道我是否走上了一条死胡同,以及我想做的事情是否可能。
我能够通过减少传递给 THREE.TessellateModifier 的最大边长度参数并增加应用程序的数量来创建具有多个顶点的网格。毕竟我不需要细分修改器。
最终代码如下:
var tessellateModifier = new THREE.TessellateModifier(.01);
//subdivisionModifier.modify(polyGeometry);
// Apply the modifier to our cloned geometry.
for(var x=0; x<25; x++) {
tessellateModifier.modify(polyGeometry);
}
此外,无需借助顶点着色器来扭曲网格。使用每个顶点的 setLength() 函数可以移动它们以创建位于地球表面正上方的弯曲多边形。
//push each vertex to just above the surface of the globe
for(var i = 0; i < this.polyMesh.geometry.vertices.length; i++){
this.polyMesh.geometry.vertices[i] = this.polyMesh.geometry.vertices[i].setLength(this.surfaceDisplacement);
}
这个解决方案在 2024 年也可以使用吗?或者还有其他更好的方法吗?