3D数学中MVP矩阵运算后,设备归一化是在管线的哪一个阶段完成的?

Number of views 289

MVP矩阵运算是在顶点着色阶段进行的,能详细解释下后面都发生了什么嘛?比如设备归一化是在哪个阶段进行的?图元装配?光栅化?片元着色器?以及片元着色器之后发生的详细事情?

2 Answers

看了下AI的回复,大体上都没什么问题,关于裁剪空间与规范化设备坐标做点补充:
在顶点着色器后,顶点坐标通常被转换到裁剪空间(Clip Space),这是一个四维齐次坐标系。裁剪空间中的坐标经过透视除法后,转换为规范化设备坐标(Normalized Device Coordinates, NDC),范围为 [-1, 1]。
接着会有屏幕映射即视口变换的过程:
视口变换将NDC中的坐标映射到屏幕上的实际像素位置,如实际屏幕宽高为(1920, 1080)。
image.png
对于光栅化阶段的三角形覆盖,并不是所有的像素都会被一个三角形完整地覆盖,有相当多的情况都是一个像素块内只有一部分被三角形覆盖,对于这种情况,有三种解决方案:常用的有Standard Rasterization(中心点被覆盖即被划入片元)、Outer-conservative Rasterization(只要被覆盖了,哪怕只有一点也被划入片元)、Inner-conservative Rasterization(完全被覆盖才会被划入片元)。值得注意的是,片元不是真正意义上的像素,而是包含了很多种状态的集合(譬如屏幕坐标、深度、法线、纹理等),这些状态用于最终计算出每个像素的颜色。
所以这一阶段就会有抗锯齿(Anti-aliasing)相关的操作。因为不管用什么方式划分片元,三角形边缘部分总会显得很锐利。所以多重采样抗锯齿(MultiSampling Anti-Aliasing,MSAA)应运而生,这种抗锯齿方法对中心点不在三角形内的边缘处采用多增加同一个像素块内的采样点解决,具体算法这里不过多说明。

在经过AI已经说明的各个阶段,片元颜色就会被送到颜色缓冲区。GPU会使用双重缓冲(Double Buffering)的策略,即屏幕上显示前置缓冲(Front Buffer),而渲染好的颜色先被送入后置缓冲(Back Buffer),再替换前置缓冲,以此避免在屏幕上显示正在光栅化的图元。

在3D图形渲染管线中,MVP(模型视图投影)矩阵运算是顶点处理阶段的一部分。这个阶段主要负责将顶点从局部坐标系转换到屏幕坐标系,以便能够在屏幕上正确显示。MVP矩阵是由模型矩阵、视图矩阵和投影矩阵组合而成的。

以下是MVP矩阵运算后的各个阶段的详细流程:

  1. 顶点着色器阶段:在这一阶段,输入顶点经过MVP矩阵变换,从局部坐标系转换到屏幕坐标系。此外,顶点着色器还可以执行其他自定义操作,如光照计算等。

  2. 裁剪:经过MVP变换后的顶点会进入裁剪阶段。在这个阶段,管线会检查顶点是否位于视锥体内。如果顶点在视锥体外,则会被裁剪掉;如果顶点在视锥体内,则会被保留下来。

  3. 设备归一化:裁剪后的顶点会被标准化为设备坐标系。在设备坐标系中,所有顶点的x、y和z坐标范围都被归一化为[-1, 1],而w坐标通常是1。这个过程被称为设备归一化(Device Normalization),它是在裁剪之后进行的。

  4. 透视除法:在设备归一化之前,顶点坐标通常是以齐次坐标形式表示的。为了将齐次坐标转换为欧几里得坐标,需要进行透视除法。透视除法即将顶点的x、y和z坐标分别除以w坐标,从而实现透视效果。透视除法实际上也包含在设备归一化的过程中。

  5. 图元装配:经过设备归一化后,顶点会被组织成图元(如三角形、线段等)。这些图元将被传递给下一个阶段。

  6. 光栅化:在光栅化阶段,图元被转换为像素或片段(fragment)。每个片段对应于屏幕上一个特定位置的像素。光栅化过程还会计算每个片段的颜色和其他属性。

  7. 片元着色器:每个片段都会通过片元着色器进行处理。片元着色器可以根据片段的位置和其他属性来计算颜色、深度值等信息。此外,片元着色器也可以进行纹理映射、光照计算等操作。

  8. 深度测试和混合:经过片元着色器处理后的片段会进行深度测试,以确定它们是否应该覆盖现有的像素。如果通过了深度测试,片段的颜色将与现有像素的颜色进行混合。这一步骤确保了正确的可见性排序。

  9. 输出合并:最终,所有处理过的片段会被合并成最终的图像,并显示在屏幕上。

总结一下,设备归一化是在裁剪阶段之后进行的,它属于顶点处理阶段的一部分。设备归一化完成后,顶点会被组织成图元并进行光栅化,然后进入片元着色器阶段进行进一步处理。

光栅化阶段主要做了哪些事

光栅化阶段是3D图形渲染管线中的一个重要步骤,它的主要任务是将图元(如三角形)转换为像素(片段),并将这些片段分配到屏幕上相应的像素位置。以下是光栅化阶段的主要任务和步骤:

  1. 三角形覆盖

    • 光栅化首先确定三角形在屏幕上的覆盖区域。这涉及到计算三角形的边界框,并确定哪些像素被三角形所覆盖。
  2. 片段生成

    • 对于每个被三角形覆盖的像素,光栅化器会生成一个片段(fragment)。片段是一个具有位置(x, y)、深度(z)和其他属性(如颜色、纹理坐标等)的数据结构。每个片段代表屏幕上的一个像素或部分像素。
  3. 插值计算

    • 光栅化过程中,顶点属性(如颜色、纹理坐标、法线等)会在三角形内部进行插值。这些属性会根据顶点之间的线性插值分配到每个片段上。插值方法可以是线性的或透视校正的(perspective-corrected),后者更精确地处理透视投影下的属性变化。
  4. 片段着色

    • 每个生成的片段会传递给片元着色器(Fragment Shader)进行进一步处理。片元着色器可以计算片段的最终颜色、透明度、深度值等。片元着色器允许开发者自定义片段的外观,例如应用纹理、光照计算、阴影效果等。
  5. 深度测试

    • 片段着色器处理完后的片段会进行深度测试(Depth Testing)。深度测试用于决定当前片段是否应该替换已存在的像素颜色。如果当前片段的深度值小于已存在的像素深度值,则该片段通过深度测试,否则会被丢弃。
  6. 混合操作

    • 如果片段通过了深度测试,它会与已存在的像素颜色进行混合。混合操作可以根据片段的颜色和已存在的像素颜色计算出最终的像素颜色。混合操作通常用于实现透明效果。
  7. 其他测试和操作

    • 除了深度测试,还可能有其他测试,如模板测试(Stencil Testing)和多重采样(Multisampling)。这些测试和操作可以用于实现更复杂的视觉效果,如遮挡检测和抗锯齿。

总结来说,光栅化阶段的主要任务包括确定三角形覆盖的像素区域、生成片段、插值计算顶点属性、调用片元着色器计算片段颜色、进行深度测试和混合操作等。这些步骤共同确保了三角形能够正确地绘制到屏幕上,并且与其他已绘制的对象正确地融合在一起。

片元着色器到深度测试的过程,应该还有裁切测试,alpha测试,模板测试吧?这之后的整个过程跟顺序是怎样的?