GAME104第四节

视频:04.游戏引擎中的渲染实践 | GAMES104-现代游戏引擎:从入门到实践_哔哩哔哩_bilibili

游戏渲染面临的挑战

1.非常复杂(成千上万的物体、几十种效果)

2.深度适配当代的硬件

3.预算(性能)非常固定

4.cpu的带宽和使用内存不能太多,存在一定的限制

渲染系统的工作

Rendring 最基础的过程:很多空间的顶点组成一个面,通过投影矩阵投影到屏幕上。接着将面光栅化成一个个小的像素点,在每个小像素点上找到其对应的材质、纹理,然后渲染出来。

投影光栅化、着色(绘制)

渲染硬件GPU

SIMD和SIMT

image-20241028180403322

SIMD Single Instruction Multiple Data 单指令多数据

  • 描述具有多个处理元件的计算机,这些处理元件可同时在多个数据点上执行相同的操作
  • 在CPU广泛使用,简单来讲可以直接四位运算。

SIMT Single Instruction Multiple Threads 单指令多线程

  • 一种用于并行计算的执行模型,其中单指令、多数据(SIMD)与多线程相结合
  • 计算内核做小但很多个,一条指令下来就可以同时做多个计算。

flops:浮点运算能力的指标。

做图形程序时,尽可能同时多个一起跑。

GPU架构

GPC Graphics Processing Cluster 图形处理集群:一个专门的硬件块,用于计算、光栅化、阴影和纹理化。

SM Streaming Multiprocessor 流式多处理器:运行CUDA内核的GPU的一部分

Texture Units 纹理单元:纹理处理单元,可以获取和过滤纹理

很多的运算在GPU上,都是分到Streaming Multiprocessor这个单元去处理的,

CPU与GPU的数据流

数据在计算机中流动有成本,找数据、搬动数据会非常慢。

现代引擎中,逻辑和绘制不是一起的。cpu主要负责计算,若有一部分的绘制运算要在cpu和gpu之间来回,可能会逻辑和画面不同步。游戏引擎中,尽可能让数据单项传输。

Cache缓存

缓存使用对于提高游戏性能至关重要。

减少缓存未命中和内存访问延迟,可以显著提升游戏的渲染效率和整体性能。

冯诺依曼瓶颈 von Neumann Bottleneck:

  • 简单来说,就是处理器速度与内存访问速度之间的不匹配。
  • 在冯诺依曼架构的计算机中,由于处理器(CPU)的速度远远超过内存访问速度,导致处理器在执行程序时需要花费大量时间等待数据从内存中读取或写入,从而限制了整体计算性能的现象
  • 在游戏引擎中,图形渲染和物理计算等任务通常需要大量的数据传输。模型的顶点数据、纹理信息、物理模拟的数据等都需要在CPU和内存之间频繁传输。内存访问速度跟不上CPU的处理速度会导致CPU等待,降低游戏的帧率和响应速度。

可渲染物体

游戏对象用component-based 基于组件的方式描述。

可渲染的物体通过Mesh Render Component描述。

物体渲染描述

Mesh Primitive

Mesh Primitive

一开始通过记录三角面的顶点和顶点数据,描述其网格。

现代引擎记录顶点和顶点索引值,描述网格。

优化:顶点和数据—->顶点和索引值

Materials

Materials 材质

眼睛看到的材质,确定物体的外观以及物体如何与光相互作用。

Materials和Physics Materials 物理材质(摩擦系数)不是一个东西。

Textures

Textures 纹理

image-20241028182341935

  • Albedo 反照率纹理 :定义了物体表面的颜色和基本反射特性,影响光照和颜色表现。
  • Normal 法线纹理 :定义了物体表面的凹凸细节,通过模拟表面法线方向增强细节,无需增加几何复杂度。
  • Metallic 金属度纹理 :定义了物体表面的金属感,影响物体的反射和高光效果,区分金属与非金属材质。
  • Roughness 粗糙度纹理 :定义了物体表面的粗糙程度,影响光线在表面的散射和反射的清晰度。
  • AO Ambient Occlusion 环境光遮蔽 :定义了物体表面因环境遮挡产生的阴影效果,增加场景深度和真实感。

Shaders

Shaders 着色器

shaders是源码的形式,但在引擎中当成数据处理。

