Three.js中使用Raycaster点击平面绘制点时坐标异常问题求助
解决Three.js Raycaster点击平面坐标错误的问题
先给你揪出最明显的问题——代码里有个语法错误,这大概率是导致坐标计算完全跑偏的核心原因:
1. 修复坐标转换的语法错误
你写的这行代码里,*2 1是不合法的写法,Three.js将屏幕坐标转成标准化设备坐标(NDC)时,正确的计算应该是*2 - 1:
// 错误写法 pointer.x = ((event.clientX - canvas.left) / canvas.width) * 2 1; // 正确写法 pointer.x = ((event.clientX - canvas.left) / canvas.width) * 2 - 1;
标准化设备坐标的范围是[-1, 1],这一步写错会直接让Raycaster发射的射线方向完全错误,自然得不到正确的平面交点。
2. 补上设备像素比的修正(高DPI屏幕必看)
如果你的canvas用CSS做了缩放,或者页面在高分辨率屏幕上运行,得把坐标乘以设备像素比来对齐Three.js的渲染分辨率:
const dpr = window.devicePixelRatio || 1; pointer.x = (((event.clientX - canvas.left) * dpr) / canvas.width) * 2 - 1; pointer.y = -(((event.clientY - canvas.top) * dpr) / canvas.height) * 2 + 1;
这是因为getBoundingClientRect()拿到的是canvas的CSS布局尺寸,而Three.js是基于canvas的实际像素尺寸渲染的,两者不一致就会出现坐标偏移。
3. 检查射线检测的递归设置
你调用intersectObjects(scene.children, false)时第二个参数是false,这意味着不会递归查找子对象。如果你的plane是某个父对象的子元素,就会被漏掉。可以改成true确保能检测到所有层级的对象:
const intersects = this.raycaster.intersectObjects(scene.children, true);
如果plane确实是scene的直接子元素,这一步可能不需要,但开着递归也没坏处,能避免后续嵌套对象的检测问题。
4. 验证相机的基础设置
最后再确认下相机的参数是否合理:
- 如果是
PerspectiveCamera,检查aspect是否等于canvas的宽高比(canvas.width / canvas.height),这个参数错了会导致整个场景的投影变形 - 确保相机的位置能看到平面,别让平面跑到相机的视锥体外面去了
你先把第一个语法错误改了,再一步步排查其他点,应该就能解决坐标错误的问题了。
内容的提问来源于stack exchange,提问作者goldarea
相关产品推荐
相关产品推荐

