如何在webgl中缩放纹理?

S.C*_*.C. 1 matrix aspect-ratio webgl

我有一个大小为 800x600 的纹理。如何<canvas> 在另一个尺寸的 webgl上缩放它并保持原始纵横比?假设绘图缓冲区和画布具有相同的尺寸。

gma*_*man 6

鉴于 WebGL 只关心剪辑空间坐标,您只需绘制一个 2 个单位的四边形(-1 到 +1)并根据画布的方面与图像的方面进行缩放。

换句话说

  const canvasAspect = canvas.clientWidth / canvas.clientHeight;
  const imageAspect = image.width / image.height;

  let scaleY = 1;
  let scaleX = imageAspect / canvasAspect;
Run Code Online (Sandbox Code Playgroud)

请注意,您需要决定如何适合图像。scaleY= 1意味着图像将始终适合垂直和水平方向,无论结果如何。

如果您希望它水平放置,则需要使 scaleX = 1

  let scaleX = 1;
  let scaleY = canvasAspect / imageAspect;
Run Code Online (Sandbox Code Playgroud)

如果你想要它contain那么

  let scaleY = 1;
  let scaleX = imageAspect / canvasAspect;
  if (scaleX > 1) {
    scaleY = 1 / scaleX;
    scaleX = 1;
  }
Run Code Online (Sandbox Code Playgroud)

如果你想要它cover那么

  let scaleY = 1;
  let scaleX = imageAspect / canvasAspect;
  if (scaleX < 1) {
    scaleY = 1 / scaleX;
    scaleX = 1;
  }
Run Code Online (Sandbox Code Playgroud)

  const canvasAspect = canvas.clientWidth / canvas.clientHeight;
  const imageAspect = image.width / image.height;

  let scaleY = 1;
  let scaleX = imageAspect / canvasAspect;
Run Code Online (Sandbox Code Playgroud)
  let scaleX = 1;
  let scaleY = canvasAspect / imageAspect;
Run Code Online (Sandbox Code Playgroud)
  let scaleY = 1;
  let scaleX = imageAspect / canvasAspect;
  if (scaleX > 1) {
    scaleY = 1 / scaleX;
    scaleX = 1;
  }
Run Code Online (Sandbox Code Playgroud)

上面的代码使用 4x4 矩阵来应用比例

  gl_Position = u_matrix * position;
Run Code Online (Sandbox Code Playgroud)

它可以很容易地直接传入秤

  uniform vec2 scale;
  ...
  gl_Position = vec4(scale * position.xy, 0, 1);
Run Code Online (Sandbox Code Playgroud)