首页 > 其他分享 >Lecture 04 Rendering on Game Engine

Lecture 04 Rendering on Game Engine

时间:2024-09-01 14:25:37浏览次数:11  
标签:Engine shader 纹理 Rendering Game Mesh GPU Lecture 绘制

Lecture 04 Rendering on Game Engine

Challenges on Game Rendering

  • 成千上万不同类型的物体
  • 在现代计算机上跑(CPU、GPU的复杂结合)
  • 稳定帧率
    • 帧率
    • 分辨率
  • 限制CPU带宽和内存
    • 渲染只占20%左右,剩下留给Game logic、网络、动画、物理和AI系统等等

Outline of Rendering

  • Basics of Game Engine
    • 硬件结构
    • 渲染数据组织
    • Visibility
  • Materials、Shaders and Lighting
    • PBR (SG, MR)
    • Shader模型
    • Lighting
      • Point / Directional lighting
      • IBL / Simple GI
  • Special Rendering
    • Terrain
    • Sky / Fog
    • PostProcess
  • Pipeline
    • Forward, deferred rendering, forward plus
    • Real pipeline with mixed effects
    • Ring buffer and V-Sync
    • Tiled-based rendering

Building blocks of Rendering

渲染管线相关内容见GAMES101,不再赘述

  • GPU

    • SIMD Single Instruction Multiple Data

      一个指令完成多维加减法

      比如矩阵运算、坐标运算下会使用

    • SIMT Single Instruction Multiple Thread

      一条指令在许多核上做同样指令操作

      比如计算着色器、CUDA

      所以绘制时尽可能用同样的代码,使用自己的数据来运算

    • 现代GPU架构

      • GPC Graphics Processing Cluster

        图形处理集群,用于计算、光栅化、着色和纹理

      • SM Streaming Multiprocessor

        用来跑CUDA kernels

        不同SM含有Shared Memory

      • Texture Units

        纹理处理单元,可以fetch和filter纹理

      • CUDA Core

        并行运算单元

      • Warp

        线程集合

  • Data Flow from CPU to GPU

    • CPU与内存
      • 数据加载/卸载
      • 数据预备
    • CPU to GPU
    • 高延迟
    • 带宽限制
    • 因此尽可能单向从CPU往GPU送数据,而不要从GPU读数据
    • GPU和显存
      • 高性能并行渲染
  • Be Aware of Cache Efficiency

    数据恰好在缓存上叫Cache hit,否则叫Cache miss,就要等很久

    • 全力利用硬件并行计算的优势
    • 避免冯诺依曼瓶颈
  • GPU Bounds and Performance

    应用程序性能被以下限制

    • Memory Bounds
    • ALU Bounds
    • TMU (Texture Mapping Unit) Bound
    • BW (Bandwidth) Bound
  • Modern Hardware Pipeline

    • D3D12的mesh shader
  • 其他架构

    • 比如主机UMA架构(内存是共享的)

    • 移动端架构

      考虑到功耗和芯片性能,发展出了Tile-Based Rendering

      two-pass渲染,pass one中不被剔除的图元才在pass two中执行fragment shader

      # Pass one
      for draw in renderpass:
      	for primitive in draw:
      		for vertex in primitive:
      			execute_vertex_shader(vertex)
              if primitive not culled:
              	append_tile_list(primitive)
              	
      #Pass two
      for tile in renderpass:
      	for primitive in tile:
      		for fragment in primitve:
      			execute_fragment_shader(fragment)
      

Mesh Render Component

  • Everything is a game object in the game world

  • Game object could be described in component-based way

  • game object中表达的游戏对象和真实要绘制的是两个东西(mesh component)

  • 在mesh component中会存renderable,拿到renderable就可以绘制出来

  • renderable

    • mesh

    • material

    • texture

    • normal

    • ...

Mesh

  • Mesh包含

    • 顶点位置
    • 法向朝向
    • UV
    • ...
  • Mesh表达

    存顶点索引值,因为顶点会被共用

    • Vertex Data

      • Vertex declaration
      • Vertex buffer
    • Index Data

      • Index declaration

      • Index buffer

        实际上可以不存储Index buffer,可以每个三角形的顶点索引记为一组(triangle stripe)

Materials

在现代引擎中,一般在绘制系统中只定义视觉材质,物理材质单独定义

包含Shader和Texture

  • Phong模型
  • PBR
  • ...

Texture

  • Albedo
  • Normal
  • Metallic
  • Roughness
  • AO
  • ...

Variety of Shaders

现代游戏引擎中shader既可以看作源代码也可以看作Assets

绘制时,需要给一小段代码,叫作blob (二进制数据块),是编译好的shader代码

  • Shader Graph

    连连看生成shader代码

Render Objects in Engine

Coordinate System and Transformation

模型Asset在局部坐标系定义,最终需要渲染到屏幕空间

Object with Many Materials

  • Mesh

    • Vertex Data

      • positions
      • uv
      • ...
    • Index Data

      用Submesh管理,根据材质不同,切分成submesh,对应自己的材质、纹理、shader,但是会把顶点放在一个大的buffer中,这样只需要用offset和count去取就好

      • Submesh
        • offset
        • count
  • Material

    • Shader
    • Textures

