如何基于Shape生成覆盖其区域的点集以查找距相机最近点
问题描述
我正在尝试勾勒对象的3D元素轮廓,以实现元素的可选中功能。
在2D场景下,使用Shape即可轻松实现该功能,参考代码如下:
const shape = new Shape(); if (!points.length) return shape; for (const point of points) shape.lineTo(point[0], point[1]); if (mousePos) shape.lineTo(mousePos[0], mousePos[1]); return shape;
在3D场景中的实现思路:通过鼠标沿实体轮廓绘制,使用点云填充轮廓间隙,再通过raycaster遍历每个点,将点调整为与mesh相交且距离相机最近的位置,最终得到贴合底层mesh的点轮廓。
核心疑问:如果已经获得一个Shape对象,最简单的创建覆盖该Shape区域点集的方式是什么,以便查找距离相机最近的点?
解决方案
不需要手动实现复杂的多边形区域填充算法,直接基于Three.js的内置能力就能快速生成所需点集,步骤如下:
- 优先用
ShapeGeometry做基础几何生成:将已有的Shape实例作为入参直接创建ShapeGeometry对象,它会自动对Shape的闭合区域做三角剖分,天然覆盖整个轮廓范围。 - 按需求选择采样方式拿到点集:
- 快速实现:直接读取
ShapeGeometry实例的attributes.position属性,里面存储的所有三角面顶点就是均匀分布在Shape区域内的点,不需要额外计算,适合点密度要求不高的场景。 - 自定义密度采样:如果需要精确控制点云密度,先获取Shape的2D包围盒,按你设定的步长在包围盒范围内生成等间距栅格点,调用Shape自带的
containsPoint(x, y)方法过滤掉所有落在轮廓外的点,剩余点就是完全覆盖Shape区域的规整点集,这种方式生成的点分布均匀、密度可控,最适配后续raycaster逐点检测的需求。
- 快速实现:直接读取
- 坐标对齐后做射线投射:把所有2D点转换到和你绘制Shape时一致的坐标空间(通常是对齐相机视口的平面),逐点从相机位置发射穿过对应点的射线,和目标mesh做相交检测,取距离相机最近的交点坐标替换原2D点,最终就能得到贴合mesh表面的3D轮廓点云。
注意:如果你的Shape是在屏幕像素空间绘制的,做射线检测前需要先把点坐标转换为归一化设备坐标(NDC),避免坐标空间不匹配导致相交检测结果错误。
内容的提问来源于stack exchange,提问作者GrandMassive
相关产品推荐
相关产品推荐

