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

Shader optimization

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

Shader编程和优化是游戏开发中比较困难的一部分,因为它很抽象,想要写出高质量的Shader代码要比写普通的CPU的游戏逻辑代码差别很大。有时候还要需要些走后门的歪路子小技巧,比如提前计算数据,把数据存入纹理贴图中。

很多开发者喜欢用可视化的工具编写Shader,比如Shader Forge或者Amplify Shader Editor,但是它们生成的代码有可能不是最高效的。无论我们用不用可视化工具编写Shader,都应该来使用一些能够优化Shader的技巧。

1.Consider using Shaders intended for mobile platforms

Unity的内置Shader中有Mobile的版本,这些版本的Shader效率更高,PC主机游戏平台也可以使用这些版本的Shader来减少开销,但是要评估使用这些Shader导致的渲染效果下降是否可以接受。

2.Use small data types

数据类型越小,GPU计算更快。特别是移动平台上。所以我们第一个方法就是将float(32位)替换成更小的类型,比如half(16位),甚至fixed(12位),越小的位数也就需要更少的计算量。

Color 数值是优化对象之一,通常减少一些精度效果上并没有非常明显的感知,但是也要权衡是否真的可以接受渲染上效果的下降。

要注意的是这个优化方法会根据GPU的架构甚至品牌都会有影响,优化的效果也会不尽相同,我们可能得需要进行不少测试来验证优化效果。

3.Avoid changing precision while swizzling

Swizzling 是shader中从一个现有的vector通过我们想要的数据创建一个新的vector。一些例子比如:

用xyzw和rgba都可以,无论是个vector还是color,这种写法都使得Shader代码更容易理解。

在shader中进行精度的转换是开销很大的操作,在swizzling时进行数据精度的转换开销就更大了,所以我们要杜绝在在swizzling时进行数据精度的转换,如果有这种需求,还不如一开始就使用告精度的数据。

4.Use GPU-optimized helper functions

Shader 编译器通常会有效的优化数学运算,但是CG和Unity提供的库函数相比自己写的代码大多数情况下还是效率高的多。当我们写自定义的shader时候,可以找找库里有没有已经有提供的,比如CG库提供了abs(),step()等,Unity库提供了 WorldSpaceViewDir()来计算摄像机朝向,Luminance()将Color转成grayScale等。

CG库函数:http://http.developer.nvidia.com/CgTutorial/cg_tutorial_appendix_e.html

Unity库函数: http://docs.unity3d.com/Manual/SL-BuiltinIncludes.html.

5.Disable unnecessary features

去掉不必要的属性可以节省性能,比如我们使用的Shader有没有必要需要transparency, Z-writing, alpha-testing或者alpha blending?去掉这些设置或者属性带来的渲染效果的下降是否可以接受,如果可以的话这是一个降低Fill Rate开销的好办法。

6.Remove unnecessary input data

删除掉Shader中没用到的输入数据,因为它们会需要从内存中读取,消耗性能。

7.Expose only necessary variables

把Shader中的变量在material中暴露出来是有开销的,因为GPU没办法将这些变量认为是constant的,编译器没法按常量编译它们,这些数据必须每次都从CPU传入到GPU中。当然把变量暴露出来,调整效果调试的时候会比较麻烦,所以这条优化可以是在项目的后期再处理。

8.Reduce mathematical complexity

复杂的数学运算会导致渲染的瓶颈,因此我们要尽量避免。一种方法是提前计算好,把结果存入一张textrue中,之后在运行时可以将这个texture传入Shader中然后采样获得结果从而代替复杂的运算。

对于sin()和cos()这些函数我们duck不必这么做,因为它们已经被GPU高度优化过,但是其他类似 pow(), exp(), log()和我们自己写的函数就是可以优化简化的对象。

这种技术会有额外的内存开销去存储texture,也会增加Memory Bandwidth的开销,但是Shader没采用这种技术前本来也需要textrue的话,如果textrue的alpha通道并没有使用的话,我们就可以把结果存入alpha通道中,这种做法就非常nice,并不会有额外的开销,唯一需要的就是程序和美术要配合起来,程序提供所需存的结果给美术生成texture。

9.Reduce texture sampling

Memory Bandwidth开销最大的就是texture采样。Texture使用的越少,texture越小,性能越好。Texture越多,cache命中率就会越低,Texture越大,memory Bandwidth就会消耗的越多。

10.Avoid conditional statements

现代的CPU中,对于条件判断语句,CPU会尝试进行预测,判断最有可能运行的分支,提前用空闲的核心计算。等程序真正运行到的时候,如果发现决定错误了,就舍弃之前的运算而选择另外的分支。这种技术提高了CPU的运行速度,因为提前运算或者舍弃结果都要比等待决定哪个才是正确的分支要快,而且绝大多数的时候,CPU的预测是正确的。