Instance: Use Handle to Reuse Resources

如果绘制很多东西时,每个GameObject都存储Mesh、submesh,各种材质、shader、纹理,这样数据量就非常大,并且这里很多东西都是一样的

于是在现代游戏引擎中会建立一个Resource Pool

  • 所有的Mesh放在一起,形成Mesh Pool
  • 所有Texture放在一起
  • 所有Shader放在一起

这样不同Instance只是通过一个指引指向各自需要的材质、网格等等(实例化:使用Handle复用资源)

Sort by Material

每次改变参数(纹理、shader)时损耗大,因为显卡的Streaming Multiprocessor都得停下来等到改好再运转

场景中相同材质的物体有相同的参数、相同的纹理,那么将场景中的物体按照材质排序,只设置一次材质,绘制一个个Submesh,速度就会更快

比如像DX12、Vulkan会专门将GPU的状态设置专门抽象成一个Render State Object,对显卡状态先定义好,然后一次性做大量的运算

GPU Batch Rendering

很多子物体是一模一样的,那么依次设置VBIB (Vertex and Index Buffer Validation 顶点和索引缓冲区验证) 也很浪费,所以用计算着色器或者其他shader的能力,可以一个drawcall,设置依次VBIB,和它绘制的一堆位移的数据,就能一次性创建成百上千个物体

struct batchData
{
    SubmeshHandle m_submesh_handle;
    MaterialHandle m_material_handle;
    std::vector<PerInstanceData> p_instance_data;
    unsigned int m_instance_count;
}

Initialize Resource Pools
Load Resources
    
Collect batchData with same submesh and material
    
for each BatchData
    Update Parameters
    Update Textures
    Update Shader
    Update VertexBuffer
    Update IndexBuffer
    	Draw Instance
end

将大量的绘制运算交给GPU而不是CPU,比如一次性要绘制几百米开外的树、草

Visibility Culling

大多数空间的物体、对象、粒子效果、地形等都不需要绘制

Visibility Culling是绘制系统一个最基础的系统

检测物体包围盒在不在视锥体

  • 包围盒

    • Sphere

    • AABB

      轴对称包围盒,轴是游戏世界中的坐标轴,那么只用存两个端点就能构建出一个AABB,计算效率仅次于Sphere包围盒

    • OBB

      贴着物体走

    • 8-DOP

    • Convex Hull

      凸包

  • 包围盒是很多计算的基础

    • intersection test消耗不高
    • Tight fitting
    • 计算开销小
    • 旋转和位移简单
    • 内存消耗小
  • Hierarchical View Frustum Culling

    • Quad Tree Culling

      四叉树Culling

    • BVH (Bounding Volume Hierarchy) Culling

      现代游戏引擎用得多,BVH效率不是最高的,但是因为动的物体多,重新构建层级结构快

    • PVS (Potential Visibility Set)

      一种思想,现在全面用PVS做Culling的游戏不多了,但是这种思想很有用,比如说线性单机游戏,在每个区域能看到区域是固定的,这样做除了Visibility Culling外还可以用作资源的加载

      在大世界中的应用可参考UE5的City Sample

      先用BSP-Tree

      先将空间分成一个个小方块,每个小方块通过一个Portal连接,在每个方块中通过Portal只能看到固定几个方块,比如图中在7号房间只能看到6、1、2、3四个房间,那么就只需要渲染这四个房间

      原理简单,但对空间的划分算法比较复杂

Texture Compression 纹理压缩

纹理压缩不能用图片上比较好的压缩方法,比如JEPG格式,因为不支持随机访问

纹理压缩一般采取的思想是Block-based,将图片切成一个个小块(比如\(4\times4\)),然后找其中颜色最亮的点和最暗的点,那么剩下的点就是这两个点的插值(因为很多图片相邻的像素都有关联),

于是就只能存一个最大值,一个最小值,然后每个像素存一个离最大值、最小值的比例关系,就能近似表达这个小色块的颜色,整个计算机图形学的纹理压缩都是基于这个思想的

  • PC

    • BC7 (modern)
    • DXTC (old)
  • mobile

    • ASTC (modern)

      分块可以不再是严格的\(4\times4\),而是任意形状,而且效果是最好的,解压缩的效率也不低,但是压缩的运算比较费性能,不能运行中进行压缩

    • ETC / PVRTC (old)

构建引擎时纹理压缩是非常重要的模块,而且加载到显卡中的基本上是压缩过的数据格式

Authoring Tools for Modeling

Comparison of Authoring Methods

  • Polymodeling
    • 灵活
    • 工作负担大
  • Sculpting
    • Creative
    • 大量volume of data
  • Scanning
    • Realistic
    • 大量volume of data
  • Procedural modeling
    • Intelligent
    • 难以实现

Cluster-Based Mesh Pipeline

将复杂模型分成一个个小的meshlet(比如32个三角形),每个meshlet固定后,计算是非常一致的、高效的

