我发现自己在 webGl 中使用的许多符号和域约定中有点迷失。查看this regl example (它显示狒狒测试图像)。这是我对它的理解:
- 未指定原语;它可能会推断出
GL_TRIANGLE
。 - 因此,它创建了一个三 Angular 形曲面,其顶点为
(-2, 0)
、(0, -2)
、(2, 2)
在世界空间中。在纸上画出来,看起来这是专门选择的,因为它包含区域[0,1] x [0,1]
。 uv
从世界空间获取它的值,包括这个[0,1] x [0,1]
区域(这是texture2d
)。如果我理解正确的话,惯例是+u
指向图像的右边缘,+v
指向顶部.gl_Position
设置为1 - 2*uv
,让图片占据[-1,1] x [-1,1], z =0
在“剪辑空间”中,不管它是什么。- 更重要的是,这也意味着
+{u,v}
方向对应-{x,y}
!< - 显示的图像,是,实际上是水平镜像!! ( compare to this ) 但它不是垂直镜像。 在最终与屏幕像素坐标之间的转换过程中,肯定有其他因素抵消了 y 中的负因子。
- 但是,Google 搜索没有提供任何证据表明
gl_Position
以任何方式相对于屏幕进行镜像。我看到有人讨论说它是左撇子,但这只是根据相对于世界坐标取反z
的结果。 (e.g. this question here)
简而言之,在我看来,该图像也应该垂直镜像。
我错过了什么?
为了后代,代码转载如下:(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 和您上面的示例中都没有“世界空间”这样的东西。 WebGL 只关心剪辑空间或(规范化设备坐标)。世界空间是应用程序/框架/库处理并提供着色器以最终提供 WebGL 剪辑空间(或规范化设备坐标)的东西
正如 LJ 所指出的,上面的代码不是 webgl,而是 regl,一些库。所以它要做的是那个库而不是 webgl。例如,它可能会翻转它加载的所有纹理,我们怎么知道?也就是说,很容易猜到它会做什么。
对你的问题的简短回答是整个图像被翻转是因为
gl_Position = vec4(1.0 - 2.0 * position, 0, 1);
改成
gl_Position = vec4(position, 0, 1);
你会看到它是颠倒的
它正在绘制一个巨大的三 Angular 形。输入值是
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 /屏幕/帧缓冲区
蓝色区域是屏幕/ Canvas
至于翻转,重要的是要注意纹理没有“向上”的概念。更重要的是要记住纹理坐标 0,0 引用纹理中的第一个像素,1,1 引用纹理中的最后一个像素。
这是应用于该三 Angular 形的纹理坐标
其中纹理中的红点代表纹理坐标中的 0,0。
将 0,0 视为纹理的起点(而不是底部)的原因是,当您渲染到纹理(通过帧缓冲区)时,您不需要进行任何翻转。只有当你最终渲染到屏幕上时,翻转才会起作用,因为 WebGL 在绘制到屏幕时恰好将 -1,-1 放在左下角。
这有点难以解释,但如果您查看 this example您会看到在向/从纹理渲染离屏时不需要翻转。仅当渲染到 Canvas /屏幕时。
如果你想看到大三 Angular 形,把shader改成这个
gl_Position = vec4((1.0 - 2.0 * position) * 0.2, 0, 1);
验证纹理是否翻转here's the original
你可以看到它在 regl 示例中呈现翻转
关于学习WebGL和裁剪空间I'd recommend these tutorials
关于javascript - 为什么这个图像不是垂直镜像的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40331405/