Unity 2017 Game Optimization 读书笔记 Dynamic Graphics(2)

Lighting and Shadowing

现代的游戏中,基本没有物体能在一步就完成渲染,这是因为有光照和阴影的关系。光照和阴影的渲染在Fragment Shader中需要额外的pass。

首先要设置场景中的Shadow Casters和Shadow Receivers,Shadow Casters投射阴影,Shadow Receivers接收阴影。之后每一个Shadow Receiver渲染时,GPU就会在灯光的位置和角度渲染Shadow Caster物体,将深度信息存储到一张贴图中。这张贴图就是常说的ShadowMap,它用来实时的渲染阴影。光照渲染和阴影渲染在渲染管线中开销非常大,需要每个顶点都要提供法线信息以及额外的顶点颜色信息等。因为Fragment Shader需要多个passes完成最终的渲染,Backe End在Fill Rate(许许多多的像素都需要绘制,重新绘制和合并)和 Memory BandWidth(额外的texture需要来回获取,比如LightMaps和ShadowMaps)两方面都会压力很大,这也是为什么实时阴影是非常昂贵的,也会给Draw Call带来很大开销。

但是光照渲染和阴影渲染应该是现在游戏中最重要的两部分,的的确确能给游戏带来效果上质的提升,出色的光照和阴影效果能使得平庸的场景摇身一变。有两种渲染管线,Forward Rendering 和 Deferred Rendering,在 Rendering  Edit |Project Settings | Player | Other Settings | Rendering 下可以进行设置,接下来介绍下这两部分。

Forward Rendering

