图形渲染管线简介

  本文的目的是梳理一下渲染管线,本人还在打基础阶段,文中可能会有些许问题,望见谅。

  图形渲染管线是连接起整个渲染领域的总线,大部分的渲染都是在图形管线上展开的。图形渲染管线又和 GPU 渲染管线紧密不可分。下图比较了 RTR 第四版与各种图形 API ,以及 GPU 渲染管线,不同的管线可能会在具体细节上划分与下图不同。下图中,绿色为可编程,黄色为可配置,红色为完全固定。文中主要按照 DX11 管线进行分步解说。

Pipeline

应用程序阶段 Application

  应用程序阶段主要靠 CPU 进行,基础任务是将这一帧更新的相机,图元和光照信息传到 GPU。

  CPU 还会处理应用程序逻辑,例如碰撞检测,纹理动画,几何变形等,还可以在 CPU 进行一些剔除,例如层次视锥剔除,减少 GPU 的负担。

几何处理 Geometry Processing

  几何处理阶段的输入是顶点与图元的顶点索引,输出是屏幕空间的顶点。简单来说,几何阶段就是负责把顶点都转换到屏幕空间,以便光栅化阶段处理。下面是几何处理阶段的各个子阶段:

子阶段英文功能
输入组装Input Assembler将顶点组装成图元供其他阶段使用,但邻接信息仅在 Geometry Shader 可见
顶点着色器Vertex Shader逐顶点处理着色,一般会处理变换与投影 (MVP 矩阵),将顶点转换到齐次剪切空间
曲面细分Tesselation可选阶段,包括两个着色器和一个细分阶段
几何着色器Geometry Shader可选阶段,能够处理/增/删图元
流输出Stream Out可选阶段,将新增的图元存入 memory
裁剪与屏幕映射Clipping & Screen Mapping剔除视锥外的顶点,将顶点转换到屏幕坐标系
顶点着色器 Vertex Shader

  顶点着色器的输入是顶点和顶点属性,顶点着色器负责将顶点的位置从局部空间转换到齐次剪切空间 (Homogeneous Clipping Space),顶点着色器还可以操作顶点相关的属性,比如颜色,法线,纹理坐标等,一般会在顶点着色器会计算逐顶点的光照。

  还会在顶点着色器做其他一些操作,比如 Instancing (将同一个物体的顶点绘制在多个地方),或者做关节动画,蒙皮,顶点动画。

变换 Transformation

  在顶点着色器里会将顶点从局部空间转换到齐次剪切空间,需要经过 MVP 变换 (Model, View, Projection Transformation)。
- Model :局部空间->世界空间
- View:世界空间->相机空间
- Projection: 相机空间->齐次剪切空间

  Model 变换牵涉到三个矩阵,缩放,旋转,平移 (Scale, Rotation, Translation,SRT)。缩放和旋转是线性变换,可以用三维矩阵来表示。平移是仿射变换,放在齐次空间,用四维矩阵来表示更加方便。SRT 的值一般存在物体的属性中,运算时取出来,组成矩阵,并将三个矩阵连乘起来,与顶点相乘。

  View 变换是将顶点从世界空间转到相机空间,这是一个简单的坐标系变换。将相机的 pos, up, center (相机看向的点) 三个点传入,进行叉积运算,就得到了 view 坐标基矩阵。

投影 Projection

  Projection 变换是将三维空间通过投影转换到二维的平面上。投影有透视投影和正交投影两种。

  在透视投影中,相机空间会设置最远/最近的距离,可见的物体会被限制在一个平头椎体 (Frustum) 的范围内。透视矩阵所要做的事情就是将这个平头椎体内的点透射到近视点的平面。

  实际上,顶点着色器还需要将齐次剪切空间的点映射到统一的坐标上。因为光栅化阶段的硬件需要 NDC 坐标 (Normalized Device Coordinates),该坐标与屏幕的长宽比无关,等同于将平头椎体变成了单位立方体。

  顶点坐标乘以投影矩阵后,需要是 NDC 坐标。

可选阶段 Optional Stage
表面细分 Tessellation

  Tessellation 主要用来做面的细分,可以将现有的面数拆分得更多,提供更多得细节。这个阶段常用来生成更精细的地形或其他表面。

