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

WebGL鼠标跟随圆形适配问题:跨设备及窗口Resize时定位异常

解决鼠标跟随圆形在不同分辨率/窗口Resize时的偏移问题

问题背景

实现了鼠标指针跟随圆形绘制功能,在1920×932的PC视口上显示正常,但在1280×593的笔记本视口上圆形无法精准跟随鼠标。硬编码视口尺寸为vec2(1920,932)时,笔记本上显示正常,但窗口Resize后偏移问题复现;PC端Resize时无异常。需要实现圆形在任意屏幕尺寸或窗口Resize时都能精准跟随鼠标。

问题根源

当前片段着色器中,宽高比校正逻辑存在错误:代码以鼠标点为原点对UV坐标进行缩放,导致坐标空间错位。当设备视口宽高比与硬编码值存在差异时,圆形就会偏离鼠标位置。

修正后的代码

export const fragment = `
varying vec2 vUv;
uniform vec2 viewport;
uniform vec2 uMouse;

float createCircle() {
    // 将视口像素坐标转换为归一化UV(范围0-1)
    vec2 viewportUv = gl_FragCoord.xy / viewport;
    // 计算视口宽高比
    float viewportAspect = viewport.x / viewport.y;
    
    // 翻转鼠标Y轴(适配WebGL坐标系,Y轴向下为正)
    vec2 mousePoint = vec2(uMouse.x, 1.0 - uMouse.y);
    
    // 计算等比例缩放因子,以较短边为基准保持坐标空间为正方形
    vec2 center = vec2(0.5);
    
    // 将视口UV转换到无拉伸的等比例空间
    vec2 normalizedViewportUv = (viewportUv - center) * vec2(
        viewportAspect < 1.0 ? viewportAspect : 1.0,
        viewportAspect > 1.0 ? 1.0 / viewportAspect : 1.0
    ) + center;
    // 将鼠标坐标同步转换到同一等比例空间
    vec2 normalizedMousePoint = (mousePoint - center) * vec2(
        viewportAspect < 1.0 ? viewportAspect : 1.0,
        viewportAspect > 1.0 ? 1.0 / viewportAspect : 1.0
    ) + center;
    
    // 调试:标记鼠标位置(红色)
    if (length(normalizedViewportUv - normalizedMousePoint) < 0.01) {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
    
    // 计算圆形半径:基于视口宽度保持固定像素大小
    float circleRadius = max(0.0, 100.0 / viewport.x);
    // 计算当前像素到鼠标点的距离
    float dist = distance(normalizedViewportUv, normalizedMousePoint);
    // 平滑过渡圆形边缘
    dist = smoothstep(circleRadius, circleRadius + 0.001, dist);

    return dist;
}

void main() {
    float circle = createCircle();
    // 绘制点精灵的圆形遮罩
    float dist = length(gl_PointCoord - vec2(0.5));
    float disc = smoothstep(0.5, 0.45, dist);

    gl_FragColor = vec4(disc * circle);

    // 剔除透明区域
    if (disc < 0.01) discard;
}`;

关键修正点

  • 改用基于视口中心的等比例坐标转换,确保视口UV与鼠标坐标处于同一无拉伸的坐标空间,彻底解决宽高比差异导致的偏移。
  • 同步对鼠标坐标和视口UV做相同的转换逻辑,保证两者相对位置始终一致。
  • 保留原鼠标Y轴翻转逻辑(若CPU端已将鼠标坐标转换为WebGL坐标系,可移除1.0 - uMouse.y)。
  • 圆形半径计算逻辑保留,确保不同分辨率下圆形物理像素大小一致。

内容的提问来源于stack exchange,提问作者demo test

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 16:12:49