如何解决鼠标悬停元素时粒子提前偏移的顶点着色器问题
问题:文字粒子未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; }
问题原因与修复方案
核心原因
- 鼠标距离计算逻辑未做严格范围限制:即便鼠标离粒子很远,当前公式仍可能产生非零值,触发粒子偏移。
- uMouse初始位置不合理:若初始值设为靠近粒子群的坐标(比如(0,0,0)),会导致粒子一开始就触发位移逻辑。
修复步骤
- 限制鼠标影响范围:修改
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;
- 初始化uMouse到安全位置:在JS代码中,将uMouse初始值设为远离粒子群的坐标(比如
new THREE.Vector3(9999, 9999, 0)),仅当鼠标悬停在元素上时,才更新uMouse为实际鼠标坐标。
内容的提问来源于stack exchange,提问作者hello
相关产品推荐
相关产品推荐