shader graph提供艺术家在可视化界面下,通过叠加编辑shader效果,编辑完毕后回生成一段shader源码。

subMesh

subMesh 子网格

现代引擎非常常用的概念。

子网格是模型内部的独立网格部分。

在游戏引擎中,模型可以被划分为多个子网格,每个子网格可以有自己的材质和渲染设置。

单个模型渲染不同纹理

image-20241028165701783

多对象渲染

Resource Pool 资源池

对于多个人,他们用的都是同一个材质、shader等。

现代引擎习惯将shader、Mesh等放入各自的一个Pool,多个人直接是在Pool中引用。

image-20241028165820109

通过submesh把每个对象、物体、mesh按照材质进行切分,接着将相同的材质、相同的纹理、相同的mesh等各自归类到一起,用Pool管理。绘制每一个对象时,直接引用就好。这里就是instance 实例化。

现在游戏引擎,尽可能将绘制交给GPU。

Visibility Culling 可见性裁剪

Bounding Box 包围盒:

  • 一种简单的几何形状,用于在游戏中快速检测物体之间的潜在碰撞或交互,它通常比物体的实际形状要大,以包含整个物体。
  • 简单来说,包围盒就像是物体的“安全距离”,确保物体在移动或旋转时不会与其他物体发生意外的交互

包围盒时很多运算的基础。

image-20241028171522101

  • Sphere 球体:最简单的包围体,适合圆形或近似圆形的物体,计算成本低,但可能不够紧凑。
  • AABB 轴对齐包围盒:与坐标轴对齐的盒子,计算简单,易于实现,但可能不如OBB紧凑。
  • OBB 定向包围盒:可以旋转的盒子,比AABB更贴合物体形状,适合不规则物体。
  • 8-DOP 八方向包围盒:由8个轴对齐的盒子组成,用于快速检测物体间的相交,适合大规模场景。
  • Convex Hull 凸包:紧密贴合物体表面的最小凸形状,计算成本较高,但非常紧凑。

BVH用的很多,动态做Culling很快。

Potential Visibility Set

PVS算法/思想。

把空间分成一个个小方块。在每个房子中时,通过闷/窗,最多可以看到哪几个房间,就渲染哪几个房间。

image-20241028170741157

假设把一个个世界当成一个zone,相当于前面的房间。那这里就可以看成处理场景资源的加载。

GPU Culling

显卡处理能够帮助得到其是否看得到。

early z/high z 思想: 先把场景深度绘制一遍,只要其他物体的深度更加深,那么这个像素甚至整个物体就可以跳掉。

整体都是用GPU告高速并行计算的能力,用廉价的成本行程一群遮挡物的深度图,然后把能扔掉的场景就扔掉。

Texture Compression 纹理压缩

绘制里对图片压缩的思想和普通计算机压缩的思想不同,绘制系统里用的是block-base。

block-base: 把图片压缩成一个个小块。

Block Compression 思想:

  • 找到最暗或者最鲜艳的像素点,其他像素点通过关联度(即与那个参考点的比例关系)去近似表达这个小色块的颜色。
  • 应用的算法有:BC7或DXTC(PC)等。

Authoring Tools of Modeling 建模工具

Authoring Tools of Modeling

Blender、3dMax、MAYA

zBrash 雕刻

Scanning 扫描

image-20241028173118437

现代管道模型

游戏引擎的绘制技术一直在前进。

Cluster-Based Mesh Pipeline

新的模型表达的渲染管线:Cluster-Based Mesh Pipeline

  • 用一个算法,基于数据凭空算出很多的三角形集合。
  • 通过将复杂的三维模型分割成许多小的、固定大小的网格簇(Clusters),来提高渲染效率。
  • 每个簇包含一定数量的三角形,这些三角形在渲染时可以作为一个整体进行处理。

虚幻的Nanite

Nanite虚拟化微多边形几何技术,是UE5的一项关键技术。

Nanite允许游戏开发者使用高多边形数的模型而不会牺牲性能,这些模型可以包含数以亿计的三角形,而无需传统的多边形优化或LOD(细节层次距离)技术。

总结

游戏引擎的绘制系统是一个现代科学,非常依赖硬件的理解。

Mesh、模型和shader之间的关系。

绘制时,尽可能通过一些运算,将绘制的东西减到越少越好,所以Visibility很重要。

越来越多复杂的运算,都从CPU挪到GPU上进行运算。