Unity Built-in

渲染流程图


CPU应用程序阶段

剔除

剔除(Culling)

将看不见的物体整个排除在渲染范围之外,不进行渲染


视锥体剔除

视锥体剔除(Frustum Culling)

视锥体:指摄像机根据FOV参数远、近裁面产生的一个锥体

视锥体与物体进行碰撞检测来确定哪些物体应该被渲染,物体被碰撞盒进行包裹以便进行碰撞检测


层级剔除

层级剔除(Layer Culling Mask)

排除某几个特定层级上的物体


遮挡剔除

遮挡剔除(Occlusion Culling)

被遮挡的物体不被渲染


排序

排序(Sort),通过渲染队列(Render Queue)确定渲染顺序

  • 不透明队列(<2500)

    • 默认2000

    • 按摄像机距离从前到后排序

  • 半透明队列(>2500)

    • 默认3000

    • 按摄像机距离从后到前排序


打包数据

打包数据(Batch)

CPU要将写一些关于模型和渲染的数据打包发送给GPU


模型信息

就是要被渲染的模型文件的信息,如,fbx、obj等

  • 顶点坐标(vertices)

  • 法线(vertex normals)

  • UV(texture coords)

  • 索引列表(Indices Array)

  • 切线

  • 顶点色


变换矩阵
  • 世界变换矩阵

  • VP矩阵

    • 根据摄像机位置和FOV等参数构建


灯光、材质参数
  • Shader

  • 材质参数

  • 灯光信息


绘制调用


GPU渲染阶段

GPU渲染管线流程

顶点着色器

顶点着色器(vertex shader)

  • 最重要的任务

    • 顶点坐标模型空间变换到裁剪空间

  • 模拟“拍照”的过程

  • 顶点着色器并不会产生2D图像,仅使得场景中的3D对象产生变形效果

  • 可编程

经过矩阵将空间向量进行平移、旋转、缩放等操作

模型空间 -> 世界空间

(放置物体)

通过模型矩阵(Model Matrix)

世界空间 -> 相机空间

(摆好相机)

通过视图矩阵(View Matrix)

相机空间 -> 裁剪空间

(按下快门)

通过投影矩阵(Projection Matrix)


图元装配及光栅化

也就是硬件操作阶段,不能人为操作

  • 裁剪操作

    • 对三角面进行裁剪操作,超出部分会被裁剪掉,重新生成一个新的三角面

  • 标准化设备坐标(NDC)

    • 将裁剪空间的坐标(-w~w)缩放到-1~1

    • 为映射到屏幕坐标系做准备

  • 背面剔除

    • 通过模型信息的索引列表观察一个三角面的分布方向

    • 逆时针为正面

    • 顺时针为背面

  • 屏幕坐标

    • 只针对NDC的XY坐标进行转换

  • 图元装配

    • 之前都是对顶点进行操作,该阶段进行连线,生成封闭的三角形

    • 生成的三角形被称为图元

  • 光栅化

    • 将3D顶点转化为2D像素

    • 取屏幕坐标的XY坐标对图形进行“拍扁”操作

    • 通过插值生成算法生成片元

    • 屏幕坐标(NDC)的Z坐标(深度值 depth)被用来判断生成的片元哪个应该最先显示在前面

  • 片元

    • 片元存储有对应插值计算后的数据

      • 深度值Z

      • 法线

      • 顶点色

      • 切线

      • 位置

      • 所有自定义的数据


片元着色器
  • 最重要的任务

    • 给片元上色

  • 可编程

  • 纹理技术

    • 纹理采样

      • 给定一个纹理坐标,通过算法找到对应纹素地址的颜色值

    • 纹理过滤机制

      • 当计算结果不为整数时该取哪个纹素地址

    • Mipmap

      • 将大的图像映射到小的区域里

      • 生成多个level图根据区域大小进行映射

    • 纹理寻址模式

      • 纹理坐标计算后的值超过了纹素地址的范围

    • 纹理压缩格式

      • RGBA - 真彩色

      • ASTC - 移动端

      • ETC2 - 安卓

      • PVRTC - IOS

  • 光照计算

    • 光照组成

      • 直接光照

        • 光线到达物体表面后结果一次反射进入人眼

      • 间接光照

        • 光线到达物体表面后结果多次反射进入人眼

  • 光照模型

    • Phong光照模型

      • 对BRDF(双向反射分布函数)函数的简化

        Phong = max(n \cdot l,0) + pow(max(r \cdot v,0),smoothness) + ambient

    • 漫反射光(Diffuse)

    max(n \cdot l,0)

    • 镜面反射光(Specular)

    (r \cdot v)^{sh}

    • 环境光(Ambient)

  • 基本框架

    • 基本框架 = 直接光漫反射(Direct Diffuse) + 直接光镜面反射(Direct Specular) + 间接光漫反射(Indirect Diffuse) + 间接光镜面反射(Indirect Specular)

    • 基本框架扩充 = 基本框架+More


输出合并
  • 最重要的任务

    • 处理遮挡关系

    • 处理半透明混合

  • 帧缓冲区(Frame Buffer)

    • 颜色缓冲区(Color Buffer)

    • 深度缓冲区(Depth Buffer)

    • 模板缓冲区(Stencil Buffer)

  • Alpha测试(Alpha Test)

    • 检测片元的Alpha值,如果低于某一个数值就丢弃

  • 模板测试(Stencil Test)

    • 与深度测试类似,设定某一规则,符合规则的片元才会被写入模板缓冲区(Stencil Buffer)

  • 深度测试(Depth Test)

    • 片元的深度值Z与深度缓冲区的数值进行比对,如果片元深度值Z小于深度缓冲区的值,则会写入,反之亦然

    • 深度写入(ZWrite)

      • 控制通过测试的片元是否写入深度缓冲区

      • 不会影响颜色缓冲区的写入

    • 深度测试(ZTest)

      • 自定义深度测试的规则,决定哪些片元可以通过测试

    • 提前深度测试(Early-Z)

      • 可提高性能

      • 需要硬件支持

  • 混合(Blending)

    • 相对于深度测试,是一个比较柔和的机制

    • 对于半透明混合,要得到正确的渲染顺序,需要严格按照从后到前的规则

    • 对于半透明混合,一般需要关闭深度写入(ZWrite)

    • 对同一个位置上的多个片元进行混合计算,得到新的颜色值

      Alpha Blend = SrcColor * A + DestColor * B

      其中,AB是两个自定义因子,比如如下着色器指令

      Blend SrcAlpha OneMinusSrcAlpha
      Blend SrcAlpha One

      就相当于

      Alpha Blend = SrcColor * SrcAlpha + DestColor * (1.0-SrcAlpha)

      Alpha Blend = SrcColor * SrcAlpha + DestColor * 1.0



规则,就是用来打破的( ̄へ ̄)!