【UnityShader】渲染流水线

本文详细介绍了Unity渲染流程的三个阶段:应用阶段、几何阶段和光栅化阶段,包括数据加载、渲染状态设置、DrawCall、顶点着色器、曲面细分着色器、几何着色器、裁剪、屏幕映射、三角形设置、三角形遍历、片元着色器和逐片元操作等关键步骤,解析了GPU如何将3D模型转化为屏幕上连续的图像。
摘要由CSDN通过智能技术生成


  渲染流水线的最终目的在于生成或者说是渲染一张纹理,即我们在屏幕上看到的所有效果。它的输入是一个虚拟摄像机、一些光源、一些Shader以及纹理等。

渲染流程概述

渲染流程分为3个阶段:应用阶段、几何阶段、光栅化阶段。
渲染流程

应用阶段

  • 准备场景数据;
  • 粗粒度剔除,把不可见的物体剔除出去,这样就不需要再移交给几何阶段进行处理;
  • 设置好每个模型的渲染状态,例如使用的材质、纹理、shader等。
  • 输出的是渲染所需要的几何信息,即渲染图元。渲染图元可以是点、线、面等。

几何阶段

  • 几何阶段负责和每个渲染图元打交道,进行逐顶点、逐多边形的操作。
  • 几何阶段的重要任务就是把顶点坐标变换到屏幕空间中,再交给光栅器进行处理。

光栅化阶段

  • 光栅化阶段使用上一阶段传递的数据来产生屏幕上的像素,并渲染出最终的图像。
  • 光栅化阶段的任务主要是决定每个渲染图元中的哪些像素应该被绘制到屏幕上,它需要对上一阶段得到的逐顶点数据进行插值,然后再进行逐像素处理。

渲染具体流程

渲染流程
图中,绿色表示该阶段是完全可编程控制的,黄色表示可以配置但不是可编程的,蓝色表示是由GPU固定实现的,开发者没有控制权。实现表示该shader由开发着编程实现,虚线表示该shader是可选的。

应用阶段

即CPU 和 GPU 通信阶段。具体分为三个阶段

把数据加载到显存中

  所有渲染所需的数据都需要从硬盘中加载到系统内存(RAM)中。然后,网格和纹理等数据又被加载到显卡上的存储空间——显存中。这是因为,显卡对于显存的访问速度更快,而且大多数显卡对于 RAM 没有直接访问权限。把数据加载到显存中后,RAM 中的数据就可以移除了,但对于一些数据来说,CPU仍然需要访问它们(例如,我们希望CPU可以访问网格数据来进行碰撞检测),那么我们可能就不希望这些数据被移除,因为从硬盘加载到 RAM 的过程是十分耗时的。

设置渲染状态

  渲染状态,通俗解释就是,这些状态定义了场景中的网格是怎样被渲染的。例如,使用的shader、光源属性、材质等。

调用 DrawCall

  CPU 调用图像编程接口,以命令GPU进行渲染的操作。

几何阶段

顶点着色器
  • 完全可编程;
  • 输入来自于 CPU;
  • 主要是处理顶点,逐顶点操作,输入进来的每个顶点都会调用一次顶点着色器。
  • 顶点着色器本身不可以创建或者销毁任何顶点,而且无法得到顶点与顶点之间的关系。例如,我们无法得知两个顶点是否属于同一个三角网格。但正是因为这样的独立性,GPU可以利用本身的特效并行化处理每个顶点,这意味着这一阶段的处理速度会很快。
  • 主要工作:顶点变换和逐顶点光照,还可以输出后续阶段所需的数据。
  • 顶点着色器可以改变顶点的位置,这在顶点动画中是非常有用的。
  • 必须完成的一个工作,把顶点从模型空间变换到齐次裁剪空间。把顶点坐标变换到齐次裁剪坐标下,再由硬件做透视除法后,最终得到归一化的设备坐标。
曲面细分着色器
  • 可选的着色器;
  • 用于细分图元;
几何着色器
  • 可选着色器;
  • 它可以被用于执行逐片元的着色操作或者被用于产生更多的图元。
裁剪
  • 可配置的,但不可以编程控制,而是硬件上的固定操作,可以自定义一个裁剪操作来对这一步进行配置。
  • 一个图元和摄像机视野的关系有3种:完全在视野内、部分在视野内、完全在视野内。将那些不在摄像机视野内的顶点裁剪掉,部分在视野内的图元需要进行一个处理,就是裁剪。还要剔除某些三角图元的片面。
屏幕映射
  • 不可配置和编程;
  • 这一阶段输入的坐标仍然是三维坐标系下的坐标(范围在单位立方体内);
  • 屏幕映射的任务是把每个图元的 x 和 y 坐标转换到屏幕坐标系中。是一个缩放的过程。

光栅化阶段

三角形设置
  • 都是固定函数阶段;
  • 这个阶段会计算光栅化一个三角网格所需要的信息。具体来说,上一个阶段输出的都是三角网格的顶点,即我们得到的是三角网格每条边的两个端点。但如果要得到整个三角网格对像素的覆盖情况,必须计算每条边上的像素坐标。为了能够计算边界像素的坐标信息,就需要得到三角形边界的表示方式。这样一个计算三角网格表示数据的过程就叫做三角形设置。
三角形遍历

三角形遍历

  • 检查每个像素是否被一个三角网格所覆盖。如果覆盖的话,会生成一个片元。而这样一个找到哪些像素被三角网格覆盖的过程就是三角形变量,也被成为扫描变换。
  • 这一步输出的是一个片元序列。需要注意的是,一个片元并不是真正意义上的像素,而是包含了很多状态的集合,这些状态用于计算每个像素的最终颜色。
片元着色器
  • 完全可编程;
  • 用于实现逐片元的着色操作;
  • 片元着色器的输入是上一个阶段对顶点信息插值得到的结果。更具体来说,是根据那些从顶点着色器重输出的数据插值得到的。而它的输出是一个或者多个颜色值。
  • 这一阶段可以完成很多重要的渲染计算,其中最重要的技术之一就是纹理采样。
  • 虽然片元着色器可以完成很多重要的效果,但它的局限在于,它仅可以影响每个片元。
逐片元操作
  • 具有很高的可配置性,即我们可以设置每一步的操作细节;
  • 负责执行很多重要的操作,例如修改颜色、深度缓冲、混合等;
  • 任务
    1)决定每个片元的可见性。这涉及了很多测试工作,例如深度测试、模板测试等。
    2)如果一个片元通过了所有的测试,就需要把这个片元的颜色值和已经存储在颜色缓冲区中的颜色进行混合。
  • 片元 --> 模板测试 --> 深度测试 --> 混合 --> 颜色缓冲区

  当模型的图元经过了层次计算和测试后,就会显示在屏幕上。屏幕上显示的是颜色缓冲区中的颜色值。但是,为了避免看到正在进行光栅化的图元,GPU会使用双重缓冲的策略。这意味着,对场景的渲染是在幕后发生的,即在后置缓冲中,一旦场景以及被渲染到后置缓冲中,GPU就会交换后置缓冲区和前置缓冲区中的内容,而前置缓冲区是之前显示在屏幕上的图像。由此,保证了我们看到的图像总是连续的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值