我正在尝试在 JavaScript 中执行与在顶点着色器中相同的转换。我的顶点着色器正在像典型的 WebGL 示例一样转换顶点:
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0)
我的 Canvas 是 600x600px(但在这种情况下 Canvas 大小是无关紧要的。)
生成的 gl_Position.xy 不是我所期望的。它不是在 0,600 或 -300,300 或 -1,1 范围内,而是大约在 -6,6 范围内。 (我最终在着色器中编写了测试,例如:如果转换后的 gl_Position.x > 5.0 将其着色为红色。)
无论 Canvas 大小如何,-6,6(或 12x12)绘图区域保持不变。
添加比例因子并通过肉眼对其进行调整后,我成功地将我的 javascript 转换与着色器转换同步了。但是如何从 WebGL 获取转换后的顶点的绘图区域的大小呢? -6,6 范围是如何确定的?
最佳答案
如果您真的想匹配顶点变换,您会忽略一些发生在之后可编程顶点变换的操作。
您忘记了 gl_Position.xyz
在获得您在问题中讨论的 NDC 或屏幕空间坐标之前仍然需要进行一些转换。
在顶点着色器之后和光栅化之前发生了透视划分 (
pos.xyz
/=pos.w
)- 给定一个正交投影矩阵,这应该是一个空操作,
pos.w
将始终是1.0
...
- 给定一个正交投影矩阵,这应该是一个空操作,
- 还有一个视口(viewport)变换,可以将坐标从 NDC 空间中取出并放入屏幕空间中。
- 视口(viewport)变换与其他所有变换略有不同,因为视口(viewport)不是使用矩阵定义的,它基本上只定义缩放和偏置操作,对裁剪没有影响。
花点时间回顾一下这个插图:
(来源:songho.ca)
在此图中,顶点着色器的输出标记为Clip Coordinates
(剪辑空间),您应该知道原始组装和光栅化是转换为Window Coordinates的地方
(屏幕空间)终于完成了。此外,上面要点中讨论的两个操作不是可编程流水线的一部分。
如果您想知道,图表来自 Song Ho Ahn (안성호) 的网站。它是标题为 『OpenGL Transformation』 的文章的一部分,这可能有助于强化我在此答案中讨论的内容。
关于opengl-es-2.0 - WebGL:顶点着色器变换和应用程序/软件变换之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19340201/