精华内容
下载资源
问答
  • 游戏渲染
    千次阅读
    2021-12-28 16:27:49

    需要注意的是,本文涉及的内容过多过杂,基本涉及到游戏渲染和图形管线的方方面面。内容是根据多方面的资料整理而成,比如本人的Unity和Unreal引擎相关的理解和认知,以及引擎相关官方文档等,以及DirectX和OpenGL相关官方文档等,以及网络上各种相关文章和资料等。可能有一些纰漏或者不足之处,或者有些阶段的资料来源较为单一,本人主要目的是从概念理解上对应整个游戏引擎的渲染管线,不一定和真实的游戏完全一一对应,比如应用程序阶段的知识对应到游戏引擎应该会有一些区别和取舍,几何阶段和光栅化阶段主要参考的是OpenGL和DirectX,Vulkan和Metal相关资料参考较少,可能不同的图形API会有一些出入。由于涉及内容过多,难免理解不到位,有发现比较明显错误的,请指出以尽早修正,避免造成误解。

    一、渲染管线的思维导图

    这是本文内容的思维导图,通过该图可以从整体上把握全文的内容,对渲染管线有整理的理解。

    二、应用程序阶段

    2.1 渲染数据加载

    这个阶段指的是将渲染所需要的相关数据,比如模型、贴图、材质、Shader等加载到内存中,通常只发生一次,不需要每帧重复加载。比如,Unity游戏需要在运行时,将需要的场景或者人物从AssetBundle中加载出来,然后引擎才能显示加载的场景或者人物。

    2.2 物体级别的裁剪

    以下描述的裁剪算法是按照粒度从粗到细的裁剪,相应复杂度和代价也是在递增。最简单的是基于距离的裁剪;然后是利用空间数据结构实现的视锥体裁剪;动态的入口裁剪是一种特殊情况,可以算在视口裁剪内也可以用于预计算;然后预计算数据的裁剪;接下来才是动态的遮挡剔除。

    2.2.1 基于距离的裁剪

    思路是超过一定的视距即不渲染该物体,Unreal引擎支持这个特性,参考Cull Distance Volumes。对于Unity,可以使用CullingGroup实现类似的功能。即使引擎没有提供类似的支持,在游戏逻辑层面,先可以每帧或者隔帧判断物体跟摄像机的距离,来动态显示隐藏物体。

    2.2.2 视锥体裁剪

    用物体跟摄像机视锥体做相交测试,将完全没有相交的物体过滤掉。为了加快速度,使用的是物体的包围盒或者包围球跟视锥体做相交测试。游戏引擎内一般都会有空间数据结构来组织物体,比如BVH,那么可以直接使用BVH来搜索加速这个计算。具体过程是用视锥体和空间数据结构去做相交测试,如果当前节点没有相交,那么不需要继续,如果有相交则继续遍历子节点直到叶子节点或者没有相交,叶子节点中存储的物体即是需要渲染的物体。

    基于空间数据结构的裁剪

    四叉树和八叉树

    四叉树对应的是二维空间,下面以八叉树为例来说明。八叉树是将三维空间平均划分为八个部分作为八个子节点,重复划分到一定的粒度为止,比如叶子节点内最多存储多少个物体,物体存储在叶子节点内。
    优点:概念和实现简单。
    缺点:无限空间不好划分;物体可能跨越分割面;物体分布不均匀会造成层次过深,搜索效率不高。
    适用场景:四叉树适用于基于高度场的地形管理;八叉树室适用于室外分布均匀的三维场景(有高度)。

    BSP

    针对八叉树这种不均匀划分,如果将物体均匀划分成两部分,那么就是Binary Space Partition Tree,可以避免树的层次过深。注意,BSP的每个节点存储的是划分平面,而不是物体,划分平面将场景分为前后2个部分,分别对应左右子树;由于需要BSP树针对的多边形,因此可以针对物体的AABB包围盒做划分。

    优点:物体分布均匀,不会出现树层次过深;支持任意空间。
    缺点:实现复杂,构造时间长,不适合动态场景。
    适用场景:紧凑并且分布均匀的室内场景;静态场景;自带物体排序,方便实现画家算法。

    KD-Tree

    BSP全称是K-Dimensional Tree。这是一种特殊的BSP,在BSP上进一步将划分面限制跟坐标轴垂直,但是保持从物体分布的中间划分,以尽可能得到一个物体分布均匀的树。KD-Tree不仅仅可以用来做空间划分,在其它领域经常用来组织K维度的数据来做搜索,比如K维数据查询、近邻查询。
    优点:物体分布均匀,不会出现树层次过深;数据可以组织为数组形式的完全二叉树,缓存友好等。
    缺点:如何确定最优或者较优的划分面?
    适用场景:紧凑并且分布均匀的室内场景;辅助其它数据结构进行邻域查询。

    BVH

    全名是Bounding Volume Hierarchy,中文翻译层次包围盒。BSP和KD-Tree的节点代表的都是分割面,但是面有可能穿过物体。层次包围盒的思想是每个节点代表一个空间,空间计算其包含物体的最小包围盒,划分空间后重新计算子空间的包围盒。与BSP最大区别是节点代表的不再是分割平面而是包含最小包围盒的子空间。因此,这些子空间可能出现一定的重叠,但是不会出现物体出现在不同的划分里面。
    优点:节点存储的是物体,方便碰撞检测等查询;构建快,动态更新方便。
    缺点:如何确定最优的包围盒?
    适用场景:视锥剔除;物体碰撞检测;射线检测;光线跟踪。

    空间数据结构的其它应用

    除了视锥体裁剪外,空间数据结构还有很多其它应用,比如
    1、Ray Casting (射线检测)
    2、碰撞检测
    3、邻近查询 (比如查询玩家周围敌人)
    4、光线追踪

    Portal Culling(入口裁剪)

    适用于将场景划分为格子,格子之间可能存在入口的情形,如下图所示,
    Portal Culling
    从入口只能看到部分被墙壁遮挡住的物体,因此可以借助这个特性加速视锥体和格子的相交裁剪。Unity中的Occlusion Portal即是这个特性。如果预计算出Protal Culling的结果,那么可以在运行时加快物体裁剪。

    2.2.3 预计算遮挡剔除

    这是一种空间换时间的算法,会增大内存占用,降低Cpu的裁剪消耗。所以是否需要预计算遮挡数据,还需要具体讨论。一般如果内存消耗不大,但是Cpu占用较高的话,可以尝试开启预计算遮挡数据。

    Precomputed Visibility (UE4)

    参考虚幻引擎的Precomputed Visibility。思想是将场景划分为格子,计算每个格子内可以看到的可见物体集合相关的数据,用于运行时动态查询。

    预计算Occlusion Culling (Unity)

    参考Unity的Occlusion culling。类似于UE4的Precomputed Visibility,不过Unity的Occlusion Culling也支持动态物体,但是动态物体只能occludee(被遮挡物体)。Unity的预计算Occlusion Culling应该是入口剔除的一种预计算实现。

    2.2.4 动态遮挡查询

    这里讲的是在CPU上或者GPU上实现的遮挡查询。图形API已经提供了遮挡查询相关的接口,比如OpenGL的Query Object或者DirectX的Predication Queries。但是不是所有的硬件都能够支持,因此可以在软件层面即在CPU上做软渲染实现遮挡查询。Hierarchical Z-Buffer Occlusion则是在普通的硬件遮挡查询上的进一步优化,使用了层次Z-Buffer来进一步加快速度。

    软件遮挡查询

    软光栅化模仿硬件遮挡查询,因此不受设备类型限制,只是需要额外消耗CPU。

    硬件遮挡查询

    使用图形接口本身提供的遮挡查询接口。基本思想是用物体的包围盒去渲染Z-Buffer,统计通过深度测试的像素数目,如果有通过说明当前物体没有被完全挡住,保存结果用于下一帧查询。因此,硬件遮挡查询会存在两个问题:额外的渲染消耗和延迟一帧。

    Hierarchical Z-Buffer Occlusion

    类似硬件遮挡查询,不过使用Hierarchical Z-Buffer来加快查询速度。具体实现比较复杂,请参考相关文章。

    2.2.5 LOD切换

    LOD指的是Level Of Details。如果物体通过了以上的裁剪,那么说明会提交给渲染线程进行处理。LOD切换指的是这些物体的细节层次切换,比如一些不重要的或者看不清楚的物体选择更简单的模型。

    基于距离的LOD切换

    最常见的方式是根据摄像机距离来进行LOD切换,越远的物体选择更简略的LOD,Unity和UE4默认是这种方式。

    基于渲染分级切换LOD

    但是我们也可以主动切换LOD,比如检测到当前硬件较差,需要切换到更低的画质,那么可以根据游戏设置的渲染品质分级来切换低的LOD。

    LOD过渡

    LOD的一个常见问题是LOD的过渡问题,可能在切换LOD时候会察觉到明显的过渡。常见的方式是在切换时候混合2个LOD,比如透明度逐渐从1变化到0或者从0变化到1,避免出现明显的过渡。

    2.3 物体级别的渲染排序

    为了减少OverDraw或者实现半透明效果,所有通过裁剪的物体会按照一定的次序进行渲染。下面列举几个常见的渲染次序。游戏引擎实际的渲染过程还会跟引擎渲染管线的Pass定义顺序相关,比如不透明和透明物体在不同的Pass内渲染的,而且是先在一个Pass内渲染透明物体,再在另外一个Pass渲染透明物体。

    从前到后渲染(不透明物体)

    从前到后渲染可以利用Early Z-Test过滤掉不必要的片元处理。因此,如果先渲染近处的物体,那么后面渲染的远处物体就不会通过Early Z-Test,就不会进入片段处理阶段。不过,不是所有的硬件都需要按照从前到后的物体顺序进行渲染,这毕竟需要额外的CPU消耗来排序物体,部分支持HSV(hidden surface removal)特性的GPU,比如PowerVR是不需要做这个排序的。Unity提高了静态变量SystemInfo.hasHiddenSurfaceRemovalOnGPU来查询GPU是否支持HSV,
    Urp渲染管线会根据这个来判断是否需要跳过从前到后排序物体。

    从后到前渲染(半透明物体)

    由于半透明物体的渲染算法要求必须从后到前渲染物体,同时关闭深度测试 ,前面的物体与后面的物体进行颜色混合。那么这个排序过程是无法省掉的,类似从前到后渲染的排序,可以采样BSP来排序物体。

    渲染层级或渲染队列

    Unity同时定义了这2种排序,不过SortingLayer的优先级更高,这个是定义在物体的Renderer组件上。RenderQueue是定义在Shader和材质上,优先级在渲染层级之后。理论上,就是对所有物体进行优先级排序。

    最少渲染状态切换

    还有一种方式是尽可能在渲染物体的时候避免渲染状态切换,这样能够尽可能减少CPU消耗。那么可以在CPU计算出来一个最优的渲染顺序来尽可能减少渲染状态切换。

    2.4 渲染数据绑定和状态设置

    这一个阶段讲的是在CPU上设置渲染相关数据和状态,以及为了减少渲染状态切换的渲染合批的思想。

    视口设置

    设置窗口的渲染区域,比如OpenGL的glViewport。通过这个设置,我们可以在一个窗口上渲染多个不同的视口,比如游戏的分屏。

    FrameBuffer设置

    一般游戏引擎不会直接将物体渲染到默认的渲染缓冲上,单独的RenderTarget方便进行后处理,在后处理之后再Blit到默认缓冲上。一个FrameBuffer可以包含颜色、深度、模板三个附件,也可以将深度和模板组织成一个32位的RT。

    渲染合批

    渲染合批指的是为了减少渲染状态切换的一种优化手段,Unity URP渲染管线的SRP技术可以大幅度优化渲染批次。这是一个在Shader变体层次的合批,与之前的材质层次的合批相比有很大的优化。

    顶点输入绑定

    对于OpenGL来说就是创建和绑定VAO(Vertex Array Object)。一个VAO中可以包含VBO(Vertex Buffer Object)、IBO(Index Buffer Object)。然后用glVertexAttribPointer和glEnableVertexAttribArray指定数据到Shader的输入变量。
    顶点属性通常包括,位置、法线、切线、UV、顶点颜色等。

    Shader绑定

    渲染数据绑定好之后,需要指定当前使用的Shader,这包括Shader的编译链接和使用等(假设Shader代码已经加载进来)。

    Shader编译链接使用

    类似于CPU上运行的程序,Shader也需要编译链接以及开始使用的过程,不过这个过程基本上是固定。
    可以参考learnopengl的着色器一节。

    Uniform变量绑定

    Shader中通常会有很多全局变量,比如MVP、摄像机位置、光的信息等。这些都需要在CPU上传入Shader中。

    Output-Merger Stage相关设置

    在渲染管线的最后(片元着色器之后),有一个Output-Merger阶段,也叫做Raster Operations。这是一个不可编程阶段,但是有很多选择可以设置。比如剪切测试、模板测试、深度测试、颜色混合因子和函数、sRGB转换等。这些都需要在应用程序阶段进行设置。

    2.5 DrawCall调用

    终于到了应用程序的最后一步,即DrawCall的调用了。OpenGL对应的接口是glDrawArrays或者glDrawElements

    三、几何处理阶段

    这是第二个大的阶段,当前阶段已经进行GPU中了。该阶段的起点和主要过程是顶点着色器。除了着色器之外,其余阶段都是硬件自动进行的,除了可选阶段之外,其余的都是固定的,应用程序无法根据配置来进行更改。

    3.1 顶点着色器

    顶点着色器的处理对象是应用程序阶段绑定的每个顶点,顶点着色器会获得顶点属性以及相应的Uniform变量。顶点着色器的输出是一个NDC Clip Space的顶点位置。NDC(Normalized device coordinates)是规范化设备坐标系的位置,OpenGL的范围[-1,1],DirectX的范围是[0,1]。之所以说是Clip Space,因为该阶段得到的顶点数据是一个齐次坐标,还需要进行透视除法,即x、y、z除以w分量才能得到NDC坐标系下的位置。

    3.2 曲面细分着色器

    曲面细分着色器是一个可选阶段,用于将一个简单模型细分成复杂的模型。其实该阶段是2个着色器和一个固定阶段的组合。在DirectX中叫做Hull Shader stage、Tessellator stage、Domain Shader stage;在OpenGL的Tessellation中叫做Tessellation Control Shader、Tessellation Primitive eneration、Tessellation Evaluation Shader。具体的介绍和使用方式请参考相关资料。

    3.3 几何着色器

    几何着色器也是一个可选阶段。几何着色器的输入是图元的顶点集合(比如三角形图元有三个顶点,点图元只有一个顶点),输出是一个新的图元,新的图元也要包含一个顶点集合。简单来说,几何着色器的输入和输出都是图元,输入的图元是在应用程序阶段指定的,输出的图元可以在顶点着色器中实现。

    3.4 Stream Output (Transform Feedback)

    这是一个可选的阶段。这个阶段在DirectX中叫做Stream Output ,在OpenGL找叫做Transform Feedback。如果该阶段开启,那么顶点数据流会输出到一个Buffer中,这个Buffer可以给顶点着色器使用也可以返回给CPU,当前渲染管线则不会进行接下来的处理。

    3.5 图元组装

    这一步是将之前得到的顶点数据组合成图元,比如顶点图元、线段图元、三角形图元。该阶段输出图元进行接下来的处理。

    3.6 透视除法和NDC裁剪

    该阶段的输入是组装好的图元,输出的是NDC裁剪之后的图元。首先对图元的顶点进行透视除法,这样得到的顶点数据都会位于NDC内,方便进行NDC裁剪。图元裁剪后可以会产生新的图元。

    3.7 屏幕空间映射

    该阶段是将NDC下的图元顶点坐标映射到屏幕空间。值得注意的是顶点坐标是一个齐次坐标,透视除法后得到的是NDC下的坐标;然后,通过一个缩放和平移变换将x和y映射到屏幕空间。

    3.8 面剔除 (Face Culling)

    这一个阶段指的是三角形的前后面剔除。前或者后的定义是根据正视三角形的时候定义三角形顶点的旋向,可以定义逆时针旋转或者顺时针旋转为前面。实际上,面剔除跟实际的摄像机位置没有关系,不管摄像机转到哪个地方,前后面不会改变,比如渲染立方体的时候,后面都是立方体内部看不到的面,无论摄像机如何旋转。因为,前后面的定义是固定视角正对三角形时候定义的。

    四、光栅化阶段

    该大的阶段的输入是几何处理阶段输出的图元。该阶段主要分为四个部分,首先是光栅化图元得到片元(潜在的像素信息),然后进行Early Fragment Test,通过测试后再进行片元着色器,最终进行输出合并阶段的各种测试以及颜色混合等,再输出到颜色缓冲区。

    4.1 图元光栅化

    该阶段是将图元的顶点信息进行线性插值,然后生成片元数据。每个片元上有顶点信息线性插值而来的片元数据。需要注意的是,这个插值是线性的,如果有一些数据是非线性的,则不能在顶点着色器中计算然后输出到片元着色器,因为线性插值的结果和在片元着色器中计算的结果是不一致的。
    这里需要特别说明的是,关于深度z’的生成。屏幕空间映射后的z’是关于摄像机空间z倒数的一个线性函数。之所以使用1/z而不是z,是为了在近处获得更好的深度缓冲精度,因为1/z在近处的变化更快,可以优化Z-Fighting这种现象。由于z’不是一个关于z的线性函数,因此z’应该是在光栅化后硬件自动根据1/z计算出来的,而不是先计算z’再光栅化。

    4.2 Early Fragment Test

    参考OpenGL的Early Fragment Test,可以看到不仅仅通常所说的Early Z-Test还有其它好几个阶段都可以进行EarlyTest,一共是四个测试(Pixel ownership test、Scissor test、
    Stencil test、Depth test)和遮挡查询更新。根据文档,Pixel ownership test和Scissor test从OpenGL4.2起会总是在EarlyTest阶段进行。那么,如果这些测试没有在EarlyTest阶段进行,则会在最终的输出合并阶段进行;如果进行了,那么输出合并阶段也不会重复处理。

    Early Z-Test的限制

    不要在片元着色器中改变深度,比如glsl的gl_FragDepth;也不要discard片元,通常实现AlphaTest会根据Alphadiscard片元。因为这些操作会导致硬件无法预测最终的深度,从而无法进行提前深度测试。

    4.3 片段着色器

    片段着色器的输入是光栅化来的各种顶点属性,输出是一个颜色值。该阶段是计算光照结果的主要阶段。通常片元着色器会有比较复杂的计算,通常的优化手段是将计算转移到顶点着色器甚至CPU(应用程序阶段,用Uniform传入)上。

    4.4 Output-Merger Stage(Raster Operations)

    终于进入最后的输出合并阶段,该阶段的输入是一个个的片元。片元需要进行一些列的测试和转换,最终才会将颜色输出到缓冲区上。

    Pixel ownership test

    根据OpenGL的文档,该阶段只对默认缓冲区生效,用于测试像素是否被其它窗口遮挡的情形。对于自定义的FrameBuffer,不存在这个测试。

    Alpha Test

    需要特别说明的是,Alpha测试当前是已经被废弃了,从DirectX10和OpenGL3.1开始废弃,参考Transparency Sorting文档;当前需要在片元着色器用discard实现。列在这里主要是为了完整性。

    Scissor test

    参考OpenGL的剪切测试文档,Scissor Test。通过在应用程序阶段设置,可以让片元只通过视口的一个小矩形区域。根据EarlyTest的文档,推测该阶段目前都在EarlyTest阶段进行了。

    Multisample operations

    如果启用了MSAA,那么需要进行resolve才能够输出到默认颜色缓冲中,进行屏幕显示。假如在默认缓冲中开了MSAA,那么从MSAA的后备缓冲交换到前向缓冲就需要进行resolve操作,因为前向缓冲是single-sample的。如果是自定义的FrameBuffer开启了MSAA,那么在Blit到默认缓冲区的时候也需要进行resolve操作。

    模板测试

    模板测试基本思想是用一个八位的模板缓冲,一个参考值,一个比较函数,一个掩码,用该参考值和片元对应的模板缓冲值使用比较进行比较(比较之前进行掩码),通过的则片元可以继续进行深度测试,否则丢弃。另外还可以定义模板成功和失败,以及深度测试成功和失败后模板缓冲如何变化。可以参考OpenGL的Stencil Test文档。
    模板测试的一个常见的应用是描边或者在像素级别分类。

    深度测试

    深度测试是根据当前片元的深度值与深度缓冲进行比较,比较函数可以设置,通过比较的片元才会进行接下来的处理,否则丢弃当前片元。

    遮挡查询更新

    参考OpenGL的遮挡查询文档Query Object
    该阶段会更新遮挡查询的结果,因此遮挡查询的结果只能用于下一帧渲染。

    颜色混合

    需要注意的是,容易误解半透明渲染才会有颜色混合,实际上颜色混合是管线的一个固定的阶段,不透明渲染也会有默认的混合方式。
    理解颜色混合,首先要明白2个概念,source和dest,source指的是当前的片元,dest指的是要目标缓冲中对应的颜色。
    颜色混合主要是需要设置2个函数,一个函数用于设置混合因子,一个函数用来设置混合函数。混合因子有四种,source rgb和dest rgb,source a和dest a,可以一起指定也可以分开指定。具体可以参考OpenGL的Blending文档。

    sRGB转换

    1、我们知道显示器或者颜色纹理的颜色空间是sRgb,sRGB空间就是Gamma校正的颜色空间,也就是已经Gamma校正过的颜色数据,这样子在显示器上才能正常显示。如果我们使用的线性工作流,也就是在线性空间中制作资源,编写Shader计算光照结果,那么片元着色器的输出需要转换到sRgb空间。这个转换部分硬件上是自动支持,对于不支持的硬件则需要在Shader里面转换。
    2、如果要硬件自动转换,首先要创建的必须是srgb颜色空间的FrameBuffer,在OpenGL中可以使用glEnable(GL_FRAMEBUFFER_SRGB)开启;要保证片元输出的线性空间的颜色,也就是要采用线性工作流。
    3、需要注意的是,避免将sRGB转换和ToneMaping混合起来,ToneMaping做的是将HDR映射到LDR。这只是一个带偏向性颜色范围映射,也就是算法倾向性的增强部分颜色。而sRGB转换才是将颜色从线性空间转换到sRGB空间。

    Dithering

    首先说明一下,颜色格式分为Float、Normalized Integer、Integer三种,默认缓冲区就是Normalized Integer格式的颜色。根据OpenGL的文档,当将一个Float颜色写入Normalized Integer缓冲区的时候,可以开启Dithering。Normalized Integer缓冲区是一个定点数缓冲来存储浮点值,比如通常我们的颜色是定义在[0,\1]的浮点值,但是颜色缓冲是[0,254]\的Int值,OpenGL会自动进行转换。

    Logic operations

    根据OpenGL的文档,当将颜色写入Integer(Normalized Or Not)缓冲区的时候,可以开启Logic operations。这是一些Bool操作。具体可以参考文档Logical Operation。Logical Operations在sRGB颜色空间是禁止的。

    Write mask

    该阶段可以分别指定Color、Depth、Stencil的写入掩码。具体参考文档Write Mask

    五、RenderPass

    5.1 Renderer

    以上所有内容在游戏引擎只是一个RenderPass,实际情况下,每帧游戏引擎会按照一定的顺序渲染多个Pass。比如,深度Pass(或者深度法线Pass)、阴影Pass、不透明物体Pass、透明物体Pass、后处理Pass等;而且后面的Pass会利用前面的Pass渲染结果来处理,比如深度Pass渲染的深度纹理可以用在后续的Pass实现一些效果。
    总而言之,真实的游戏引擎是每帧渲染多个Pass,每个Pass对应上述的内容。

    5.2 CameraStack

    实际上,在Unity的Urp渲染管线中,更完整的过程是渲染相机堆栈->每个相机堆栈对应一个渲染器->每个渲染器包含多个Pass。不过,Urp里面每个相机堆栈只对应一个FrameBuffer,也就是所有的相机渲染输出都是这一个FrameBuffer,避免内存和带宽浪费。如果在场景内创建多个相机堆栈,那么其它的相机堆栈的输出应该是离屏RT。

    六、参考资料

    1、Graphics pipeline
    2、Rendering Pipeline Overview
    3、Per-Sample Processing
    4、Output Merger (OM) stage
    5、裁剪和空间管理
    6、[总结] 漫谈HDR和色彩管理(三)SDR和HDR

    更多相关内容
  • 搜索引擎-手机室内3D游戏渲染引擎研究.pdf
  • 网络游戏-3D游戏渲染引擎的渲染方法.zip
  • 论文探讨了游戏引擎中的渲染部分,建立了一款基于的游戏渲染引擎模型,并利用该渲染引擎实现了对地形、模型以及特效的渲染。
  • 网络游戏-一种游戏渲染方法和装置.zip
  • 网络游戏-3D游戏渲染引擎的资源管理方法.zip
  • FLASH游戏渲染技术

    2012-02-28 09:57:11
    FLASH游戏渲染技术 as 游戏开发必备 Flash游戏渲染方法分析 Flash渲染效率提高 Flash游戏素材保存与优化
  • 2D游戏渲染工具

    2013-08-07 10:40:21
    一个很不错插件,关于游戏制作2D渲染方面,希望有用,文件直接拖入到max里就能用。
  • Games104-04 游戏引擎中的渲染实践

    千次阅读 2022-04-07 11:26:39
    游戏渲染基础: 硬件体系结构 渲染数据 可见性 材质,阴影和光照: PRB(SG,MR) 着色器变换 光照 点/定向光照 IBL/Simple GI 特殊渲染: 地形 天空/雾 后处理 管道 正向渲染,延迟渲染和Forward+渲染 ...

    渲染概述

    1. 游戏渲染基础:
      • 硬件体系结构
      • 渲染数据
      • 可见性
    2. 材质,阴影和光照:
      • PRB(SG,MR)
      • 着色器变换
      • 光照
      • 点/定向光照
      • IBL/Simple GI
    3. 特殊渲染:
      • 地形
      • 天空/雾
      • 后处理
    4. 管道
      • 正向渲染,延迟渲染和Forward+渲染 (Forward,deferred rendering,forward plus)
      • 混合效应的真实管道 (Real pipeline with mixed effects)
      • 环形缓冲和同步刷新(Ring buffer and V-Sync)
      • 基于图块渲染(Tiled-based rendering)

    在游戏渲染系统中的挑战

    1. 所需要渲染的游戏对象数据量十分庞大,所有东西都放在一个容器中,游戏的渲染系统十分复杂
    2. 深度地适配现代计算机硬件
    3. 保证游戏性能,稳定的帧率和高质量的分辨率
    4. 限制对GPU带宽和内存占用的访问,确保CPU不被渲染系统完全占用。

    渲染系统的对象

    渲染管线和数据(Rendering Pipeline and Data)

    在这里插入图片描述

    计算投影和栅格化

    投影分为正交投影透视投影
    在这里插入图片描述
    栅格化:栅格化是将矢量图形格式表示的图像转换成位图以用于显示器或者打印机输出的过程。
    栅(shan)格化,是一个专业术语,栅格即像素,栅格化即将矢量图形转化为位图(栅格图像)。最基础的栅格化算法将多边形表示的三维场景渲染到二维表面。
    在这里插入图片描述

    计算阴影(Computation - Shading)

    在这里插入图片描述
    代码右图对应的是GPU的结构
    shader样本代码中包含以下结构:

    1. Constants/Parameters
    2. ALU algorithms
    3. Texture Sampling
    4. Branches

    计算纹理采样(Computation - Texture Sampling)

    分为三步:

    1. 第一步:使用最近的mipmap级别
    2. 第二步:两个mip-map映射中执行双线性插值
    3. 第三步:结果之间的线性插值

    了解GPU

    SIMD and SIMT

    SIMD(Single Instruction Multiple Data):描述具有多个处理元素的计算机–同时对多个数据点执行相同操作的计算机。
    在这里插入图片描述

    SIMT(Single Instruction Mutiple Threads):并行计算中使用的一种执行模型,其中单指令、多数据(SIMD)与多线程相结合。
    在这里插入图片描述

    GPU 结构体系

    ![在这里插入图片描述](https://img-blog.csdnimg.cn/96a3e6085f8b4fd68f1ba8f3f725700d.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5aSn5Y-vQ29kZQ==,size_20,color_FFFFFF,t_70,g_se,x_1

    1. GPC(Graphics Processing Cluster):专用硬件块用来计算、栅格化、阴影和纹理处理
    2. SM(Streaming Multiprocessor):运行CUDA内核的GPU的一部分
    3. Texture Units:可以获取和过滤纹理的纹理处理单元
    4. CUDA Core:允许不同处理器同时工作数据的并行处理器
    5. Warp:一组线程

    Data Flow from CPU to GPU

    数据在计算机中流动是有成本的,所以尽可能的实现CPU到GPU单向传输数据,不要从显卡里面读取数据
    在这里插入图片描述

    Be Aware of Cache Efficiency

    • 充分利用硬件并行计算
    • 尽量避免冯·诺依曼的瓶颈

    在GPU中利用缓存的机制可以大大提高其工作效率

    GPU Bounds and Performance

    要注意GPU性能的边界
    程序应用性能的限制:

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

    可渲染物体

    Building Blocks of Renderable

    下图是对一个可渲染的物体拆分:
    在这里插入图片描述

    Mesh在游戏引擎里面的表达

    在这里插入图片描述
    通过顶点和法向量的数据形成形状。
    上面的方法是一种效率比较低的存储方法,下图为高效的方法
    在这里插入图片描述
    把所有的顶点数据存放在一起,只存取顶点数据的索引值

    材质(Materials)

    材质模型:
    在这里插入图片描述

    多种多样的的纹理

    在表达一个材质时,纹理占据了一个十分重要的地位
    在这里插入图片描述

    材质中十分重要的部分——shader

    利用shader代码对材质进行不断的变化来实现多种多样的游戏世界

    坐标系与变换

    模型资产是基于本地坐标系生成的,最终我们需要将它们呈现到屏幕空间中。

    在这里插入图片描述

    将材质放入Object中

    一个物体中可能由不同的材质组成才能表现出真实的效果,所以我们需要引入submesh(子mesh)来对不同的材质进行区分,并把相同的纹理、submesh、mesh归类在一起
    在这里插入图片描述
    利用submesh来放入不同的材质:
    在这里插入图片描述

    Resource Pool

    若一个场景、物体存在多种可复用性的材质,我们一般采用Resource Pool的架构来对相同的资源进行管理,来提高效率
    在这里插入图片描述
    但是在游戏场景中我们的场景是不断变换的,GPU又非常懒,所以我们为了简化GPU的工作,对场景中的Material进行排序,这样可以提高GPU的运行效率
    在这里插入图片描述

    GPU Batch Rendering

    在现代游戏引擎中,我们尽可能的把绘制运算交给GPU去运算,而不是交给CPU去运算,并且我们在运行GPU时,为了使其工作效率更高,我们要减少DrawCall的次数,所以我们会尽可能的在一次DrawCall中绘制大量的数据,此时就运用到了Batch
    在这里插入图片描述

    可见性裁剪

    只将可见视野范围内的Object进行渲染来提高效率
    那怎样去实现呢?
    利用以下方法:

    • 包围盒
    • 各种算法,进行区域划分,常用的由BVH,PSV

    纹理压缩

    1. 传统的图像压缩像JPG和PNG
      • 良好的压缩率
      • 图片质量
      • 设计用于压缩或解压整个图形
    2. 游戏纹理压缩
      • 译码速度
      • 随机存取
      • 压缩速率和视觉质量
      • 编码速度

    Block Compressin

    在这里插入图片描述

    • PC端的BC7的算法可以当你生成了一个纹理,可以实时地去生成压缩的纹理
    • ASTC主要用于手机端

    建模工具

    • Maya
    • Max
    • Blender

    新的渲染管线

    基于聚类的网格管道(Cluster-Based Mesh Pipeline)

    在这里插入图片描述

    可编程网格管道(Programmable Mesh Pipeline)

    在这里插入图片描述

    展开全文
  • 引擎可以大致分为两类 一类是所有的代码都在引擎中编写 包括和硬件打交道的部分 这种引擎编写过程十分复杂 代码的 优化要求很高 尤其是需要为不同的硬件编写不同的驱动代码 这类引擎基本出现在通用图形 API 出现以前...
  • 所以要想了解Shader在这个流水线大工厂里到底干了些什么,我们最好先了解这间渲染工厂到底做了些什么工作,大体的环节以及每个环节的概念,这有助于我们了解这位员工它的主要工作内容。 渲染的大致概述与流程 ...

    #1

    以下为个人学习Shader的学习笔记整理,注重于理解与大体原理了解,不会过于深入也肯定会有说的不对的地方还望在包涵的时候帮我指出一下错误之处!感激不尽!

    什么是Shader?

    Shader 翻译过来就是着色器 其主要扮演的角色是渲染画面流水线时的一员。所以要想了解Shader在这个流水线大工厂里到底干了些什么,我们最好先了解这间渲染工厂到底做了些什么工作,大体的环节以及每个环节的概念,这有助于我们了解这位员工它的主要工作内容。

    渲染的大致概述与流程

    面包房”(渲染的大体流水线环节)

    以下是个人对其大概的概念理解,为了更好的去理解,我愿意将其称为面包房,“面包房”的工作由CPU与GPU一起合作

    渲染流水线分为主要三个阶段:

    1.应用阶段

    2.几何阶段

    3.光栅化阶段

    专有名词并不能帮助我们去理解这几个概念,但是如果用面包房进行比喻会好很多。

    和面团

    应用阶段,这个阶段主要由CPU进行负责,其主要需要做的工作其实是开发者进行主导,也就是放置物体,指定摄像机位置,物体的材质球附加,场景中使用的光源等等,在游戏开发的过程中,就是布置关卡环境的环节,其主要过程如上。

    由于不在渲染原理范畴内,不过多描述。但它在渲染流程中充当了面包房里的和面阶段,有了面团才能做面包嘛,它最重要的作用是输出渲染信息,也就是渲染图元即面团。设置放好的物体模型与光影设置信息就在这个环节被定了下来,接下来这些环节就会被送往下个阶段。

    配用模具,做出面包形状

    几何阶段在这个阶段就是处理面团的时候了,集合阶段时,会将渲染图元进行处理,怎样绘制图元,在三维空间里的哪里绘制图元,将其顶点坐标变换到屏幕空间中然后输出其二维顶点坐标并传递给下一个阶段。

    屏幕的显示其实只是一个二维的平面,而我们看到的游戏画面其实都是一帧帧绘制出来的,所以这个环节就是将UN中三维的空间信息进行处理成为二维坐标后进行传递,很像做面包或者蛋糕的时候使用模具一样定型,其内部更细致的原理与环节将会之后细述。这一阶段通常在GPU上进行。

    烤面包

    光栅化阶段由几何阶段传输过来的参数会由GPU进行处理来产生屏幕上的像素,借由这些像素渲染出最终的图像,这个阶段就是烤面包了,为数据的定型进行最终处理,最后输出画面,这一阶段也会在GPU上执行。

    以上就是整个渲染流程的大致概念。

    CPU与GPU之间的通信

    前文提到过,CPU与GPU一起工作,工作之间就有交流,所以它们之间也是有通信的,通信之间,由CPU指导GPU工作,在前面应用阶段准备好了参数与渲染状态之后CPU就要调用一个指令来告诉GPU,嘿!显卡!我的数据都准备好了!你按着我的设置准备开始渲染这一帧画面吧!”这个渲染命令就是Draw Call。通俗点来讲,和面师傅叫面包师做一个菠萝包,材料和做什么和面师傅已经准备和告诉面包师了,接下来就是面包师的工作了。

                                                                                                                                                                                               

    额外话题:CPU与GPU之间的通信不止Draw call 这条命令,Draw call应当尽可能的少调用,过多的Draw call 会降低帧率,CPU与GPU之间的工作就好像和面师傅想做100个菠萝包,它对面包师说请帮我制作1个菠萝包。”然后递过去一个和好的面团子,如此重复100次。我们也知道GPU的运算能力十分强大,很多情况下CPU在准备下条命令的时候GPU早就没事干了,而CPU还在准备渲染的数据命令等,这不仅浪费了显卡的计算能力,也花费了过多的时间在Draw call上。

    如何减少?方法有很多,这里仅提出批处理的方法。

    如果是做菠萝包的话很简单,让和面师傅搓够100个菠萝包的面团子然后告诉面包师:“请制作100个菠萝包,”就好了。

    一样的道理,把小的Draw call 合并成一个大的Draw call 就可以了,但请注意,批处理更加适合处理静态物体,比如大楼与地面,因为我们需要在CPU中合并网格,静态物体只用合并一次就好了,动态物体每次运动都需要重新合并网格会产生一定影响。

                                                                                                                                                                                                   

    以下部分为较为细致的描述几何阶段与光栅化阶段的工作流程

    面包师(GPU)的工作

    前面提到过,几何阶段光栅化阶段都在GPU上工作,接下来描述的就是这两个阶段其中的一些更细致的一些过程。

    接下来是GPU进行这段工作时的流水线

    顶点数据 >>>> 顶点着色器 >>>>> 曲面细分着色器 >>>> 几何着色器 >>>> 剪裁 >>>> 屏幕映射 >>>> 三角形设置 >>>>  三角形遍历 >>>> 片元着色器 >>>> 逐片元操作  >>>>> 屏幕图像

    绿色部分是几何阶段,蓝色部分则是光栅化阶段

    (有一些名词在游戏设置中画质的选项上面看着有点眼熟)

    接下来大致描述其中每个部分的功能,其中需要重点描述的是顶点着色器、剪裁、屏幕映射、三角形设置、三角形遍历、片元着色器、逐片元操作。

    顶点着色器

    顶点着色器,它的处理单位是顶点,每一个输入进来的顶点都会调用一次顶点着色器,他主要的功能有两个:坐标变换,逐顶点光照.

    坐标变换就是对顶点的坐标进行某种变换,它在顶点动画中非常有用,布料或者水面的上下波动都需要顶点着色器,它的实现主要是依靠将顶点坐标从模型空间转换到齐次剪裁空间在硬件的透视除法后得到归化一的设备坐标。从我个人的角度来理解就是将传过来的模型顶点坐标数据变换成硬件可以理解的坐标系,进而向下继续传递参数。

    剪裁

    摄像机不总是盯着一个画面进行输出,当然也会有在视野外的东西,这个时候及时的舍弃这一部分叫做剪裁,在这个环节,完全在视野外的图元将不会向下个环节传递参数,被剪裁的部分会产生新的顶点。

    屏幕映射

    从其次剪裁空间传输过来的坐标依然还是三维坐标系屏幕映射就是要把三维坐标换成屏幕坐标系与画面分辨率有关,如下图。

    其本质是一个缩放的过程。

     注意!不同的接口会产生不一样的坐标系统!

    如果的到的图像是倒转的那么可能就是这个原因造成的(坐标系统的差异)

    OpenGL与DirectX是不同的图像应用编程接口,简单来讲,其实和面师傅和面包师之间的交流不是简单的说话,显卡知道如何去渲染的时候也需要特定的函数,OpenGL与DirectX则是基本的函数指令。这两家曾因为技术不同而产生竞争,幸而有显卡驱动这个”中介人“的出现,现在基本上所有的GPU都可以与这两种编程接口工作。

    三角形设置

    这一步开始进入了光栅化阶段,屏幕映射阶段已经输出了屏幕坐标系下的顶点位置以及其他信息,输出的顶点信息其实是都是三角网格的顶点,这个阶段将会借助顶点信息生成三角形网格,为下一个阶段做准备。

     三角形遍历

    这个阶段则如图所示,主要是输出片元。

    片元着色器

    在这个阶段,三角形遍历所产生的数据也就是三角形网格如何覆盖每一个偏远的数值会在这里产生这一系列数据的信息,相当于打包好一块面包的制作方法和材料,接下来的阶段才是真正对像素产生影响的阶段。

    这一阶段可以完成许多重要的渲染技术比如纹理采样,在此不过多赘述。

    大的要来啦

    逐片元操作

    接下来这就是渲染流水线最后一步逐片元操作。

    这一步主要有两大流程:

    1.深度测试模板测试每个片元的可见性。

    2.将所有通过测试的片元进行合并或者是混合。

    前面所有的阶段都是为了生成一个片元准备的,像是制作面包不仅仅是和面,还有加入其他的配料定型等等,但是一块面包也是要做的好才能拿的出手的,所以要对每个片元进行测试,一个片元只有通过了所有的考试才能获得与GPU谈判的资格即与颜色缓冲区合并,任何一项测试没有通过都意味着这个片元将会被舍弃。

    接下来是两种测试的基本原理概述

    模板测试

    模板测试,GPU在拿到一个片元之后会与比较函数进行一个比对,这个比较函数可以由开发者指定,如果这个片元没有通过这个测试,那么它会被舍弃。不管这个片元有没有通过测试,我们都可以修改模板缓冲区,这样,我们就可以借助这一项测试来控制渲染的区域或者方法,比如渲染阴影或者轮廓。

    深度测试

    深度测试,顾名思义,它是来测试深度的,这个深度与字面上的意义稍有出入,指的是离摄像机的远近深度,我们总是希望靠近摄像机的显示出来而远处或被遮挡的忽略,这个测试就满足了我们的需求。它不仅可以比较片元是否被遮挡,一个透明的物体的透明效果也与深度测试有关。

    合并

    当一个片元成功的通过了这两项测试之后,他就可以来到合并步骤了,合并可以选择下一帧的这个片元上的颜色是覆盖掉上一帧的呢还是因为开启了混合模式而与上一个片元叠加?这其中也涉及了半透明物体的处理,不过多细述。

    到此为止,一个像素终于被成功的渲染出来了!当然GPU和CPU还要重复千百上亿次这样的工作。

    这就是大致的渲染过程原理啦!

    展开全文
  • 一些游戏用到的渲染技术

    万次阅读 2018-05-18 21:19:57
    泡泡网显卡频道2月19日 近年来3D图形技术的发展势头非常迅猛,软件方面游戏的画面和逼真度有了长足进步,硬件方面显卡的更新换代越来越频繁。但始终存在这样一个现象,无论显卡的性能翻多少倍,游戏玩家们总感觉还是...

    泡泡网显卡频道2月19日 近年来3D图形技术的发展势头非常迅猛,软件方面游戏的画面和逼真度有了长足进步,硬件方面显卡的更新换代越来越频繁。但始终存在这样一个现象,无论显卡的性能翻多少倍,游戏玩家们总感觉还是不够强大,GPU庞大的运算能力到底被谁吃掉了呢?

    答案很简单,游戏为了提高画面质量、更加接近于真实世界,使用了诸多先进的图形技术,特效的“滥用”大幅提升了游戏画面水平,但也抵消掉了GPU性能的增长。
    这里写图片描述

    那么最新的图形技术到底能给游戏带来多少的画面改进,对于显卡的需求会有多夸张呢?今天笔者就将主流游戏中使用最广泛的技术提取出来,对其原理和需求进行详细的分析,以飨读者。

    其实很多最先进的游戏高级图形技术都包括在了新版本的DirectX API当中,或者说是通过DirectX中的Shader Model新指令集来实现。但这些东西并不容易理解,也不够直观,所以本文反其道而行之,通过肉眼可以看得出来的差别来分析DirectX版本更新对于图形技术的改进到底有多大?

    运动模糊(Motion Blur)

    这里写图片描述

    ● 游戏中为什么需要模糊处理?清晰一点不是更好吗?

    首先请大家思考一个问题:为什么每秒24帧的速度对于电影来说已经足以获得很流畅的视觉效果,而对于游戏来说却会显得磕磕碰碰呢?

    原因很简单,摄像机在工作的时候并非一帧一帧绝对静止的拍摄,它所摄下的每一帧图像已经包含了1/24秒以内的所有视觉信息,包括物体在这1/24秒内的位移。如果在看电影的时候按下暂停键,我们所得到的并不是一幅清晰的静止画面,而是一张模糊的图像,问题就出在这里!

    传统的电脑3D图像做不到这一点,游戏里的每一帧就是一幅静止画面,如果你在运动的过程中截一张图片下来,得到的肯定是一幅清晰的静态图。

    这里写图片描述
    很多游戏中都有运动模糊的选项

    所以,运动模糊技术的目的有二:一是增强快速移动场景的真实感,二是在FPS并不高的时候让游戏显得不是很卡。运动模糊技术并不是在两帧之间插入更多的位移信息,而是将当前帧同前一帧混合在一起所获得的一种效果。

    ● 基于DX10技术的运动模糊更真实

    之前已经有很多DX9游戏采用了运动模糊技术,效果最显著、最夸张的非《极品飞车》系列莫属,很多玩家表示不太适应这种效果,原因就在于打开特效之后画面模糊的太夸张了,时间一长容易头晕——显然,这不是我们想要的运动模糊!

    这里写图片描述

    传统的运动模糊技术,游戏只是简单虚化了环境,而对高速运动的物体则仅仅保留运行轨迹而已,这样的前景和背景融合在一起自然效果很差,完全就是拖影和残影,影响视觉体验。

    这里写图片描述

    这里写图片描述

    而在DX10模式下,有了全新的几何着色技术,这样就可以使用流处理器资源来计算运动物体的几何坐标变换,然后配合高精度的顶点纹理拾取技术,达到了完美监控整个运动过程的目的。如此一来进行模糊处理的话,就杜绝了不分青红皂白的现象——该模糊的依然模糊,该清晰的照样清晰!

    ● 代表游戏:《失落星球》、《孤岛危机》、《战争机器》、《生化危机5》

    景深(Depth of Field)

    这里写图片描述

    ● 为什么要加入景深——模拟镜头和人眼的视觉效果

    使用单反数码相机拍照的朋友应该知道,大光圈镜头所带来的背景虚化效果非常好,能够凸出人物和景物,主次分明。其实人眼在注意观察物体时,也会将焦距拉近,主体清晰可见但远景一片模糊,这就是通常所说的景深效果。
    这里写图片描述

    大多数游戏都有景深选项

    3D游戏为了模拟真实,更接近镜头/人眼的成像原理,也将景深引入渲染过程之中。由于3D游戏只是将图像投影在了平面的显示器上,不会有深度,因此想要实现景深效果必须在图像输出之前就进行预处理,把游戏主角以外的远景全部虚化。

    ● DX10带来更好的景深处理

    DX9时代,是通过投机取巧的方式来实现景深效果的,它自动判定距离,将远处景物的纹理、阴影、光照等特效全面缩水,然后再辅以模糊处理,而只对近景做正常渲染输出,这样就会让玩家注意到主角而忽视远景。

    这里写图片描述

    而DX10则没有任何的偷工减料,它通过几何着色器,将深度帖图中的纹理信息按照距离拆分到缓冲,然后分为几个不同的视角进行渲染,最后合成完整的图像。因此最终实现的景深效果在特效方面不会有任何缩水,远景完全符合正常的虚化模式,如果仔细观察的话,光影等细节依然得到保留。

    ● DX11带来更快的景深处理

    DX10的景深处理能够实现近乎完美的景深效果,但通过不同视觉渲染的方法还是不够灵活,而且会大大增加GPU后端处理(光栅单元)的负担,产生负载不均的情况,导致性能损失较大。
    这里写图片描述

    而DX11则通过DirectCompute中新增的Gather4数据采集指令,使得计算着色器能够以四倍的纹理采集速度,帮助减少GPU纹理单元和光栅单元的负担,从而在进行景深处理时消除了瓶颈,提升渲染效率。

    ● 代表游戏:《古墓丽影》、《失落星球》、《孤岛危机》、《潜行者》、《战争机器》

    环境光遮蔽(Ambient Occlusion)

    这里写图片描述

    ● 光栅化渲染的极限——环境光遮蔽

    在GPU和CPU有能力进行实时光线追踪(Ray Tracing,按照真实世界光线投射原理反向渲染的技术)之前,环境光遮蔽是当今光栅化渲染模式中最好、最高效的替代方案。环境光遮蔽通过计算光线在物体上的折射、衍射、散射和吸收,在受影响位置上渲染出适当的阴影,进一步丰富标准光照渲染器的效果。
    这里写图片描述

    一些游戏支持多种环境光遮蔽模式

    屏幕空间环境光遮蔽(Screen Space Ambient Occlusion,SSAO)是AO的一个变种,它通过对屏幕内进行简单的空间划分,然后进行计算。SSAO的工作原理是:通过采样象素周围的信息,进行简单的深度值对比来计算物体身上环境光照无法到达的范围,从而可以近似地表现出物体身上在环境光照下产生的轮廓阴影。虽然只是模拟实现,但确实能增强场景的层次感,让画面更细腻,让场景细节更加明显。

    ● DX10.1大大提升SSAO效率

    SSAO可以利用“逐象素场景深度计算”技术计算得出的深度值直接参与运算,也可以利用DX10.1当中的Gather4函数实现更快速纹理采样及过滤。DX10模式下开启SSAO性能损失非常大,因此SSAO技术多出现在DX10.1游戏中。通过实际测试来看,DX10.1显卡在DX10.1模式下(如果该游戏支持的话)的性能相比DX10会提升20%-30%之多,从而使得SSAO成为真正实用的技术,而不再是花瓶。
    这里写图片描述

    ● DX11带来更高清晰度的HDAO

    在DX11中,SSAO被进一步升级至HDAO(高清晰),因为DX11中的Gather4函数更加强大,它可针对特定的颜色分别采样,能自动识别能做阴影映射的值,从而实现更快更好的阴影过滤。HDAO和SSAO都能向下兼容旧硬件,但运行速度会打折扣。换句话说,DX11和DX10.1是在改进算法、优化性能的基础上,使得显卡有能力渲染出更复杂、更完美的特效,而DX10虽然在也能达到同样的画面效果,但速度会很慢,实用性不大。
    这里写图片描述

    ● 代表游戏:《孤岛危机》、《潜行者》、《火爆狂飙》、《鹰击长空》、《帝国:全面战争》、《尘埃2》

    镶嵌细分曲面(Tessellation)

    这里写图片描述

    ● 媲美电影CG画质——镶嵌式细分曲面技术

    游戏和电影CG动画,其实都是由计算机渲染出来的,那为什么画质差别那么大呢?这是因为CG动画的模型要比3D游戏复杂成千上万倍,所以CG也要成千上万倍与电脑的性能才能渲染出来,而且还无法实现实时渲染。

    3D游戏考虑到家用电脑的机能,模型不可能设计得太复杂,否则就不具备可玩性。但为了让游戏变得更加逼真、达到更高画质,太简单的模型的确拿不出手,那么有什么方法既能大幅提升模型复杂度、又不至于给显卡造成太大负担呢?Tessellation技术就是为此而生的。

    这里写图片描述

    简单来说,Tessellation是一种能够在图形芯片内部自动创造顶点,使模型细化,从而获得更好画面效果的技术。Tessellation能自动创造出数百倍与原始模型的顶点,这些不是虚拟的顶点,而是实实在在的顶点,效果是等同于建模的时候直接设计出来的。
    这里写图片描述

    实现相同的模型细节,Tessellation显然比直接建模更快更高效

    除了大幅提升模型细节和画质外,Tessellation最吸引程序员的地方就是:他们无需手动设计上百万个三角形的复杂模型,只需简单勾绘一个轮廓,剩下的就可以交给Tessellation技术自动镶嵌,大大提高开发效率;而且简单的模型在GPU处理时也能大幅节约显存开销,同时大幅提升渲染速度!

    ● Tessellation的妙用

    Tessellation技术的原理很简单,就是把简单的模型智能的镶嵌成为复杂模型,使得游戏中的景物变得更加细腻真实。实际上除此之外Tessellation还能实现一些令人意想不到的功效:

    这里写图片描述

    DX11代表作《DiRT2》就大量使用了Tessellation技术,它用Tessellation构建了动态水面、动态布料旗帜和观众人物模型,其中加强人物模型不难理解,而动态水面和布料效果足以媲美物理加速,让人惊讶不已!

    Tessellation(细分曲面)水面效果对比
    

    这里写图片描述

    DX11模式

    这里写图片描述
    DX9模式

    Tessellation(细分曲面)布料效果对比
    

    这里写图片描述
    DX11

    这里写图片描述
    DX9

    虽然XBOX360和ATI的全线DX10显卡都支持Tessellation技术,但支持Tessellation游戏并不多,随着DX11将Tessellation作为一项重要技术纳入API规范之后,未来DX11游戏都将会支持这一技术,但由于DX11中的Tessellation和DX10/DX9版本有很大的区别,因此并不会向下兼容,Tessellation只能通过DX11显卡在DX11游戏中才能实现。

    ● 代表游戏:《潜行者:普里皮亚季的呼唤》、《科林麦克雷:尘埃2》、《异形大战铁血战士》(即将发布)

    物理效果(PhysX)

    这里写图片描述

    ● 动态逼真——物理效果的实现

    3D游戏中“物理”指的是什么呢?简言之就是模拟真实世界中的物理定律,使得运动物体产生一些复杂的交互性干涉,从而改变形状、轨迹或状态的一种技术。比如:流体(水、烟、雾)、碰撞、变形、爆炸、毁坏、布料、碎片……物理技术虽然属于图形技术的一种,但所涉及到的运算并非是图形渲染,而是大量的并行计算,等结果算出来之后才会进行后续的渲染操作。

    这里写图片描述
    3D游戏中一些典型的物理应用

    这里为什么要强调GPU物理加速呢,因为CPU物理加速其实早就进入实际应用阶段,但由于CPU性能有限(或者说CPU并不擅长做物理运算),大多数游戏仅采用了少许简单的物理效果作为点缀,未能给玩家带来视觉上的震撼力,也就容易被大家所忽视。比如《半条命2》系列游戏都使用了物理技术,在击穿木板或爆炸时会有一定的破坏效果,但如果不特别指出的话您可能注意不到。
    这里写图片描述
    Crysis爆炸时的物理效果不错(CPU加速),但在场景毁坏与交互方面略有不足

    ● 物理引擎并不是只有PhysX一种,但只有PhysX支持GPU加速

    除了CPU外,还有专用的PPU(即物理加速卡)来进行物理运算,但随着GPU进入DX10时代,并行架构的流处理器拥有比PPU和CPU更强大的浮点运算能力,GPU物理加速技术被提上日程。终于,在NVIDIA收购Ageia公司之后,通过CUDA技术将PhysX物理引擎重新编译了一遍,使得GeForce 8以上的N卡都能够支持物理运算,通过大量的测试来看,即便是低端N卡的物理加速能力也要比专用的物理加速卡强,CPU跟它根本不是一个级别。

    就拿最近比较热门的《蝙蝠侠:阿卡姆疯人院》这款游戏来说,是否开启PhysX有着天壤之别,PhysX能够让蝙蝠侠的披风更拉风、地洞中的雾气在人经过时产生互动、地面上的碎片和纸屑在打斗过程中飞舞、地板砖桌椅墙壁都有可能被打碎、布料和旗帜随风而动……

    这里写图片描述

    物理引擎也不是只有PhysX一种,已经被Intel收购的Havok也提供了很不错的物理解决方案,但目前支持GPU加速的还只有PhysX这一种,由于GPU拥有很强的运算能力,因此PhysX引擎所实现的物理效果最为出色,但对显卡的要求也很高。

    开启PhysX之后是十分消耗资源的,GTS250以下级别的显卡性能损失特别大,最好是能安装一块额外的显卡做专门的物理加速运算,而GTX260+以上级别的显卡则可以同时处理图形渲染和物理加速运算,能够保证不低于30帧的速度。至于A卡则不支持PhysX加速,强行开启的话只能使用CPU进行运算,效率自然非常低下,不过使用A卡做渲染N卡做物理加速也是个临时解决方案。

    ● 代表游戏:《虚幻竞技场3》、《镜之边缘》、《雪域危机》、《蝙蝠侠:阿卡姆疯人院》

    高动态范围光照(HDR)

    这里写图片描述

    ● 大名鼎鼎的HDR技术再次缩水

    HDR(High Dynamic Range,高动态范围光照)技术相信很多人并不陌生,想当年DX9C SM3.0面世时,正是凭借HDR技术一举成名,HDR所带来的绚丽光影效果给玩家极强的视觉震撼,但却产生了很多负面效果,这些历史遗留问题时至今日都没有得到完美解决。

    几乎所有的图形技术都是随着时间的推移来进一步增强效果,只有HDR被一而再再而三的“缩水”,这是为什么呢?

    ● DX9C时代HDR与AA水火不容

    HDR技术通过采用浮点格式的颜色代码来为纹理、光照等计算提供极大的精度和颜色范围(以前的纹理一般都是采用整数型的颜色格式)。尽管最后显示到屏幕上还是每个颜色通道8位的整数格式,但是以前的材质、光照计算中纹理也是用每通道8位的格式来参与计算,所以在显示到画面之前,很多细节就在低精度的运算中丢失了。

    HDR效果虽然很美,但在DX9C模式下进行16位浮点(FP16)运算时,会占用到原本属于多重采样抗锯齿(MSAA)的缓冲区域,使得游戏开启HDR后无法进行FSAA处理。当年的一大批DX9C游戏都是如此,比如《孤岛惊魂》、《细胞分裂》、《虚幻3》引擎的全系列游戏。

    ● ATI X1000和XBOX360是个例外

    ATI的DX9C显卡发布较晚,因此在设计之初就考虑到了HDR+AA的需要,整合了额外的缓存,只要通过游戏或者驱动重新指定另外的缓冲区,就能完美支持HDR+AA效果,所以X1000系列和XBOX360主机都能支持HDR+AA。

    这里写图片描述

    不过ATI的HDR+AA方案并不是业界标准,还是有不少游戏无法同时开启HDR和AA,通过驱动强行更改缓冲区的方式和一些游戏有兼容性问题,ATI官方都不认可这种做法。

    ● DX10时代,新增两种HDR颜色格式

    为了解决困扰业界已久的HDR+AA问题,微软在DX10当中加入了两种新的HDR格式,对每个颜色通道16位浮点数的格式进行删减,第一种是R11G11B10(红色绿色各11位,蓝色10位,总计32位),另一种是红绿蓝各9位共享5位指数(计算机中浮点数是尾数附加指数的形式来表示)。

    新增的两种HDR格式都只有32位,而并非DX9C时代的48位(FP16x3),所以动态范围精度有些下降,但好处就是新的HDR不会与MSAA抢占缓冲区,所消耗的显存也大大减少,效率和兼容性提高,至于光影效果的缩水其实很难看出来。

    ● DX11时代,新增HDR纹理压缩技术

    HDR除了不支持抗锯齿外,还不支持纹理压缩技术,因为HDR在设计之初的要求就是光照和纹理都必须保持高精度。随着时代的发展,游戏的分辨率越来越高,纹理贴图越来越精细,而纹理贴图如果不经压缩就放在显存里面的话,容量是相当恐怖的,因此新一代的游戏显存消耗成倍增加,这其中罪魁祸首其实还是HDR技术。

    为了解决这个显存消耗大户,在DX11当中又新增了一种专为HDR设计的纹理压缩格式:BC6H,压缩比高达6:1。

    这里写图片描述

    上图展示的是图像通过BC6H压缩模式进行压缩的前后效果对比图。其中左边的图像为原始图像,中间的是在压缩过程中损失的一些细节,而右边的就是压缩后的图像。可以看出,从画质上来看几乎没有损失(肉眼看不出),但是却可以大幅度降低显存的占用。

    经过了DX9C、DX10和DX11三代API,HDR技术在神不知鬼不觉的情况下被两次“缩水”之后,才真正走向成熟,由此可见好的图形技术不光是要效果出色,更重要的是拥有高效率和实用性,才能被更多的游戏所接受,被更多的显卡所支持。

    ● 代表游戏:几乎所有主流游戏都有使用HDR效果,时至今日依然有一些采用虚幻3引擎的游戏无法同时开启HDR和AA,需要通过修改的方式实现

    视差映射贴图(Parallax Mapping)

    这里写图片描述

    ● 传统纹理贴图的弊端

    纹理贴图大家都明白,就是往建好的3D模型上“贴”一些二维的画面,让人物显得更真实一些,比如常见的砖墙、凹凸不平的地面等,这些如果全部用三角形来实现的话,那么模型就会非常复杂,GPU将会不堪重负,但如果用“一张已经画好砖纹的纸”贴上去的话,那么渲染起来就会轻松好多。

    但是这么做也有很大的缺点,贴图毕竟是2D的,如果在游戏中换个角度看的话,很容易就会发现墙面没有任何立体感,砖纹看上去非常假!为了让2D贴图看上去也有3D立体效果,就诞生了多种贴图技术,比如凹凸贴图、法线贴图、位移贴图、视察映射贴图等。

    ● 凹凸贴图

    凹凸贴图技术简单说起来是一种在3D场景中模拟粗糙表面的技术,将带有深度变化的凹凸材质贴图赋予3D物体,经过光线渲染处理后,这个物体的表面就会呈现出凹凸不平的感觉,而无需改变物体的几何结构或增加额外的点面。例如,把一张碎石的贴图赋予一个平面,经过处理后这个平面就会变成一片铺满碎石、高低不平的荒原。当然,使用凹凸贴图产生的凹凸效果其光影的方向角度是不会改变的,而且不可能产生物理上的起伏效果。

    这里写图片描述
    凹凸贴图的墙壁效果,注意看边缘其实没有任何凹槽

    凹凸贴图在今天看来已经是老的不能再老的一种技术了,虽然能够获得凹凸的效果,但是凹凸的程度非常受限制,基本上只能做出一些简单的浮雕效果来。这种技术通常用在一些观察视角变化很小的情况上,例如地面,墙壁,远处的一些模型等等,如果角度稍微一大,你就会发现那些凹坑其实是根本不存在的。

    ● 法线贴图

    法线贴图就是把一个表面的凹凸情况用每个点的法线向量记录下来,在贴图的时候根据法线贴图做光影的变换,从而实现凹凸效果。

    法线贴图比起凹凸贴图而言,能够实现的效果更好了,相对的就是运算量更大了,需要大量的纹理材质,每个象素的光照情况都需要计算这个点的法线向量和光照情况的夹角计算该点的亮度和颜色。为了节约GPU资源,ATI曾开发了3DC+纹理压缩技术,这对于法线贴图有莫大的帮助。

    当然,法线贴图技术同样不是完美的,它也有着自己的不足,凹凸贴图没有能够解决的切向效果问题肯定是仍然不能够得到解决。此外,就是法线贴图技术不能够解决解决更大的凹凸情况的效果。大家如果去观察的话,法线贴图效果能实现的通常是一些内凹或者外凸不是很严重的表面效果。

    ● 视差映射贴图

    为了解决法线贴图在处理较深内凹之时不能够达到的弊端,诞生了新的视差映射贴图技术。该技术其实称之为视差遮蔽贴图似乎更容易理解一些,因为它会对纹理的坐标做变换,一些凸出的纹理会遮蔽到其他的纹理,这样就会看起来具备更好的凹凸的感觉了。

    这里写图片描述
    ATI X1000 Demo中就包含了视察映射技术

    正如我们在上图看到的情况一样,地面上的石块的凹凸感觉非常好,前面的石块已经对后面的石块进行了局部的遮蔽。虽然这个Demo中的砖块依然很假,但砖块之间凹凸的效果已经得到了完美体现,非常遗憾的是,没有任何一款DX9游戏使用过这种视差贴图技术。

    ● 直到DX10时代才大量使用视差映射贴图技术

    视差贴图技术的实现原理,其实和法线贴图是一样的,都是根据法线贴图进行的处理,所以我们可以把它当作是法线贴图的一种衍生技术。视差贴图技术的实现是和硬件没有必然联系的,这个技术概念的诞生其实也非常早,只是未能得到大量使用,这是因为视差贴图技术的运算量要比法线贴图大了不少,原来的显示芯片因为性能有限基本都运行不了。

    这里写图片描述
    狂野西部DX10版本首次使用了视差映射贴图

    这里写图片描述
    《孤岛危机》中的石块和地面都使用了视察映射贴图

    最早使用视差映射贴图技术的游戏叫做《狂野西部》,首批DX10游戏之一,DX9版本不支持。由于DX10显卡都采用了统一渲染架构,可以方便的集中利用Shader资源,来渲染出复杂的特效。再加上有全新的几何着色器辅助,因此特效的运用方面可以更加灵活,游戏开发商可以很容易的自定义一些特效渲染方式,所以将先进的技术都安置在DX10模式之中也是无可厚非。

    ● 代表游戏:《狂野西部》、《孤岛危机》、《潜行者》

    总结:游戏高级特效不胜枚举

    游戏中所使用的图形技术动辄数以百计,即便是像3DMark这样简短的测试程序中,也包含了数十项先进的、甚至是独创的渲染技术,有些技术甚至连一个像样的名字都没有,而真正能得到广泛使用、被3D游戏爱好这所熟知的技术,确实是屈指可数。

    这里写图片描述
    Crysis的画面之所以如此完美,是因为几乎所有的高级图形技术它都有所使用

    所以,本文只是有选择性的介绍了一些知名的、肉眼看得出差别、能明显提升游戏画质的图形技术,其实在这些风光无限技术的背后,还有很多默默无闻的、用以提升渲染效率的辅助技术。

    这里写图片描述
    Tessellation技术的坎坷发展历程

    而且,这些图形技术也不是一朝一夕就能得到程序员的青睐、并获得游戏玩家的认可,比如HDR技术时至今日依然存在兼容性问题、动态模糊和景深经过三代API的改良效果才令人满意、Tessellation技术更是经过六代七年的发展才修成正果!

    每一代图形API的革新,一方面是加入新的特效、让画面变得更完美,另一方面是通过新的指令提升运算效率。显卡进入DX10时代后,画面已经达到了巅峰,很难再有较大的突破,因此后续的DX10.1和DX11都主要是为了优化算法,使得游戏运行更加流畅,也有利于游戏开发者使用更多、更强的图形技术,营造出更逼真的3D画面!

    展开全文
  • 游戏图形批量渲染及优化:Unity静态合批技术
  • 点击上方“LiveVideoStack”关注我们随着游戏及软件云端化运行能力的支持,大型游戏和软件可以在浏览器、轻客户端以及小程序中运行,在扩展了使用场景边界的同时,也为游戏和软件探索云原...
  • Unity渲染性能优化总纲

    千次阅读 2022-01-16 11:01:56
    本篇是Unity渲染性能优化官方文档中的渲染性能优化总纲,主要是让我们知道从哪些方面着手优化,都有哪些优化手段。 在优化之前要先定位出问题所在 在我们进行优化之前,要先分析出我们的应用的性能问题出在哪里。...
  • 01-什么是渲染引擎

    千次阅读 2021-01-12 08:45:00
    前情回顾:2021 技术新番 - 从零打造渲染引擎系列在开始写代码之前,要先明确渲染引擎到底是什么东西,才能知道要写什么东西。在 Google 里面搜索 ???? 渲染引擎关键字,出来的...
  • unity 渲染顺序 简单设置方法

    千次阅读 2022-03-10 19:18:30
  • 游戏开发入门(三)图形渲染

    万次阅读 多人点赞 2018-01-17 22:15:34
    视频链接:游戏开发入门(三)图形渲染(3节课 时常:约2小时20分钟) 视频链接:一堂课学会shader——渲染拓展课程(3节课 时常:约1小时20分钟) 笔记与总结(请先学习视频内容): 游戏开发入门(三)图形...
  • 介绍移动设备,介绍一款游戏引擎具备的要素,并依次进行开发实现,采用标准C++语言进行开发,需要有扎实的C++基础
  • 网络游戏-一种基于3D网页游戏渲染引擎、实现方法及制作工具.zip
  • 降低D3D渲染延迟的方法

    千次阅读 2021-02-09 15:45:13
    作者:pig-10 ...来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 下面是我当年快被输入延迟问题整疯了的时候整理出的资料: ...要理解加粗的部分就要理解渲染的.
  • 本次课程主要是针对3D游戏引擎内部的GPU之Shader渲染处理,告诉大家引擎底层是如何与Shader代码结合的。从基本的灯光渲染,环境渲染到后的Bloom渲染
  • 游戏渲染的四个挑战: 需要渲染大量的物体,考虑各种各样的效果 要运行在现代的复杂的CPU和GPU架构上,深度适配 帧率要无懈可击,永远保持住,即使在各种渲染环境和分辨率下 CPU的带宽和内存受限,游戏逻辑、网络、...
  • 网络游戏-一种游戏图像渲染方法及系统.zip
  • 网络游戏-游戏画面的渲染方法和装置.zip
  • 网络游戏-应用于游戏的图像渲染方法.zip
  • LE4--渲染系统1:渲染基础:Games104笔记---LE4--渲染系统1:渲染基础_This is MX的博客-CSDN博客_渲染系统 LE3--基础架构2:数据组织与管理:Games104笔记---LE3--基础架构2:数据组织与管理_This is MX的博客-...
  • 网络游戏-2D游戏渲染方法及移动终端.zip
  • NeRF:用深度学习完成3D渲染任务的蹿红

    千次阅读 多人点赞 2021-07-18 19:14:06
    NeRF:用神经网络完成3D渲染任务的蹿红1 引言2 前NeRF时代2.1 传统图形学的渲染2.2 神经网络侵略3D渲染任务:NeRF呼之欲出隐式场景表示(implicit scene representation)DeepSDF3 NeRF!3.1 Radiance Fields(RF)...
  • 游戏引擎中的渲染; Cluster-based mesh pipeline GPU culling

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 112,355
精华内容 44,942
关键字:

游戏渲染