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

WebGL/OpenGL着色器:基于顶点坐标缩放纹理的鼠标中心偏移问题

嘿,这个缩放偏移的问题我太熟悉啦!大概率是变换累积或者坐标转换没处理好导致的,我给你拆解下排查和解决的思路:

核心排查方向

1. 别修改原始顶点数据!

  • 如果你在CPU端每次缩放后直接更新了顶点数组的坐标,那后续缩放都是基于已经变形的顶点来计算的,自然没法以新的鼠标位置为中心正确缩放。
  • 正确姿势:死死保留原始顶点数据不动,所有缩放、平移逻辑都放到Vertex Shader里,用原始顶点 + 实时变换参数来计算最终位置。

2. 鼠标坐标必须转对坐标系

  • 鼠标给你的是屏幕像素坐标,得把它转换成和顶点一致的模型坐标系坐标才能当缩放中心。如果每次缩放后画布的坐标系已经变化,但你没重新计算鼠标对应的模型坐标,肯定会跑偏。
  • 给你个Shader里的正确计算示例参考:
attribute vec2 a_position; // 原始顶点坐标(不变)
uniform vec2 u_scaleCenter; // 转换到模型坐标系的鼠标位置
uniform float u_scaleFactor; // 当前缩放倍数
uniform vec2 u_canvasTranslate; // 画布的平移量(如果有拖动功能)

void main() {
  // 步骤1:把顶点挪到以缩放中心为原点的临时坐标系
  vec2 centeredPos = a_position - u_scaleCenter;
  // 步骤2:应用缩放
  vec2 scaledPos = centeredPos * u_scaleFactor;
  // 步骤3:挪回原坐标系,加上画布平移
  vec2 finalPos = scaledPos + u_scaleCenter + u_canvasTranslate;
  
  gl_Position = vec4(finalPos, 0.0, 1.0);
}
  • 关键细节:每次缩放时,u_scaleCenter必须是原始模型坐标系下的鼠标位置,不是经过缩放/平移后的屏幕坐标直接转过来的值。

3. 缩放参数累积时要反推原始坐标

  • 如果你是累积缩放(比如滚轮滚一次,缩放倍数就乘1.1),那每次计算缩放中心时,得把当前屏幕鼠标坐标反推回原始模型坐标。
  • 举个公式例子:假设当前画布已经有缩放倍数currentScale和平移量currentTranslate,那么屏幕鼠标坐标screenMouse对应的原始模型坐标是:(screenMouse - currentTranslate) / currentScale。
  • 要是跳过这步直接用屏幕坐标当中心,后续缩放必然会偏移。

4. 快速验证法

  • 你可以先做个极简测试:每次缩放前把所有变换参数重置(缩放倍数回到1,平移量归0),然后只应用当前的鼠标中心和缩放倍数。如果这时候缩放正常,那百分百是之前的变换累积没正确处理缩放中心的转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:35:56