US1L4——渲染管线-光栅化阶段

知识必备——像素

像素是计算机图形学中的基本概念,它是组成图像的最小可控单位,具有位置和属性,用于表示图像中的颜色和其他信息
它是二位图像中的一个点,每个像素都占据屏幕上的一个固定位置
比如我们常见的显示器分辨率为:1920 x 1080,就表示宽度为1920个像素,高度为1080个像素

知识必备——片元

在渲染管线中,片元是指在光栅化阶段生成的像素或像素片段
片元是渲染管线中进行像素级别操作和计算的基本单位
每个片元代表了屏幕上的一个像素,并且具有位置信息和与之相关的属性,比如:颜色、深度值、法线等等

简单来说,片元相比像素包含了更多的消息,比如:颜色、深度值、法线等等

渲染管线 的 光栅化阶段

渲染管线(流水线)中的光栅化,主要是GPU主导的阶段
它为渲染完成的最主要的工作就是 确定片元最终是否被渲染,并且确定片元的最终渲染颜色效果等
在光栅化阶段中,我们主要通过自定义 片元着色器 **** 阶段,为我们带来一些不同的表现效果

image

渲染管线的光栅化阶段同样由GPU主导,同样我们无法拥有绝对的控制权,同样GPU为我们开放了部分控制权
光栅化阶段主要做的事情是根据几何阶段输入的信息计算每个图元覆盖哪些像素,以及为这些像素计算他们的颜色等等工作

image

  • 三角形设置:

    几何阶段输入到光栅化阶段的数据主要是三角形网格的顶点信息,我们得到的只是三角形网格每条边的两个端点信息
    如果想要得到整个三角形网格对像素的覆盖情况,就必须计算每条边上的像素坐标,
    为了能计算三角形边界像素的坐标信息,我们必须得到三角形边界的表示方式。

    三角形设置这个小阶段,GPU主要做的事情就是计算三角形网格的表示数据

  • 三角形遍历:

    该阶段主要根据三角形设置中计算出的三角形网格数据,检查每个像素是否被一个三角形网格所覆盖
    如果覆盖的话,就会生成一个片元(包含屏幕坐标、深度、法线等等信息)
    这个阶段也被成为扫描变换

    image

    三角形遍历这个小阶段,GPU主要做的事情就是根据三角形网格信息得到被它们覆盖的片元序列

  • 片元着色器(像素着色器)

    它主要完成对 三角形遍历输入的片元序列中的 每个片元(像素)的着色计算和属性处理
    片元着色器需要完成的工作主要有:

    1. 光照计算 —— 计算片元的光照效果
    2. 纹理映射 —— 根据片元在纹理中的位置,对纹理进行采样,将纹理颜色映射到片元上,实现表面贴图效果
    3. 材质属性处理 —— 根据材质的属性,比如颜色、透明度、反射率等,计算片元的最终颜色和透明度
    4. 阴影计算 —— 根据光源等信息,计算片元是否处于阴影中,影响其最终颜色

    等等,对于我们来说**片元着色器是完全可编程的**

  • 逐片元操作(输出合并阶段)

    它主要完成对 片元着色器 输出数据(最终颜色、法线、纹理坐标、深度等)进行各种处理和计算
    逐片元操作主要完成的工作主要有:

    1. 决定每个片元的可见性,比如**深度测试**、模板测试
    2. 如果通过了所有测试,需要把片元的颜色值和已经存储在颜色缓冲区的颜色进行合并(混合

    等等,对于我们来说逐片元操作是可配置的

光栅化阶段为渲染准备了些什么

在渲染管线(流水线)的光栅化阶段,最主要做的工作就是,对片元(像素)进行最终处理
最主要完成的就是确定片元(像素)最终是否渲染到屏幕上,并且确定其的最终渲染的颜色效果

对于我们来说,我们只要在片元着色器中进行一些处理就可以带来不同的表现效果的体现
比如:逼真的水面效果、火焰、黑白、模糊等等效果

逐片元操作中的深度测试流程

深度测试和深度写入共同决定了多个物体在屏幕上的显示情况,当多个物体之间相互存在遮挡时,深度测试将确保正确渲染未被遮挡的模型

  • 深度缓冲(Depth Buffer):

    深度缓冲是一个与屏幕像素对应的缓冲区,它用于存储每个像素的深度值(距离相机的距离)。
    在渲染场景之前,深度缓冲被初始化为最大深度值,表示所有像素都在相机之外。 最后留在深度缓冲中的信息会被渲染

  • 深度测试

    深度测试的主要目的是确保在渲染时,像素按照正确的深度(距离相机的距离)顺序进行绘制,从而创建正确的遮挡关系和透视效果
    在渲染场景之前,深度缓冲被初始化为最大深度值,表示所有像素都在相机之外。
    在渲染过程中,对于每个像素,深度测试会将当前像素的深度值与深度缓冲中对应位置的值进行比较。

    image​​深度测试图

    可以简单理解为,深度测试就是用来确认 不同模型所占的同一块屏幕区域 到底需要渲染哪一个模型上对应的颜色
    深度测试会依次将 模型所占屏幕上的片元的深度值(Z-Buffer) 与 对应像素的深度缓冲的深度值 比较,

    如果这个片元的深度值比深度缓冲区的深度值更小(也就是说离摄像机更近),则通过深度测试,将会被渲染

    也就是说,一般情况下:

    1. 如果当前像素的深度值小于深度缓冲中的值,说明当前像素在其他物体之前,它会被绘制
      如果此模型开启了深度写入,则更新深度缓冲,若没有,则深度缓冲区的深度值不变
    2. 如果当前像素的深度值大于等于深度缓冲中的值,说明当前像素在其他物体之后,它会被丢弃,不会被绘制,并保持深度缓冲不变。

    注意,如果一个片元通过了深度测试,但是没有开启深度写入,那么这个片元依然会渲染出来
    也就是说,片元是否会渲染取决于是否通过深度测试,而不是取决于是否存在于深度缓冲区

  • 深度写入

    对于一个通过了深度渲染的片元,如果模型开启了深度写入,则该片元的深度值将被写入到深度缓冲内,与后面的片元进行比较

    对于深度写入,一般半透明的模型是不会开启深度写入的,举例:
    假设存在A,B,C三个平面,遮挡关系如下图,其中距离摄像机从近到远的平面依次为:C —— A —— B

    image

    因此,如果C的和其他平面占屏幕的公共区域的片元开启了深度写入,则A和B与将不能通过深度测试,A和B对应的片元也不会被渲染

    但是,如果C是半透明平面,显然我们需要结合后面的A和B的片元的颜色去混合渲染,
    这时我们不能开启C的深度写入,这样A和B对应的片元还是会通过深度测试,可以被渲染出来

    如果A也是半透明物体,那么A也不能开启深度写入,这样B对应的片元才通过深度测试,可以混合渲染颜色

逐片元操作中的混合流程

混合操作是在深度测试后执行的,通过深度测试流程的片元才能去进行混合,混合过后会将像素的颜色存储到对应的颜色缓冲区

混合操作是3D图形渲染中的一个重要步骤,它涉及到如何将半透明物体的颜色与背后物体的颜色结合起来。

在深度测试之后,如果一个片段(即像素)通过了测试,接下来就会进行混合操作(Blending)。
混合操作决定了这个片段的最终颜色如何根据其透明度与背后的颜色合成。
混合操作通常用于实现物体的透明度效果,比如玻璃、水、烟雾等。

混合流程如下:

混合流程图