为什么这个图像不是垂直镜像的?

Why is this image not mirrored vertically?

我发现自己在 webGl 中使用的许多符号和域约定中有点迷失。查看 this regl example(显示狒狒测试图像)。这是我的理解:

简而言之,我觉得这张图片也应该垂直镜像。

我错过了什么?


为了后代,代码转载如下:(MIT licensed)

const regl = require('regl')()
const baboon = require('baboon-image')

regl({
  frag: `
  precision mediump float;
  uniform sampler2D texture;
  varying vec2 uv;
  void main () {
    gl_FragColor = texture2D(texture, uv);
  }`,

  vert: `
  precision mediump float;
  attribute vec2 position;
  varying vec2 uv;
  void main () {
    uv = position;
    gl_Position = vec4(1.0 - 2.0 * position, 0, 1);
  }`,

  attributes: {
    position: [
      -2, 0,
      0, -2,
      2, 2]
  },

  uniforms: {
    texture: regl.texture(baboon)
  },

  count: 3
})()

WebGL 和您上面的示例中都没有 "world space" 这样的东西。 WebGL 只关心剪辑 space 或(规范化设备坐标)。 World space 是 app/framework/library 处理并提供着色器以最终提供 WebGL 剪辑 space(或规范化设备坐标)

正如 LJ 所指出的,上面的代码不是 webgl,而是 regl,一些库。所以它要做的是那个库而不是 webgl。例如,它可能会翻转它加载的所有纹理,我们怎么知道?也就是说很容易猜到它会做什么。

对你的问题的简短回答是整个图像被翻转是因为

gl_Position = vec4(1.0 - 2.0 * position, 0, 1);

改为

gl_Position = vec4(position, 0, 1);

你会看到它是颠倒的

它正在绘制一个巨大的三角形。输入值为

  position: [
      -2, 0,
      0, -2,
      2, 2]
  },

和这一行

gl_Position = vec4(1.0 - 2.0 * position, 0, 1);

表示写入gl_Position的值是

1 - 2 * -2, 1 - 2 *  0
1 - 2 *  0, 1 - 2 * -2
1 - 2 *  2, 1 - 2 *  2

这是

 5,  1
 1,  5
-3, -3

如果我们相对于 canvas/screen/framebuffer 绘制它,我们得到

其中蓝色区域是screen/canvas

至于翻转,重要的是要注意纹理没有 "up" 概念。更重要的是要记住纹理坐标 0,0 引用纹理中的第一个像素,1,1 引用纹理中的最后一个像素。

这是应用于该三角形的纹理坐标

其中纹理中的红点代表纹理坐标中的0,0。

将 0,0 视为纹理的起点(而不是底部)的原因是,当您渲染到纹理(通过帧缓冲区)时,您不需要进行任何翻转。只有当你最终渲染到屏幕上时,翻转才会起作用,因为 WebGL 在绘制到屏幕时恰好将 -1,-1 放在左下角。

这有点难以解释,但如果您查看 this example,您会发现渲染离屏 to/from 纹理时不需要翻转。仅在渲染到 canvas/screen.

如果你想看到大三角形,把着色器改成这个

gl_Position = vec4((1.0 - 2.0 * position) * 0.2, 0, 1);

验证纹理是否翻转here's the original

并且您可以在 regl 示例中看到翻转的渲染

至于学习WebGL和剪辑spaceI'd recommend these tutorials