然而,现在我不明白从这个空间到屏幕坐标空间的转换是在何时进行的:
剪裁之后、光栅化之前吗?
光栅化之后、剪切和z测试之前吗?
最后在写入帧缓冲器之前?
Clip.W
以产生NDC。在结果NDC空间中范围在[-1,1]之外的任何东西都对应于位于剪切体积之外的点。在NDC之前的坐标空间被称为剪裁空间有其原因 ;)在OpenGL 4.5中引入了扩展GL_ARB_clip_control
,允许您在GL中采用D3D的NDC约定。
glClipControl (GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE);
glClipControl (GL_UPPER_LEFT, GL_ZERO_TO_ONE); // Y-axis is inverted in D3D
“剪辑空间”和“标准化设备坐标”并不是同一个概念,否则它们就不会有不同的名称。
“剪辑空间”是指经过投影矩阵变换后,但在通过 w
标准化之前的点的坐标系。
“标准化设备坐标”是指经过通过 w
标准化后的点的坐标系。
Camera space -->
x projection matrix --->
Clip space (before normalisation) --->
Clipping --->
Normalisation by w (x/w, y/w, z/w) --->
NDC space (in the range [-1, 1] in x and y)
https://developer.apple.com/documentation/metal/hello_triangle
“引用:”你可以将从剪辑空间(在图像内的每个轴上为-1到+1)到屏幕坐标系的转换,也称为视口空间(在X轴上为0到ResX,在Y轴上为0到resY,在Z轴上为0到1,即深度),看作是在顶点处理器之后、光栅化之前发生的。
当你编写顶点着色器时,输出的是顶点在剪辑空间中的投影位置,但在片段着色器中,每个片段都有自己的屏幕坐标和深度。
剪辑空间是一个“空间”,正如其名称所示,它是一个参考框架、坐标系统,即一种特定的原点和三个轴的选择,用于指定点和向量。
它的原点位于剪辑体的中心,其三个轴按API指定的方式对齐。例如,该空间中笛卡尔坐标为(+1,0,0)的点出现在图像的右端,而坐标为(-1,0,0)的点出现在左端。
NDC(规范化设备坐标)是一组坐标,如其名称所示,它们是剪裁空间中点的三个笛卡尔坐标。例如,取一个齐次坐标为(3,0,0,3)的剪裁空间点,您也可以表示为(30,0,0,30)等多种方式,并且具有笛卡尔坐标(1,0,0),其NDC为(1,0,0)。
NDC空间是剪裁空间,在NDC空间到窗口空间的转换是由硬件实现的,在NDC和光栅化之间发生。
有API可以设置宽度和高度,默认值与窗口大小相同。
// metal
func setViewport(_ viewport: MTLViewport)
// OpenGL
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
OpenGL中的NDC空间,xyz范围为[-1, 1]。而在Metal中,Z轴范围是0到1。
NDC空间通常采用左手坐标系。
w
坐标定义了剪裁体在剪裁空间和 NDC 空间中的范围,但在 NDC 空间中,w
是 1.0 并且所有内容都已经被标准化。在剪裁空间中,每个顶点可以存在自己的比例,由不同的w
坐标定义;一旦转换到 NDC 空间中,所有顶点都达成一致并且更容易处理。 - Andon M. Colemanw
值--这就是透视的来源,但它不是剪裁空间的自动部分。经过透视除法后,一旦所有内容都在NDC空间中,透视会导致具有不同剪裁空间w
坐标的任何顶点扩散开来。正交投影在剪裁空间中同样有效,并且不会导致这种情况。 - Andon M. Coleman