找回密码
 立即注册
查看: 227|回复: 0

图形1.1 渲染管线

[复制链接]
发表于 2022-10-10 09:55 | 显示全部楼层 |阅读模式
拓荒犬:GPU Rendering Pipeline——GPU渲染流水线简介

整体流程:

应用阶段:粗粒度剔除,渲染设置,准备基本数据,输出到几何阶段
几何阶段:顶点着色器,曲面细分,几何着色器,顶点裁剪,屏幕映射
光栅化阶段:三角形设置,三角形遍历,片段着色器
逐片元操作:裁剪测试,透明度测试,深度测试,模板测试,混合
后处理


应用阶段 ( CPU ):

1.1 加载场景基本数据:


  • 物体数据:
  • 物体的Transform: 位置、旋转、缩放
  • 物体的网格数据 : 顶点位置、UV贴图
光源信息:

  • 方向光、点光、聚光 等类型
  • 位置、方向、角度    等参数
摄像机数据:

  • 位置、方向、远近裁剪平面
  • 正交 OR 透视(FOV)
  • 视口比例 / 尺寸
光源和阴影:
    设置光源:

  • 方向光:颜色、方向 等
  • 点光源:颜色、位置、范围、衰减系数 等
  • 聚光灯:颜色、位置、方向、衰减系数、内外圆锥角 等
    设置阴影:

  • 是否需要阴影:判断光源范围内是否有可投射阴影的物体
  • 阴影参数:对应光源的序号、阴影强度、级联参数、深度偏移、近平面偏移 等
逐光源绘制阴影贴图: 作为阴影数据

  • 近平面偏移
  • 逐级联 计算当前光源+级联对应的观察矩阵、投影矩阵、对应视口区域, 绘制到阴影贴图

1.2 加速算法  粗粒度剔除:


  • 可见光裁剪 :
  • 根据点光、聚光的衰减, 与摄像机的距离 进行剔除
  • 聚光灯的光椎和摄像机的视椎体不相交, 则剔除
  • 可见场景物体裁剪 :
  • 剔除摄像机视椎体之外的物体 ; 剔除被其它物体遮住的物体
  • 算法:八叉树、BSP树、KD树、BVH
1.3 渲染设置

    绘制设置:

  • 使用着色器  - 不同物体使用不同的着色器
  • 合批方式:  GPU instance  、动态批处理
    绘制物体的顺序

  • 以 相对摄像机的距离 进行排序
  • 以 材质RenderQueue 进行排序
  • 以 UICanvas 的属性进行排序
    渲染目标

  • FrameBuffer
  • RenderTexture
    渲染模式

  • 前向渲染
  • 延迟渲染
1.4 输出到显存

    顶点数据:

  • 位置、颜色
  • 法线、纹理UV
  • 其它顶点数据
    其它数据:

  • MVP变换矩阵
  • 纹理贴图
几何阶段(GPU)

2.1 顶点着色器 - 视图变换

模型空间 M → 世界空间  V → 观察空间 P → 投影变换(正交/透视投影) → 视口空间
计算顶点光照时,需要光源、摄像机的位置和朝向,以及 顶点的世界位置
获得顶点的世界位置 需要做空间转换
2.2 曲面细分(可选)

使用现有顶点生成更多顶点


通过Tessellation,原有的模型被添加了大量的Vertex,有了这些Vertex,我们再应用Displacement Mapping (贴图置换),这里的贴图是存储了高度信息的纹理,可以改变每个Vertex的高度信息。
如下图所示,原始图元先通过Tessellation变得更加光滑,也同时使得模型含有更多的Vertex。然后再通过贴图置换,给每个顶点加上相应的高度偏移量,使得整个模型充满大量细节,以变得更加逼真。


——《GPU Rendering Pipeline——GPU渲染流水线简介》
2.2 几何着色器(可选, 基于图元的操作)



2.3 投影

前面阶段的坐标都是在3D空间中,要显示在2D屏幕上,就要做投影,3D转为2D




2.4 裁剪



红色三角形 在屏幕外面,剔除
橙色三角形 添加两个顶点,再剔除屏幕外的部分
黑色线段 添加一个顶点,再剔除屏幕外的部分
2.5 屏幕映射



将 unit-cube 坐标系 转换到 屏幕坐标系,
NDC空间下的XY范围是 [-1,1] , 屏幕坐标系的范围是 输出设备的长和宽
PS : openGL的原点在左下方, D3D的原点在左上方

光栅化阶段 (GPU)

3.1 三角形设置

屏幕映射 计算出了顶点在屏幕空间的坐标,
已知三角形的三个顶点, 计算三角形边界(三角形设置),绘制三角形内部覆盖的像素
“将各个点连接起来,组成真正的三角形”
“然后下一阶段会利用这些信息进行三角形的遍历,也就是检查有哪些像素位于该三角形图元内,对于点、线图元,就看他们覆盖了哪些像素。”


3.2 三角形遍历

得到三角形的边界信息之后, 遍历所有相关像素,检查像素是否被三角形覆盖
如果覆盖,则这个像素属于三角形
寻找被三角形覆盖的所有像素 的过程, 为 三角形遍历
我们可以看到,每个像素的中心有一个点,我们便是用这个中心点来进行划分的,若中心点在图元内部,那么这个中心点所对应的像素就属于该图元。



3.2 抗锯齿

SSAA:
渲染到一个分辨率放大N倍的buffer, 对放大N倍的buffer进行采样
MSAA:
在光栅化阶段, 计算多个覆盖样本
对每个像素设置多个子采样点,对每个子采样点进行覆盖测试 和 遮挡测试,
覆盖测试 判断这个子采样点是否在三角形内
遮挡测试 把子采样点的深度和Z-Buffer里的数值进行比较, 判断是否能通过
若两个测试通过,则说明这个子采样点属于这个三角形。


FXAA / TXAA:
在后处理阶段

4.逐片元操作

4.1 片元着色

对每个片元进行着色, 可编程
使用三角形的顶点颜色,对三角形内部片元进行线性插值着色


4.2 颜色混合 - 透明度测试

在处理片元时, 给定一个阈值, 如果片元的透明度低于该值, 则抛弃该片元.


4.2 颜色混合 - 深度测试 / 模板测试

深度测试


模板测试


后处理材质基础 模板/深度

4.2 混合



1.立方体、球 均为不透明时
2.立方体 不透明, 球 透明



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-25 01:04 , Processed in 0.063297 second(s), 23 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表