但是在GPU上,因为处理是并行的,对于条件判断语句,必须得决定多少核心运行这个分支,多少核心运行其他分支,直到所有分支都运行完。比如一个if-else判断,GPU需要告诉一部分核心处理true的这条分支路径,然后再去要求其他核心处理false的路径,除非所有核心处理同样的path,否则必须每次都要处理两个path。因此我们应该尽量避免在shader中使用条件判断和多分支,当然也取决于必要程度。对于像素级别的计算,相比于多分支的开销,可能我们倒不如接受一些不必要的计算。

11.Reduce data dependencies

编译器会尽可能的优化我们的Shader代码,让GPU处理起来更舒爽。下边这个例子是对优化非常不友好的一段代码:

上边的代码数据依赖非常严重,每一行的计算都依赖于上一行代码计算的结果,这种写法导致编译器没办法优化这段代码,因为他们没法在指令级别并行处理。下边的代码则解决了这个问题:

 这一次,编译器识别出这段代码可以在指令级线程并行处理,这可以大大提高执行速度。

12.Surface Shaders

Unity的Surface Shaders是一种简化的Fragment Shaders,unity引擎会自动将Surface Shaders代码转换,但是也就让我们少了很多优化的机会。Surface Shaders能做的事Fragment Shaders一定可以,但是Fragment Shader能做的Surface Shaders不一定可以。个人认为是尽量不要用Surface Shaders。

13.Use Shader-based LOD

我们可以强制Unity在渲染远距离的物体时使用更简单的Shaders,这样可以有效降低Fill Rate的开销,特别是对于我们的目标是要支持多平台或者非常广的硬件范围。LOD keyword可以在Shader中使用来设置当前支持的Shader,如果当前的shader和LOD level并不匹配,则会降低至其他备用Shader一直到有匹配的Shader,我们在运行时可以通过maximumLOD属性来动态更改shader的LOD值。

这个特性和之前介绍过的mesh的LOD技术很相似, 可以查看Shader-based LOD 的文档获取更多信息。https://docs.unity3d.com/Manual/SL-ShaderLOD.html

 

 

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

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

相关文章

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;就是在车迟国的“…

LeetCode面试题03. 数组中重复的数字

方法一&#xff1a;遍历数组 由于只需要找出数组中任意一个重复的数字&#xff0c;因此遍历数组&#xff0c;遇到重复的数字即返回。为了判断一个数字是否重复遇到&#xff0c;使用集合存储已经遇到的数字&#xff0c;如果遇到的一个数字已经在集合中&#xff0c;则当前的数字是…

涨跌因子计算器下载哪里下载_微信爱情指数计算器整蛊app下载_爱情指数计算器整蛊测试下载...

微信爱情指数计算器整蛊app是一款不错的爱情必备的计算器服务&#xff0c;让情侣们有一个很有意思的整蛊服务的App&#xff0c;喜欢的话快来下载吧。微信爱情指数计算器整蛊app介绍1、爱情指数计算器整蛊app是很有意思的一款爱情指数计算器软件2、操作起来也比较的简单&#xf…

如何用最简单的方式解释依赖注入?依赖注入是如何实现解耦的?

第一章&#xff1a;小明和他的手机 从前有个人叫小明 小明有三大爱好&#xff0c;抽烟&#xff0c;喝酒…… 咳咳&#xff0c;不好意思&#xff0c;走错片场了。应该是逛知乎、玩王者农药和抢微信红包 小明的三大爱好 我们用一段简单的伪代码&#xff0c;来制造一个这样的小…

closewait一直不释放_夏至太阳庆典 || 巨蟹座日蚀新月大释放蜡烛魔法仪式(寻找新的幸运儿)...

太阳庆典. 2020夏至 太阳庆典蜡烛魔法仪式夏至(MIDSUMMER)是四个至点之一&#xff0c;站在春分与秋分之间&#xff0c;并且成为光明力量的象征&#xff0c;因为在这一天白昼的时间是最长的&#xff0c;也代表阳性力量会在这一天达到顶端。许多古老文化会利用火元素来象征这一…

Postman status: 415_415亩!白云首宗农村土地规模化流转成功签约

6月3日钟落潭镇竹二村土地经营权流转签约仪式在白云产权中心顺利举行这是白云区首宗由政府主导的规模化土地流转↓↓↓<< 点击上方&#xff0c;观看完整视频 >>签约现场当天下午&#xff0c;竹二村经济联合社、广州市云供农业科技有限公司和广东三青农业科技有限公…