You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js Raycasting坐标偏移:Shader红点与鼠标位置不匹配求助

问题分析与解决方案建议

核心排查方向

从红点偏移随滚动距离变化的特征来看,问题大概率出在屏幕坐标到Shader空间的转换环节,没有正确处理视图滚动、坐标原点差异或画布缩放适配。以下是具体排查点:

1. 鼠标坐标的原点匹配错误

浏览器鼠标坐标默认以页面左上角为原点,但Shader中纹理/模型空间通常以左下角为原点,这会直接导致Y轴方向的偏移。检查代码是否对鼠标Y坐标做了翻转处理:

// 错误:直接传入浏览器原始Y坐标
vec2 mouse = vec2(u_mouseX, u_mouseY);
// 正确:基于画布高度翻转Y轴
vec2 mouse = vec2(u_mouseX, u_canvasHeight - u_mouseY);

2. 滚动偏移未做补偿

偏移随滚动距离变化,说明没有把页面滚动的scrollTop/scrollLeft纳入坐标计算。传递鼠标坐标前必须扣除滚动偏移:

const rect = canvas.getBoundingClientRect();
// 获取鼠标在画布内的相对坐标(已扣除滚动和边框偏移)
const mouseX = event.clientX - rect.left;
const mouseY = event.clientY - rect.top;
// 将处理后的坐标传入Shader的uniform变量

3. 画布DPI与缩放适配缺失

如果页面存在缩放或未适配设备像素比(DPR),会导致坐标映射比例错误。确保传入Shader的坐标基于画布实际像素尺寸:

const dpr = window.devicePixelRatio || 1;
const mouseX = (event.clientX - rect.left) * dpr;
const mouseY = (event.clientY - rect.top) * dpr;

同时在Shader中归一化坐标时,要使用画布的实际像素宽高:

vec2 normalizedMouse = mouse / vec2(u_canvasWidth, u_canvasHeight);

4. 3D模型空间的坐标转换遗漏

如果是在3D模型表面绘制选中点,不能直接将屏幕坐标映射到模型UV,必须通过unproject方法将屏幕坐标转换为世界空间射线,再与模型求交得到表面坐标。

代码检查重点

对照你的实现,优先确认:

  • 鼠标坐标是否扣除了页面滚动偏移和画布边框
  • Shader中是否完成了鼠标坐标的原点翻转与归一化
  • 画布实际像素尺寸与CSS显示尺寸是否一致,是否适配了DPR

效果截图

内容的提问来源于stack exchange,提问作者Bn'R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 23:12:06