目录
《GAMES104》渲染系统课程大纲
渲染概述
游戏渲染面临的挑战
渲染流水线
着色
纹理采样(Texture Sampling)
GPU的概念
SIMD and SIMT
GPU Architecture
CPU到GPU的数据流
缓存(Cache)
Renderable可渲染对象
Mesh
Materials
坐标系与变换(Coordinate System and Transformation)
SubMesh
资源池(Resource Pool)
Visibility Culling (可见性裁剪)
Bounding Volume Hierarchy Culling
Potential Visibility Set
GPU Culling
纹理压缩(Texture Compression)
Authoring Tools of Modeling
Cluster-Based Mesh Pipeline
Take Away
我们首先看到渲染技术的发展
以及作为游戏引擎渲染基础的图形学理论
一个容器中同一时刻有大量的游戏对象需要进行渲染,并且不同对象渲染的形式、算法还有所差异,这些使得游戏的绘制系统变得非常复杂;其次,游戏引擎的渲染还要与当代的硬件适配;同时,游戏引擎需要保证渲染的稳定性,即使进入非常巨大复杂的场景,也要在至少1/30ms内完成绘制,随着玩家需求的提高,这一时间甚至可能被缩短到1/60ms、1/120ms之内;游戏引擎的渲染还要考虑到可用的计算资源,一般渲染可用资源只能占到百分之十左右,还需预留资源用于GamePlay等系统。
这一过程将一个个顶点数据进行投影(Projection)、光栅化(Rasterization),形成许多像素点,许许多多的像素点便组成了我们看到的画面。
在着色的时候我们会对某些常量/变量进行访问,比如说屏幕长和宽的像素数量;会进行一些数学运算,比如计算光照时寻找法线的位置,以及光线的衰减程度;还会进行纹理采样等计算。
为了防止走样现象,也就是为了防止在游戏中当我们的视角由近及远移动时产生的画面抖动,我们会在层级与层级之间进行插值,还会在每个层级中的相邻像素点之间进行插值,构成多级渐远纹理(Mipmap)。
对于图形程序中的复杂计算,我们交由另一独立硬件处理——GPU,也正是GPU不断的发展进步,才有了现在越来越精致的画面。
数据在不同的运算单元之间读取传输是十分消耗资源的,所以一般只让数据由CPU单向流动到GPU。
我们在存放数据时一般集中存放,就是为了便于缓存的读取,即缓存命中数据(Cache hit);若缓存不断的无法读取数据(Cache miss),不断的重新读取,将会大大降低处理的效率。
现代计算机的结构就是一条流水线,每一个环节的效率低下都可能限制整体的表现。
一个应用的表现就受限于:
起初的网格体数据储存方式并不高效,它储存每个点的位置,法线朝向等属性,进而储存每三个点组成的三角形的数据,而这一个个三角形的数据便构成了这个网格体的数据。
因为每个顶点是由多个三角形公用的,所以我们可以通过只储存每个顶点的数据和对应的索引值,绘制三角形时根据索引值顺序绘制来提高效率。
为什么每个顶点都需要定义法线方向?
当绘制表面有折线时,可能会出现顶点位置一样,但法线方向完全不同的情况,所以每个顶点都需要定义法线方向。
材质决定了物体的外观和被光线照射时的表现
比较著名的材质模型有:Phong Model、PBR Model等等
纹理(Texture)是材质的一种非常重要的表达方式
着色器(Shaders)也是Renderable对象的一个重要组成部分
我们可以通过不同的投影变换将物体投影到不同的坐标系中,具体原理参考GAMES101课程
我们根据Mesh的材质不同将其分为许多子网格(SubMesh),每个子网格存储一个Offset值,在计算时只需要通过对应的Offset值便可知道该部分三角形使用的材质
在储存时,为了节省资源以及方便相同资源的复用,我们会将每个游戏对象切分为Mesh、Material、Shader等,并将相同类型的资源储存到一个统一的资源池中,比如Material类型的资源统一储存在Material类型对应的资源池中
相应的,每一个游戏对象也就是这些资源的实例化组合
为了提高速度,我们可以将资源池中可复用的资源按照材质分类后再传入GPU中
同时,我们注意到游戏中许多子物体也是相同的,我们也可以利用上面的策略,在一次绘制指令中,创建许多对象,但只传入一次Vertex Buffer和Index Buffer,通过避免重复传入来提高速度
游戏世界中一般只绘制视锥中的物体
不同的包围盒模型:
从最大的包围盒开始依次向下级包围盒做裁剪剔除
当玩家每经过一个Portal时,就只绘制当前所在的Zone内可以看见的其他Zone,这一思想可以用于动态载入场景
通过GPU对不同面之间的交集的快速计算,以此来裁剪剔除无需渲染的面
对传统的图片压缩格式(如JPG、PNG)采样需要全部解压,无法实现随机访问其中的一个点,并且采样的计算十分复杂
因此游戏引擎中一般采用块压缩(Block Compression),这种压缩使得我们只需要知道图片中像素的极大值和极小值以及其他像素相对两者的插值的坐标,便可以得到原先的图片
随着开放世界、3A大作的流行,模型的细节、精度也越来越高,也就需要新的模型管线Cluster-Based Mesh Pipeline。它将一个高精度模型按规律分为许多簇(Cluster),一簇可以是64个面片,这种细分使得我们可以对随机的簇进行绘制指令,并根据深度进行排序
Unreal的Nanite就是上述思想细分到像素级别的体现,也是上述思想的工业化体现
课程传送门:04.游戏引擎中的渲染实践 | GAMES104-现代游戏引擎:从入门到实践_哔哩哔哩_bilibili