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

如何解决鼠标悬停元素时粒子提前偏移的顶点着色器问题

问题:文字粒子未hover就提前偏移

我用ShaderMaterial实现了交互式文字粒子效果,将光标位置作为uniform传入,根据粒子与光标的距离控制粒子位移。功能可正常运行,但存在问题:鼠标还未悬停到元素上,粒子就已发生偏移。

顶点着色器代码

uniform vec3 uMouse;
uniform float uSize;
uniform float uPixelRatio;
uniform float uTime;

attribute float aScale;
attribute float pindex;
attribute float angle;

void main()
{
    /**
     * Position
     */
     //local
    float rndz = (random(pindex) + snoise(vec2(pindex * 0.1, uTime * 0.1)));

    vec3 particlePosition = (modelMatrix * vec4(position, 1.0)).xyz;
    
    float distanceToMouse = pow(1. - clamp(length(uMouse.xy - particlePosition.xy) -.03, -4., 1.), 2.5);

    particlePosition.x -= distanceToMouse * 0.5 * rndz * cos(angle);
    particlePosition.y -= distanceToMouse * 0.5 * rndz * sin(angle);

    //camera

    vec4 viewPosition = viewMatrix * vec4(particlePosition, 1.);

    gl_Position = projectionMatrix * viewPosition;

    //size
    gl_PointSize = uSize * aScale * uPixelRatio;
}

问题原因与修复方案

核心原因

  1. 鼠标距离计算逻辑未做严格范围限制:即便鼠标离粒子很远,当前公式仍可能产生非零值,触发粒子偏移。
  2. uMouse初始位置不合理:若初始值设为靠近粒子群的坐标(比如(0,0,0)),会导致粒子一开始就触发位移逻辑。

修复步骤

  1. 限制鼠标影响范围:修改distanceToMouse的计算逻辑,仅当鼠标与粒子的距离小于设定阈值时才生效,否则偏移强度设为0:
float mouseDistance = length(uMouse.xy - particlePosition.xy);
// 阈值可根据场景调整,示例设为0.5
float distanceToMouse = mouseDistance < 0.5 ? pow(1. - clamp(mouseDistance - 0.03, 0., 1.), 2.5) : 0.0;
  1. 初始化uMouse到安全位置:在JS代码中,将uMouse初始值设为远离粒子群的坐标(比如new THREE.Vector3(9999, 9999, 0)),仅当鼠标悬停在元素上时,才更新uMouse为实际鼠标坐标。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 02:15:58