同样的Shader多个Pass渲染,一共有多少个pass取决于光源的数量和光源的距离和光源的亮度。在Unity中,前向渲染规则如下:一个场景中多光照情形,按光源的重要程度排序,比如ABCD四盏灯用效果最好的逐像素方式渲染光照,DEFG用逐顶点方式渲染光照,GH则用球谐光照方式计算光照。(关于球谐光的一些知识,可以参考我的这篇文章https://blog.csdn.net/yinfourever/article/details/90205890)

Unity中正向渲染分为一个Base Pass和多个Additional Passes.

image

image

 

Base Pass: 用逐像素的方式渲染一个directional light, 所有球谐光和逐顶点光。在这个pass里也会计算lightmap等,directional light可以计算阴影,要注意如果使用了lightmap照亮的物体不会被球谐光照亮。

Additional Passes:每个其他需要用逐像素渲染的光源将会用一个Addtional pass渲染,默认情况下这些灯光不会有阴影除非使用了 multi_compile_fwdadd_fullshadows variant shortcut 更详细的信息可以参考Unity官方文档中关于Forward Rendering的介绍https://docs.unity3d.com/2019.2/Documentation/Manual/RenderTech-ForwardRendering.html
可以通过Edit | Project Settings| Quality | Pixel Light Count 设置像素光的数量,但是会被每个Render Mode设置为Important的Lights覆盖。

ForwardRendering当场景中有大量点光源时由于Render States需要不断的设置会产生大量Draw Call,跟场景光源数量正相关。

Deferred Rendering

Deferred Rendering通过G-Buffer工作,是将光照计算延后进行处理的一种渲染方法。

延迟渲染的优点
Deferred Rendering 的最大的优势就是将光源的数目和场景中物体的数目在复杂度层面上完全分开。也就是说场景中不管是一个三角形还是一百万个三角形,最后的复杂度不会随光源数目变化而产生巨大变化。

复杂度仅O(n+m)。
只渲染可见的像素,节省计算量。
用更少的shader。
对后处理支持良好。
在大量光源的场景优势尤其明显。
 
延迟渲染的缺点

内存开销较大。
读写G-buffer的内存带宽用量是性能瓶颈。
对透明物体的渲染存在问题。在这点上需要结合正向渲染进行渲染。
对多重采样抗锯齿(MultiSampling Anti-Aliasing, MSAA)的支持不友好,主要因为需开启MRT。
由于Deferred Shading的Deferred阶段是在完全基于G-Buffer的屏幕空间进行,这也导致了物体材质信息的缺失,这样在处理多变的渲染风格时就需要额外的操作。

更详细的有关渲染模式的知识请查看我的这篇文章(墙裂建议看)

https://blog.csdn.net/yinfourever/article/details/90263638

Vertex Lit Shading (legacy)

已被遗弃

Global Illumination

全局光,是烘焙光照贴图的一部分。光照贴图是提前烘焙好的,因此可以有足够的时间生成高质量的光照贴图,会节省大量Draw Call。也正是因为提前烘焙好的,所以它不是实时的,所以它对Static物体生效,动态物体需要通过LightProbe才能受到影响。LightProbe并不是像素级精准的(使用球谐光),并且会生成额外的LightProbe Maps,对Memory BandWitdh有开销,但是确实会对渲染效果带来很大的提升。

对于全局光,不仅计算直接光照的影响,还会将物体间反弹的光考虑进去。老版本的GI系统是Enlighten,它不仅提供了静态的GI,还提供了一种Pre-computed Real-time GI,可以用来制造实时渲染的假象,比如昼夜更替系统。目前Unity最新的GI系统是Progressive LightMapper。

关于这部分知识,我写过另一篇文章帮助理解https://blog.csdn.net/yinfourever/article/details/105151596

Multithreaded Rendering

多线程渲染在大多数平台中是被默认开启的,比如PC或者其他CPU支持多核的。对于Android,Edit | Project Settings | Player | Other Settings |Multithreaded Rendering可以进行设置,对于IOS可以在Edit | Project Settings | Player| Other Settings | Graphics API设置。

对于场景中的一个物体,要进行渲染的话有三件事需要处理。决定这个物体是否需要渲染,生成渲染指令,通过相关图形API发送指令到GPU。如果没有Multithreaded Rendering,这些工作都要由CPU主线程承担,开启Multithreaded Rendering,把渲染指令推送给GPU的工作将由render线程承担,其他例如剪裁等工作将由其他一些worker 线程承担。这给CPU主线程大大减压,可以给物理运算以及脚本逻辑运算留出更多空间。

开启Multithreaded Rendering后,关于CPU-Bound会有一些影响,没开启的时候,所有工作都是由CPU主线程做,因此无论那部分性能的优化都会对CPU-Bound带来改善。开启Multithreaded Rendering后,因为工作被分散到各个线程,即使对主线程做出一些优化,对CPU-Bound的减轻程度可能也会变得很小。

是否开启Multithreaded Rendering对GPU没影响,GPU已经总是用多线程渲染。

Low-level rendering APIs

通过CommandBuffer可以使用高级别的API对渲染管线进行一些控制,但是可用的内容和范围还是太少,因此可以用C++代码直接控制图形API,将C++代码打成一个Plugin,hook到Unity的渲染管线中。

当然,现在Unity已经推出了SRP(可编程渲染管线),已经可以完全自定义渲染管线,十分方便,因此这一小节提到的方法可能已经基本不会使用了。关于SRP,可以看我这篇文章https://blog.csdn.net/yinfourever/article/details/89364090

Detecting performance issues

Profiling rendering issues

通过Unity的Profiler 可以快速定位是瓶颈是在CPU和是GPU.

CPU-bound

下图是一个CPU瓶颈的例子,这个场景有成千的简单Cube物体,但是没有使用batching并且有阴影的渲染,这导致CPU需要生成大量的Draw Call,但是GPU实际上渲染任务很少。

如何定位问题的呢?下图中CPU平均需要25ms处理一个循环,而GPU只需要4ms以内,这就说明了瓶颈在CPU端,应该想办法使用一些优化CPU端的技术。

 GPU-bound

下图的测试条件为很少的Draw Call,但是使用非常复杂的Shader进行渲染。如果想测试是否是GPU端的瓶颈,需要注意的是要关掉V Sync(垂直同步),不然会影响Profiler。

从图中我们可以看到CPU和GPU都消耗29ms左右,但是再深层次查看一下,CPU的时间都花在了 Gfx.WaitForPresent函数上,这是在CPU在等待GPU完成这帧操作而浪费掉的时间,即使开启多线程渲染,CPU也必须是等待渲染管线完成后才能开始下一帧。Gfx.WaitForPresent也同时会被Vertical Sync使用,因此要关掉Vertical Sync来避免干扰。

Brute-force testing 

 如果从Profiler中没办法定位问题,我们可能就得使用蛮力测试。比如从场景中去除一些物体,看看性能有没有很大改善,如果很小的改动会带来很大提升,那其就定位了问题。

降低屏幕分辩率和降低贴图的分辩率来进行测试是两种定位瓶颈是FillRate还是Memory Bandwidth的好方法。

降低屏幕分辨率可以有效降低Frill Rate的消耗(比如2560 x 1440 降为 800 x 600大概会降低8倍),如果性能有很大的提升,说明Fill Rate有可能是我们应该首要考虑优化的地方。

类似的,如果降低贴图的分辨率后性能提升非常大,则说明Memory BandWidth可能是瓶颈。

GPU的瓶颈通常是FillRate和Memory Bandwidth,很少是Front End的原因,Vertex Shader如果有问题,只能是因为传入了太多几何体需要处理或者使用了很复杂的Geometry Shader。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/246205.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity 2017 Game Optimization 读书笔记 The Benefits of Batching

batching(合批) 和大量的描述一个3D物体的数据有关系,比如meshes,verices,edges,UV coordinates 以及其他不同类型的数据。在Unity中谈论batching,指的是用于合批mesh数据的两个东西&#xff1a…

Unity 2017 Game Optimization 读书笔记 Dynamic Graphics (3)

Rendering performance enhancements Enable/Disable GPU Skinning 开启GPU Skinning可以减轻CPU或GPU中Front End部分中某一个的负担,但是会加重另一个的负担。Skinning是mesh中的顶点根据动画中骨骼的当前位置进行计算,从而让角色摆出正确的姿势。 …

Unity手游开发札记——布料系统原理浅析和在Unity手游中的应用

原文:https://zhuanlan.zhihu.com/p/28644618 0. 前言 项目技术测试结束之后,各种美术效果提升的需求逐渐成为后续开发的重点,角色效果部分的提升目标之一便是在角色选择/展示界面为玩家提供更高的品质感,于是可以提供动态效果的…

行为树(Behavior Tree)实践(1)– 基本概念

原文:http://www.aisharing.com/archives/90 行为树(Behavior Tree)实践(1)– 基本概念 自从开博以来,每天都会关心一下博客的访问情况,看到一些朋友的订阅或者访问,不胜欣喜&…

Unity 2017 Game Optimization 读书笔记 Dynamic Graphics (5) Shader优化

Shader optimization Fill Rate和 Memory Bandwidth开销最大的地方就是Fragment Shader。开销多大取决于Fragment Shader的复杂程度:多少纹理需要采样,多少数学计算函数需要使用等等。GPU的并行特性意味着在线程中如果任何地方存在瓶颈,都会…

Unity 2017 Game Optimization 读书笔记 Dynamic Graphics (6)

1. Use less texture data 这条优化技巧非常直接,减少texture的数据量,减少分辨率或者降低位数,虽然可能会降低渲染质量。但是通常使用16-bit textures并不会明显的感觉到渲染效果下降。 MipMap技术可以有效减少VRAM和Texture Cache之间来回…

LeetCode 面试题57 - II(剑指offer) 和为s的连续正数序列

今天毕业五年了,一直忙于工作和享受,自从当年找完工作后就一直没有再刷过题,作为搬砖的码农,觉得还是应该养成长期刷题的习惯坚持下去。之前坚持了每天被一会单词,如今雅思一本也快看完了,从今天开始准备在…

反走样技术相关文章

https://zhuanlan.zhihu.com/p/28800047 https://zhuanlan.zhihu.com/p/57503957 https://zhuanlan.zhihu.com/p/33444125 https://zhuanlan.zhihu.com/p/33444429 走样的原因及其分类 说到走样,首先要说的就是采样。这也算是很多图形学专著中提到反走样相关技…

求n的阶乘的算法框图_单片机常用的14个C语言算法

问:怎么每天看到这种文章?答:只需搜索公众号"51单片机学习网"免费关注算法(Algorithm):计算机解题的基本思想方法和步骤。算法的描述:是对要解决一个问题或要完成一项任务所采取的方法和步骤的描述&#xff…

LeetCode 286. 墙与门 多源BFS和DFS

思路1&#xff1a; DFS&#xff0c;对于每个门进行一次DFS搜索&#xff0c;记录每个位置对每个门的距离&#xff0c;当有更小距离的门时更新这个数值 public void WallsAndGates(int[][] rooms) {for (int i 0; i < rooms.GetLength(0); i){for (int j 0; j < rooms[i]…

贝塞尔曲线

文章参考于&#xff1a;https://www.jianshu.com/p/0c9b4b681724 https://gameinstitute.qq.com/community/detail/129188 贝赛尔曲线的前世今生&#xff1a; 贝塞尔曲线&#xff0c;这个命名规则一眼看上去大概是一个叫贝塞尔的数学家发明的。但&#xff0c;贝塞尔曲线依据…

如何控制局域网网速_单臂路由|N1盒子(OpenWRT)单线多拨实现网速叠加

受于某些现实条件&#xff0c;有些同学苦于家里的网络带宽太小无法尽情冲浪。如何在不额外花钱升级宽带的情况下提升家里网络呢&#xff1f;且看一个盒子加路由器即可实现网络单线多拨&#xff0c;成倍提升网速完成网速叠加。题图是我家里的路由器加N1盒子。前置条件光猫有超级…

linux离线安装redmine_Linux 下一款非常好用的翻译软件

前面有一个半月的时间&#xff0c;我非常详细且非常基础的介绍了 Ubuntu 18.04 desktop 桌面系统的安装和基本使用&#xff0c;在知乎上也开了一个专栏《Linux 漫游之旅》&#xff0c;上面记录了所有的文章&#xff0c;这个专栏的目的呢是手把手教新接触 Linux 操作系统的朋友如…

vivo应用商店电脑版_VIVO应用商店代理商江湖的那些关系

VIVO应用商店代理商江湖的那些关系需要源文件清晰版本加微信wps007其他干货文章如何不花钱或者少花钱把ASO的活给干了&#xff1f;2020最新主流安卓应用市场ASO技巧以及注意事项App推广的高阶玩法&#xff0c;一箭双星&#xff01;今日头条定向优化技巧今日头条广告创意优化指南…

华为阅读下载的文件在哪里找_华为手机还要天天清理内存?1键关闭这2个设置,手机用到2035年...

阅读本文前&#xff0c;请您先点击上面的蓝色字体“科技荟 ”&#xff0c;再点击“关注”&#xff0c;这样您就可以继续免费收到最新文章了。每天都有分享。完全是免费订阅&#xff0c;请放心关注。 华为手机还要天天清理内存&#xff1f;1键关闭这2个设置&#xff0c;手机用到…

pyautogui 打包 运行 窗口_试试动态窗口管理器 dwm 吧

以不到 2000 标准行的代码写就的 dwm&#xff0c;是一个速度极快而功能强大&#xff0c;且可高度定制的窗口管理器。-- Adam Šamalk(作者)如果你崇尚效率和极简主义&#xff0c;并且正在为你的 Linux 桌面寻找新的窗口管理器&#xff0c;那么你应该尝试一下 动态窗口管理器(dy…

ArcMap 导入 wrl_flmic拍摄的素材如何无损导入电脑

点击上方“九尾短视频研习室” 可以订阅哦&#xff01;今天分享使用 iPhone 或者安卓版 filmic 拍摄的素材&#xff0c;如何无损导入到win 或 Mac 电脑中~01iPhone Mac使用 iPhone 和 Mac 的朋友&#xff0c;可以使用“隔空投送”无线传输&#xff0c;但是这个过程中&#xff…

LeetCode 97: 交错字符串

这里我们考虑用 s1和 s2的某个前缀是否能形成 s3 的一个前缀。 这个方法的前提建立于&#xff1a;判断一个 s3的前缀&#xff08;用下标 k表示&#xff09;&#xff0c;能否用 s1和 s2 的前缀&#xff08;下标分别为 i和 j&#xff09;&#xff0c;仅仅依赖于 s1 前 i个字符和…

苹果6发布时间_苹果秋季发布会将在北京时间9月16日举办

点击上方蓝字&#xff0c;关注我们苹果正式公布了苹果秋季发布会9月16日举办&#xff0c;届时国内可在五大平台上观看直播&#xff0c;据悉本次发布会将发布的产品有iPhone、ipad和Apple Watch等系列新品&#xff0c;那么这场发布会可以在哪看呢?下面小编带来了2020年苹果秋季…

安装ccs5.5总出现错误_《西游记》“斗法降三怪”,出现错误而补拍,观众总觉得改过结尾...

文|平小山86版《西游记》播出多年&#xff0c;每一年寒暑假都会在电视台重播&#xff0c;看了无数遍还是让观众乐在其中。后来无论是TVB版、浙版、还是张纪中版翻拍的《西游记》&#xff0c;都始终无法撼动它的经典地位。在86版《西游记》中有一集&#xff0c;就是在车迟国的“…