【问题标题】:How to maintain WebGL Canvas aspect ratio?如何保持 WebGL Canvas 纵横比?
【发布时间】:2014-05-30 08:22:54
【问题描述】:

我有一个通过 WebGl 绘制的画布。 我的画布尺寸:640 宽 x 480 高。

我在中间画了一个简单的正方形。然而,我惊讶地发现,当它被绘制时,它看起来有点水平拉伸。

我需要做什么才能使这个正方形看起来合适(没有拉伸)? 请注意,我没有使用任何视口设置。我只是在阅读早期的 WebGL 教程。

【问题讨论】:

  • 你能发布你的代码吗?我们不知道您是如何绘制正方形的,无论您是否在执行透视变换之类的操作。

标签: canvas opengl-es webgl


【解决方案1】:

画布的左边缘为 x = -1.0,右边缘为 x = +1.0,上边缘为 y = 1.0,下边缘坐标为 y = -1.0。

换句话说,坐标在视口中被标准化(xy、z 坐标的处理方式略有不同)。这样的坐标在剪辑空间中。

视口的宽度和高度之间的比率称为纵横比。 投影矩阵时使用纵横比。

当您不使用投影矩阵将坐标转换为剪辑空间时,您将直接提供坐标,这些坐标将根据视口的大小进行相应的缩放。

查找有关投影矩阵herehere 的更多详细信息。

要解决您的问题,只需将 x 坐标除以纵横比即可。

【讨论】:

  • 您提供的直接指向相同网址的链接。我想这是你不想要的。无论如何,这个参考很棒,正是我正在寻找的东西! +1
  • 已编辑。第二个链接往往加载缓慢。
【解决方案2】:

您是在 2d 还是 3d 中绘制正方形?没有看到您的代码,很难知道如何提供帮助。

These tutorials generally go over both the 2d and 3d case.

简短的回答是在 WebGL 绘图中,画布从左到右总是在 -1 到 +1 的空间中,从下到上总是在 -1 到 +1 的空间中。

因此,例如,如果您的画布是 300x150,并且您想在 30,40 处绘制一个 10x20 像素的矩形,则您必须以某种方式为 4 个顶点中的每一个设置 gl_Position

clipSpaceX = pixelSpaceX * 2 / canvasWidth  - 1
clipSpaceY = pixelSpaceY * 2 / canvasHeight - 1 

注意:数学将在画布的左下角显示 y。如果您希望 0 在画布顶部,则翻转 y。

clipSpaceY = -(pixelSpaceY * 2 / canvasHeight - 1) 

但是有无数种方法可以获得这些结果。仅举几例 (1) 传入在 JavaScript 中计算的剪辑空间坐标 (2) 传递像素空间坐标并在着色器中进行上述数学运算 (3) 传递一个单位正方形并进行数学运算以将其扩展为您想要的大小.

这完全取决于你。

【讨论】: