我正在研究渲染管道,当我到达剪辑阶段时,我们解释说,从视图(眼睛或相机)空间我们必须传递到剪辑空间,也称为 normalized device space (NDC),这是一个立方空间 - 1比1 .
但是,现在我不明白从这个空间到屏幕坐标空间的通道何时发生:
剪切后和光栅化之前?
光栅化后和剪刀和z测试之前?
在写入帧缓冲区之前的最后?
剪辑空间实际上距离NDC一步,所有坐标除以 Clip.W 以产生NDC . 在得到的NDC空间中超出范围[ -1 , 1 ]的任何内容都对应于裁剪体积之外的点 . NDC之前的坐标空间被称为剪辑空间是有原因的;)
Clip.W
然而,严格来说,NDC空间不一定是立方的 . 确实,NDC空间是OpenGL中的一个多维数据集,但在Direct3D中它不是 . 在D3D中,NDC空间中的Z坐标范围为 0.0 至 1.0 ,而GL中的范围为 -1.0 至 1.0 . X和Y在GL和D3D中表现相同(即,它们的范围从 -1.0 到 1.0 ) . NDC是标准坐标空间,但它在不同的API中具有不同的表示 .
最后,在光栅化期间发生NDC空间到屏幕空间(AKA窗口空间),并由视口和深度范围定义 . 碎片位置在任何其他坐标空间中都没有意义,这就是光栅化产生的: fragments .
在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
剪辑空间和NDC(规范化设备坐标)不是一回事,否则它们将没有不同的名称 .
剪辑空间是投影矩阵进行点变换后空间点所在的位置,但是在 w 进行归一化之前 .
w
NDC空间是 w 规范化后的空间点 .
http://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/projection-matrix-GPU-rendering-pipeline-clipping
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)
显然,据Apple称,剪辑空间与NDC相同 .
https://developer.apple.com/documentation/metal/hello_triangle
引用:
“顶点函数(也称为顶点着色器)的主要任务是处理传入的顶点数据并将每个顶点映射到视口中的位置 . 这样,管道中的后续阶段可以引用此视口位置并渲染像素顶点函数通过将任意顶点坐标转换为标准化设备坐标(也称为剪辑空间坐标)来完成此任务 .
示例代码中的注释的另一个引用:
“每个顶点着色器的输出位置都在剪辑空间中(也称为规范化设备坐标空间或NDC) . ”
也许这是因为教程是二维的?误导性陈述..
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空间通常是左手系统 .
4 回答
不,剪辑空间和NDC空间不是一回事 .
剪辑空间实际上距离NDC一步,所有坐标除以
Clip.W
以产生NDC . 在得到的NDC空间中超出范围[ -1 , 1 ]的任何内容都对应于裁剪体积之外的点 . NDC之前的坐标空间被称为剪辑空间是有原因的;)然而,严格来说,NDC空间不一定是立方的 . 确实,NDC空间是OpenGL中的一个多维数据集,但在Direct3D中它不是 . 在D3D中,NDC空间中的Z坐标范围为 0.0 至 1.0 ,而GL中的范围为 -1.0 至 1.0 . X和Y在GL和D3D中表现相同(即,它们的范围从 -1.0 到 1.0 ) . NDC是标准坐标空间,但它在不同的API中具有不同的表示 .
最后,在光栅化期间发生NDC空间到屏幕空间(AKA窗口空间),并由视口和深度范围定义 . 碎片位置在任何其他坐标空间中都没有意义,这就是光栅化产生的: fragments .
更新:
在OpenGL 4.5中引入,扩展GL_ARB_clip_control允许您在GL中采用D3D的NDC约定 .
传统的OpenGL行为是:
Direct3D行为可以通过以下方式实现:
剪辑空间和NDC(规范化设备坐标)不是一回事,否则它们将没有不同的名称 .
剪辑空间是投影矩阵进行点变换后空间点所在的位置,但是在
w
进行归一化之前 .NDC空间是
w
规范化后的空间点 .显然,据Apple称,剪辑空间与NDC相同 .
https://developer.apple.com/documentation/metal/hello_triangle
引用:
“顶点函数(也称为顶点着色器)的主要任务是处理传入的顶点数据并将每个顶点映射到视口中的位置 . 这样,管道中的后续阶段可以引用此视口位置并渲染像素顶点函数通过将任意顶点坐标转换为标准化设备坐标(也称为剪辑空间坐标)来完成此任务 .
示例代码中的注释的另一个引用:
“每个顶点着色器的输出位置都在剪辑空间中(也称为规范化设备坐标空间或NDC) . ”
也许这是因为教程是二维的?误导性陈述..
NDC空间是剪辑空间,NDC空间到窗口空间由硬件完成,发生在NDC之后和光栅化之前 .
有API来设置宽度和高度,默认值与窗口大小相同 .
OpenGL的NDC空间,xyz范围[-1,1] . 对于Metal,Z为0到1
NDC空间通常是左手系统 .