UE3的3D渲染流水线处理流程

发表于2017-03-22
评论2 3k浏览

本文要给大家讲述的是UE33D渲染流水线的处理流程,让开发者知道UE3引擎在3D流水线各个阶段的工作内容,这样在开发过程中才能更好的去使用3D渲染流水线。 

什么是渲染(Rendering

渲染简单的理解可能可以是这样:就是将三维物体或三维场景的描述转化为一幅二维图像,生成的二维图像能很好的反应三维物体或三维场景(如图1):

 

什么是流水线

举个栗子,生产一支圆珠笔需要生产笔芯、笔套,然后再组装3个步骤。

非流水线的生产方式就是,一个工人在生产完笔芯后,再生产一个笔套,然后再将笔芯、笔套组装成一支圆珠笔。流水线的生产方式就是,3个工人,一位专门生产笔芯,一位专门生产笔套,一位专门组装圆珠笔,流水线某个阶段的工人不用关心其他阶段流程是否完成,只需要关心本阶段的产品生产。显然,同样3个工人,流水线生产方式的批处理能力更强。

3D渲染流水线也称为3D渲染管道,是显示芯片内部处理图形信号相互独立的的并行处理单元。

 

3D渲染流水线

 

如上图所示,3D渲染流水线也类似一个工厂的流水线,它的原材料是一系列初始的3D网格数据,最终产品就是显示在2D屏幕上的3D场景。

 

3D渲染流水线的处理和照相机照相的原理很像,它们都同样是要通过将3D世界的内容放置到2D平面上,通过2D的方式来展现3D世界,只不过3D世界场景的物体是通过电脑模拟的3D场景数据,而照相机所面对的是真实的世界。

 

下面我们来讲解下3D渲染流水线的各个步骤:

 

12步骤

首先12步骤是在CPU中执行的,它们的主要作用是为3D流水线准备当前帧中最终可能要渲染到屏幕上的所有网格数据,在UE3中,鼠标键盘输入、3D物体运动、碰撞检测、场景管理、骨骼计算、伤害判断等都是在这一步处理的,也就是说,和渲染无关的所有游戏逻辑,其实都还是放在CPU处理的,只不过UE3为了加快核心模块的运行效率,使用了MMX指令(多媒体扩展指令)和SSE指令(单指令多数据流式扩展)来优化核心部分的代码,比如骨骼计算和碰撞检测。

 

3456步骤

通常从第三步开始,都是在GPU内部处理的步骤了。3456步骤是一个对顶点进行几何处理的流程,也叫做“顶点管线”,和后续“像素管线”相对应,它主要处理12步骤中输入的网格顶点数据,通过固定管道对这些数据进行几何坐标空间的变换、裁剪以及顶点的光照计算等。

 

顶点管线中有这么几个坐标空间:局部空间 -> 世界空间 -> 相机空间 -> 投影空间 -> 屏幕空间(视口空间),初始的网格数据是在局部空间中的,顶点管线将其从局部空间变换到屏幕空间作为输入供“像素管线”处理。为何要分这么多空间呢,因为上述每个空间都有处理某块逻辑的优势,比如局部空间内,一个人物的骨骼模型,它的中心点就是根骨骼的位置,在进行骨骼层次计算的时候,根骨骼放在中心位置是易于计算的,如果将其放置到世界空间中进行骨骼计算,那么根骨骼的位置不在原点且朝向也不为0,计算起来相当复杂。而世界空间中,易于描述场景中各个物体间的关系,易于作碰撞处理、伤害计算、顶点光照计算等。在相机空间中,容易描述被观察物体与观察者之间的关系,利用相机视锥体对物体进行裁剪,把观察不到的物体剔除掉。

 

坐标空间转换及推导这块内容设计到相当多几何学、线性代数等内容,但是也是非常有意思的一块内容,由于本期主要概述3D流水线的处理流程,所以几何推导这部分就不详细讲了,下期分享会结合DX9中的一些接口及程序示例讲解对应变换矩阵的推导流程。

 

VertexShader——顶点着色器是用来替换这个阶段中固定管线的顶点变换及光照计算的,传统管线处理顶点及光照的方式都是固定流程的,所以固定管线下的3D程序特效都有很大的局限性。引入顶点着色器之后,顶点的在空间中的变换以及光照处理都可以可编程化了,从而创造出许多精美的特效。顶点着色器主要是用来改变顶点固定流程中的变换过程,所以使用顶点着色器表现出来的大多是几何外形的变化以及顶点的光照、纹理等数据的变化。

 

UE3中,是不能直接编写Shader语言的,UE3中把所有Shader特效都绑定到材质中,只能通过材质编辑器来间接的编辑顶点着色器和像素着色器内容。UE3中修改顶点着色器的方式也是在材质编辑器中进行的,其中比较典型的一个输入节点叫做WorldPositionOffset,它就是在顶点管道阶段对材质对应的网格物体顶点进行编辑的一个节点,对应到底层是修改了该材质对应的顶点着色器代码(通过编辑器的HLSL按钮能够看到该材质树对应的Shader代码),如下图所示:

 

应用该材质树后,网格物体将会得到一个在Z轴方向呈现正弦波状的一个柱子:

 

要注意的是,由于这个阶段是属于渲染阶段,它不负责处理任何游戏碰撞逻辑(上面说过游戏逻辑是在CPU中进行的),所以,即使柱子是弯曲的,但是它的碰撞盒还是直立的样子。

 

UE3中,WorldPositionOffset还可以应用于植物的风动效果、水波效果等,通过传入一个风力参数或者是水波顶点受力方向等,在WorldPositionOffset的输入表达式中计算,最终得出该顶点应该渲染的位置。如图所示的材质树(红色框内),显示的是UE3中叶子类植物的风动表达式:

 

应用风动材质的植物:

 

题外话:GeometryShader,几何着色器,是SM4.0引入的。在DirectX9/SM3.0之前,GPU并不包含GeometryShader3D模型的顶点信息是通过CPU这边预先准备好之后,再输入到GPU中,在GPU这里不能随意的进行增减。它的最主要的应用就是曲面细分,让多边形少的模型变成精细程度非常高的模型。几何着色器在上图步骤4中进行处理。下图是曲面细分处理前后的效果比较:

 

 

未做曲面细分前的屋子模型。

做完曲面细分后,可以看到瓦片、烟囱、窗户等地方的三角形数量明显猛增,再结合置换贴图,渲染效果截然不同!

 

虚幻3中,如果DX版本升级到DX11且开启一定的选项,就能够支持曲面细分了。在编辑器中编辑如下:

 

步骤7

这一步英文名写的是Triangle Setup,用中文解释就是光栅化,在3456步骤,处理的主要是顶点单元,即多边形上的顶点,将顶点数据作为输入传入到步骤7中,在步骤7中通过顶点存储的信息将其转化为逐像素三角形画到缓存上,这个过程就叫做光栅化。

如图所示:

 

 

因为3456步骤传入的只有顶点信息,具体如何组织这些顶点来光栅化到屏幕上呢?DX中是通过一个叫做DrawPrimitive的函数来决定顶点的光栅化方法的,比如,输入的顶点是画成线条还是三角形或者是线段带、三角形带等。如下图所示:

 

 

视口上方两个点是按照线段的方式来光栅化的,而下方三个点是按照三角形方式来光栅化的,光栅化的图形像素颜色通过对图形顶点数据进行一定的插值方式来确定。

 

8910步骤

3个步骤统称为像素管道,主要是对步骤7中输入的光栅化像素进行操作的阶段。

这个阶段会逐像素地处理该像素的纹理映射、光照颜色、alpha融合、深度测试、模版测试等,并且根据该像素的距离信息进行雾化公式的应用。所以,顾名思义,像素管道主要处理的是像素信息,最终输出该像素最终的颜色。

 

传统的3D管线只能通过有限几个图形API接口来操作像素,比如DX中设置多纹理的一些接口以及Alpha融合的接口,能够操作的范围很有限。

 

像素着色器所替换固定流水线的功能就是在这个阶段。在引入像素着色器之后,就可以根据需要对像素做许多自由的处理,因为帧缓存内的像素信息不止包含该像素的颜色、Alpha值、深度信息和模版信息,还可以包含该像素对应的法线贴图信息、高光贴图信息、凹凸贴图信息等(这些贴图实际上保存的是一系列向量信息),通过传入一定的参数,比如时间信息、物理量等,就能制作出各种贴近现实的精美特效。

 

UE3中的像素着色器也是通过材质编辑器中的表达式来处理的,UE3材质编辑器中的大部分输入节点都是用于处理像素着色的,如图所示

 

红框内的输入节点,大部分都是像素着色器的处理范畴,在这里可以编辑该材质着色器需要的法线贴图、高光贴图、混合颜色、自发光等信息。

 

下图是UE3中的一个扭曲效果(火焰附近空气的扭曲),通过编辑材质输入的扭曲节点:

扭曲效果:

 

下图是UE3中通过材质编辑器处理的次表面散射的效果,它让人面部较薄皮肤能够产生出透光的效果(这个特效在DX11下支持),应用次表面散射材质的人脸皮肤:

 

编辑器中的输入节点处理:

 

下图是基于图像的反射效果,地面反射了场景中各种高亮物体的倒影:

 

 

步骤11

步骤11是直接将8910步骤中输出的像素内容渲染到屏幕上的过程。但是3D渲染处理还有一个很重要的阶段,叫做后处理阶段,英文名叫做“post-processing”,它与此步骤的处理有所区别,步骤11直接将像素缓存内容输出到显示器中,而后渲染技术则是将步骤11的输出的内容暂时放置到显卡中的一块缓存内,然后利用像素着色器对该缓存的像素进行一些过滤处理来获得一些特殊的屏幕特效,最终输出到屏幕上。比如阴影映射(ShadowMapping)HDR、运动模糊、景深、体积光、卡通渲染等,如下所示特效:

 

高动态光照渲染:HDRHigh-dynamic-rangerendering)用来表现高亮区域特别发亮的效果。HDR通过模糊高亮区域周边像素,增强其亮度的方式,来达到普通屏幕无法表现的高光的效果。

 

运动模糊(Motion blur):现实中的相机或者摄像机拍出的运动的物体在镜头中是会有模糊效果的,而在视频游戏中,因为物体每帧渲染到屏幕上时并没有考虑它的速度,所以无论物体速度如何,在屏幕上显示出来的样子都是很清晰的,如果加上运动模糊的效果,场景中运动的物体会显得更加真实:

射击类游戏里快速转动相机引起周边物体模糊的效果

 

赛车类游戏中,赛场两边景色模糊的效果。

 

体积光(Crepescular rays ):遮光物体被光源照射时,其周围呈现的放射性光柱的效果。

 

景深(Depth Of Field)

远离聚焦点的景物的模糊效果,如下面两幅图

 

 

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引