实时渲染图形管线
1、概念划分
1.1 基本定义:
实时渲染管线大概分为四个阶段:
应用阶段 -> 几个处理阶段 -> 光栅化阶段 -> 像素处理阶段
如下图所示:
应用阶段是图形程序在CPU驱动阶段。这一阶段常见任务【冲突检测(collision detection)】 【global acceleration algorithms】 【动画(animation)】 【物理模拟(physics simulation)】等。
几何处理阶段处理几何体操作,包括【变换(transforms,)】【投影(projections)】等操作。
光栅化阶段,主要计算出上一阶段输入的基元包含的像素。
像素处理阶段,处理颜色、深度、模板等,计算出像素的最终颜色。
1.2 概念各阶段注意点
1)应用阶段
a、这一阶段主要操作是在cpu完成。但是某些操作也可以放到gpu里面执行,比如【计算着色器(compute shader)】.
b、这一阶段的最主要任务就是 为下一阶段准备好渲染基元(rendering primitives),比如点、线、三角形
2)几何处理阶段
在GPU完成per-triangle 和 per-vertex操作。
这一阶段又可以划分成几个功能步骤:【Vertex Shading】【Projection】【Clipping】【Screen Mapping】
如下图所示:
Vertex Shading:
-- 主要任务:计算顶点位置和其他和顶点输出相关的数据,比如顶点法线、顶点纹理坐标
-- 主要操作:模型变换(model transform),顶点和法线都可能经过模型变换。完成从【模型空间】到【世界空间】的坐标 转换。
视图变换(view transform),主要目的就是将相机变换到世界空间的原点,并看向Z轴负方向(右手坐标系下,x轴向 右,y轴向上)。完成从【世界空间】到【相机空间】的坐标转换。
Shading,一个顶点材质计算操作,计算渲染物体顶点的 shading equation?
投影(Projection)
-- 将视锥体(view volume)里面的对象变换到正规化视锥体(canonical view volume. 一个单位立方体,范围(−1,−1,−1) 到 (1, 1, 1).)。常见投影方式:正交投影(orthographic)、透视投影(perspective)。完成【相机空间】到 【裁剪空间】的坐标 转换。
裁剪(Clipping)
-- 位于正规化视锥体外的物体全部裁掉,不用于渲染。使用人员还可以自定义裁剪平面,比如Section操作。在透视投影 下,还需完成透视除法(perspective division)。最终完成【裁剪空间】到【正规化设备坐标系】下。
屏幕映射(Screen Mapping)
-- 经过裁剪后剩余的基元才会映射到屏幕。完成从【正规化设备坐标系】到【窗口空间】,【窗口空间】由【屏幕空间 (基元x和y坐标值映射到这一空间)】+ 基元z 坐标值组成。
-- 理解关于像素的整数值和浮点值。一般情况下【窗口空间】最左边的浮点值是0.0,这个最左边像素中心浮点值就是0.5,
关于像素整数值和浮点值的转换公式如下:
需要注意不同API,(0,0)原点像素约定可能不一样,具体API具体分析。
可选的操作
-- 几何细分(tessellation),几何体着色器(geometry shader),流输出(stream output)
3)光栅化阶段
计算哪些像素是落在基元范围内的像素,计算算法有多种。这一阶段又分为两个功能阶段:【triangle setup】和
【triangle traversal】,如下图蓝色部分所示
4)像素处理阶段
计算出像素颜色。又分为【Pixel Shading】和【Mergeing】两个功能阶段,如上图橙色部分所示。
Pixel Shading常见操作:映射纹理(texturing)。
Mergeing常见操作:【color buffer】【z-buffer(depth buffer)】【alpha channel】【stencil buffer】,这些操作的结果最后 进行【blend operations(raster operations)】,融合后的结果存储到【framebuffer】。
2、硬件划分
2.1 基本定义
GPU硬件上包含大量的处理器(shader cores),数量一般都在千数以上。并发能力出众,并且GPU吞吐量经过优化,效率 出众。
-- GPU中,纹理作为独立资源,访问数据需要消耗时间,如果在某个时间点检测到这类耗时操作,GPU会调度切换到另一 个 shader core执行,再遇到这个耗时操作,再进行调度切换。调度流程如下图所示
上述渲染管线在概念上进行了划分,大多数GPU硬件上都实现了概念划分的功能阶段。对应到GPU硬件功能项阶段如下 图所示。
上图中,绿色部分就是图形管线中的可编程阶段。几种shader使用的都是通用编程模型,只是不同shader具有不同的角 色功能。当使用图形API调用绘制接口(draw call)时,图形管线就会调用相应的shader程序完成基元的绘制。
每种shader只有两种输入类型:uniform和varying,一种输出类型varying。uniform输入类型,在一次draw call调用过 程中,全局保持不变。varying变量表示不同shader之间可变的传递变量类型。两种类型对应到硬件寄存器如下:
-- uniforms变量对应到常量寄存器(constant registers);
-- varying变量对应到某些寄存器;
-- 具体如下图所示:
shader支持的流控制(flow control):
-- 静态流控制(Static flow control):基于uniform变量的值,这种情况下,所有核心都是执行统一分支的shader代码, 此时不存在thread divergence现象,不影响GPU shader core的执行效率。
-- 动态流控制(Dynamic flow control):基于varying变量的值,这就可能导致不同片元执行不一样的分支shader代码, 存在thread divergence现象,或造成shader core的执行效率。但是这种控制可以产生更有力的效果。
2.1 各阶段常用操作
顶点着色器(vertex shader):
-- Object generation, by creating a mesh only once and having it be deformed by the vertex shader.
-- Animating character’s bodies and faces using skinning and morphing techniques.
-- Procedural deformations, such as the movement of flags, cloth, or water.
-- Particle creation, by sending degenerate (no area) meshes down the pipeline and having these be given an area as needed.
-- Lens distortion, heat haze, water ripples, page curls, and other effects, by using the entire framebuffer’s contents as a texture on a screen-aligned mesh undergoing procedural deformation.
-- Applying terrain height fields by using vertex texture fetch
顶点着色器输出成果应用:
-- 输出用于下一渲染管线阶段处理的基元。这是最为基本的操作。
-- 输出到tessellation 阶段处理。
-- 输出到geometry shader 处理。
-- 保存到内存区域(feedback操作)。
参考:
《Real-Time Rendering》 fourth Edition Tomas Akenine-M¨oller等著