这样每个Instance都能并行化绘制

  • GPU-Driven Rendering Pipeline (2015)
    • Mesh Cluster Rendering
      • Arbitrary number of meshes in single drawcall
      • GPU-culled by cluster bounds
      • Cluster depth sorting
  • Geometry Rendering Pipeline Architecture (2021)
    • Rendering primitives are divided as:
      • Batch: a single API draw (drawIndirect / DrawIndexIndirect), composed of many Surfs
      • Surf: submeshes based on materials, composed of many Clusters
      • Cluster: 64 triangles strip

Programmable Mesh Pipeline

  • 游戏引擎与硬件结构涉及深度相关
  • submesh design被用于单个模型的多材质
  • 使用culling算法减少绘制物体
  • 将更多工作移至GPU (GPU-Driven)

Q&A

  • 图形代码的Debug
    • 不要一次性写完所以代码,每次写一部分,反复验证,没问题后再继续

标签:Engine,shader,纹理,Rendering,Game,Mesh,GPU,Lecture,绘制
From: https://www.cnblogs.com/Tellulu/p/18391253

相关文章

  • Lecture 13 Real-time Ray Tracing 2
    Lecture13Real-TimeRayTracing2Implementingaspatialfilter这里想做的是低通滤波移除高频信号会不会丢失高频中的信息?噪声不一定只在高频中集中在频域这些filtering可以应用在PCSS、SSR上的降噪用$$\widetildeC$$表示有noise的图像\[K$$表示滤波核kernel,比......
  • Lecture 14 A Glimpse of Industrial Solutions
    Lecture14AGlimpseofIndustrialSolutionsTemporalAnti-Aliasing(TAA)为什么有aliasing光栅化期间SPP不足(样本数量不足)终极解决方案是用更多的样本(MSAA)TemporalAnti-Aliasing跨越实际贡献/复用采样思路和在RTRT中如何利用temporal的信息一模一样思路......
  • Lecture 02 Layered Architecture of Game Engine
    Lecture02LayeredArchitectureofGameEngine渲染只是游戏引擎中不大的一部分ToolLayer工具层这部分不是实时的,所有可以允许多种实现方法(C++/C#开发等等)DCCDigitalContentCreation将不同文件导入成Assets·FunctionLayer功能层每个tick依次做完所有内......
  • Lecture 03 How to build a Game World
    Lecture03HowtobuildaGameWorldEverythingisaGameObject(GO)面向对象的方式有些GO之间并没有清晰的继承关系Unreal中的UObject、Unity中的Object并不是这里讲的GameObject概念,而是更类似如C#中的Object,用于确定任何对象的生命周期需要的句柄Unreal中的GameOb......
  • Lecture 08 & 09 Real-time Global Illumination (screen space)
    Lecture08Real-timeGlobalIllumination(screenspace)GIinScreenSpace只使用屏幕空间的信息换句话说,在现在的渲染结果上做后处理ScreenSpaceAmbientOcclusion(SSAO)为什么要环境光遮蔽容易实现增强场景中的物体和物体间的相对位置(立体感)什么是SSAOAO的......
  • Lecture 10 & 11 Real-time Physically-based Materials (surface model)
    Lecture10Real-timePhysically-basedMaterials(surfacemodelsandcont.)PBRandPBRMaterialsPhysically-BasedRendering(PBR)基于物理的渲染渲染内的任何事都应该是PBR的材质、光照、相机、光线传播等等不限于材质,但常常指材质PBRmaterialsinRTR......
  • Lecture 12 Real-time Ray Tracing
    Lecture12Real-TimeRayTracingBasicideasampleperpixelPPS1SPPpathtracing=$$\downarrow$$camera出发打到求出第一个交点(像素上看到的点),这一步是primaryray(工业上实际用rasterization)工业上这一步有一个技巧将这一步改为光栅化因为每个像素都要从camera出......
  • Lecture 04 Real-time Shadows 2
    Lecture04Real-timeShadows2PCFandPCSSPCF背后的数学知识Filter/convolution:如果对某个函数\(f\)做卷积,可以用\([\omega*f](p)=\underset{q\in\Nu(p)}{\sum}w(p,q)f(q)\)比如PCSS中对某一点q周围区域做卷积求visibility\(V(x)=\underset{q\in\Nu(p)}{\sum}w......
  • Lecture 05 Real-time Environment Mapping
    Lecture05Real-timeEnvironmentMappingRecap:EnvironmentLighting一张表示了来自四面八方的无穷远处光(distancelighting)的图片Sphericalmapvs.cubemapShadingfromenvironmentlighing非正式地命名为Image-BasedLighting(IBL)\[L_o(p,\omega_o)=\int_{\Om......
  • Lecture 06 Real-time Environment Mapping (Precomputed Radiance Transfer)
    Lecture06Real-timeEnvironmentMapping(PrecomputedRadianceTransfer)Shadowfromenvironmentlighting通常情况下要实时渲染非常困难在不同观察方向上Asamany-lightproblem:CostofShadowMapislinearlyto#lightAsasamplingproblem:Visibility项V会......