几何着色器 Geometry Shader

  几何着色器的输入是整个图元,还可以获得邻接图元的信息。几何着色器可以丢弃一些图元,还可以生成新的图元。这个阶段可以简化图元,例如用来做细节等级 (Level of detail,LOD)。也可以用来生成图形,例如用来做粒子生成。

  与 Tessellation 相比,几何着色器可以丢弃图元,也可以将现有的图元转换成其他图元。而 Tessellation 只能增加面数。

流输出 Stream Output

  在几何着色器中生成的顶点数据可以流输出到 GPU Memory 。这些数据可以再次放到流水线里,或者被 CPU 读取。这种方式可以迭代处理数据,常用来做水流模拟,或者粒子效果。

裁剪与屏幕映射 Clipping & Screen Mapping

  经过上述阶段,顶点是 NDC 坐标,目前的可视空间等于一个单位立方体。硬件会负责对可视空间的图元进行裁剪。

  • 在立方体之外的,舍弃掉
  • 在立方体之内的,保留
  • 和立方体边缘相交的,会改变图元。例如一条线与立方体相交,在外的顶点会被剔除,改成相交处的地点。

  经过裁剪,就只剩下立方体内的顶点了。然后需要将二维的 NDC 坐标映射到屏幕坐标系上,这个过程就是屏幕映射。

光栅化阶段 The Rasterizer Stage

  在光栅化之前,整个空间都是连续的,但屏幕上的像素点是个点阵,像素点之间的线就像栅栏,将原来连续的空间筛成了点阵,这就是光栅化的含义。

  光栅化输入的是二维屏幕空间的顶点位置及相关属性 (深度值Z,法线等),此阶段会由硬件计算出屏幕像素对应的相关属性。

三角形设定 Triangle Setup

  之前得到的都是三角形的顶点,而之后要计算屏幕上三角形会覆盖那些像素。三角形设定阶段会计算三角形边上 (及内部?)的像素坐标及相关的属性。

  (推测:应该是在这个阶段进行 反面剔除 (Backface Culling),将反面朝向相机的三角形扔掉。)

三角形遍历 Triangle Traversal

  这个阶段会进行逐像素检查,检查每个像素 (或采样点)是否被三角形覆盖,如果覆盖则生成一个片元 (Fragment)。这一阶段也被称为扫描转换 (Scan Conversion)。

像素处理 Pixel Processing

像素着色器 Pixel Shader

  像素着色器也被叫做片元着色器 (Fragment Shader),用来逐像素的计算着色,纹理贴图和纹理过滤一般都是在这个阶段进行的。

  像素着色器的输入是逐像素的属性,这些属性是根据上个阶段中的顶点插值而得到的,插值一般使用透视纠正插值 (Perspective Correct Interpolation)由硬件完成,需要借助深度值才能正确地插值。

  像素着色器还可以获取邻近像素插值的变化量,可以进行梯度计算,这个特性主要用来做纹理过滤。

  像素着色器会输出一个该像素 (片元)的颜色,也可以选择不输出。像素着色器还可以修改 深度缓冲 (Depth Buffer),甚至是模板缓冲 (Stencil Buffer)的值。

  在现代 GPU 上,像素着色器 可以将进行不同类型的输出,并写入多重渲染目标 (Multiple Render Targets,MRT),一个 RT 就是一个 buffer,可以将不同的信息写入不同的 RT,然后在下个阶段合成

合并 Merging

  这个阶段主要是将目前这一帧计算出来的 Fragment 颜色和系统中所有的 buffer 合并,得到最终的颜色值。合并阶段不可编程,但是高度可配置。

   通常会在这个阶段根据 Z-buffer 进行 可见性测试 (Depth test,深度测试),只渲染能看见的片元。也会进行透明度测试 (Alpha Test),混合半透明物体与透明物体的颜色。模板缓冲也会用来控制颜色合并。

   经过合并阶段就可以得到最终屏幕显示的颜色了。

总结

  这篇文章只是简单介绍下图形渲染管线的各个部分,旨在理清楚各部分大致的功能,输入及输出。目前还有一些功能部分不清晰,日后再进行修改。

返回目录

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值