如何保持WebGL Canvas宽高比?

问题描述 投票:0回答:3

我有一个 Canvas,我正在通过 WebGl 进行绘制。 我的画布尺寸:640 宽 x 480 高。

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

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

canvas opengl-es webgl
3个回答
5
投票

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

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

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

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

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

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


1
投票

您正在绘制 2d 或 3d 正方形吗?如果不看到您的代码,很难知道如何提供帮助。

这些教程通常会介绍 2d 和 3d 情况

简短的答案是,在 WebGL 中绘制画布时,从左到右始终处于 -1 到 +1 的空间,从下到上处于 -1 到 +1 的空间。

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


gl_Position

注意:该数学运算将使用画布左下角的 y 进行。如果您希望 0 位于画布顶部,请翻转 y。

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

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

这真的取决于你。


0
投票

问题出在 DPI / 设备像素比 (DPR) 上,可以通过 window.devicePixelRatio 看到。您可以根据此值校正对象大小,您将看到几乎正确的大小(以像素为单位)。
  1. 不幸的是,即使您达到 1:1 的尺寸,纹理也会被修改。它看起来会像抗锯齿之类的。我关闭了抗锯齿功能,但纹理仍然被修改。
  2. 自从我寻找一种无需修改即可获得纹理 1:1 的方法后,我发现了唯一的方法 - 将浏览器缩放至 80%。这会导致 1:1 DPR 并显示所有未受影响的纹理(像素到像素)。我想如果用户想看到完美的纹理,我会要求用户缩小浏览器,并且我可以显示 DPR 值,直到它为 1。
© www.soinside.com 2019 - 2024. All rights reserved.