Unity5内部渲染的优化1:介绍

译自aras的博客,总共3篇文章,讲述unity5优化自己渲染器的过程

吸取大神调试与优化经验

在工作中我们形成一个小组“strike team”来优化unity渲染的cpu部分。

基本信息/父本的警告

在很多情况下,我要严厉的说“这段代码很烂!“。当要努力改善代码的时候,你当然想提高不好的地方,这是重点。

一般来说并不意味着代码库是坏的,或者它不能用于做出好东西。就在今年3月,我们有Pillars of Eternity, Ori and the Blind Forest and Cities: Skylines among top rated PC games; 这些游戏都使用unity做的。“手机引擎只适合原型设计”这点还不太糟。

事实是,任何代码库,在很久的时间开发使用,并只有很少的人使用,在某种意义上真是糟糕。他们是代码奇怪的地方。没有人记得它们是怎样工作的,因为是在很多年前做的,没有意义了,也没有人来修复。在一个足够大的代码库,没有一个人可以知道所有的关于它如何工作的详细信息,所以在其他一些微妙的方式有一些决策冲突。借用某人的一句话“there are codebases that suck, and there are codebases that aren’t used” :)

努力改善代码库是很重要的!我们一直在坚持在改善它。我们已经在所有的方面都做了大量的改进,但坦率地说,渲染代码在近几年改进的非常多,没有人把单独维护和提高带代码成一个全职的工作,但是我们做了!

好几次我指着一些代码,说“哈哈!那太愚蠢了!”这是我写的代码。或者是有各种因素的代码(缺乏时间等)。也许我当时是愚蠢的,也许我在五年后会说一样的话。

愿望清单

系统的高吞吐量,没有瓶颈的工作。

(Unity5.0)现在的渲染,,着色器运行&图形API的CPU代码并不是非常有效率。它有一些问题,需要我们尽可能多的解决:

1.    图形加速器(Gfx)设备(我们的抽象渲染API)

a.抽象主要是围绕DX9 / 部分的DX10的概念设计。例如常数/统一(constant/uniform)缓冲现在并不适合。

b.过了几年越来越混乱,有些地方需要清理

c. 允许并行命令缓冲区创建现代API(如consoles, DX12, Metal 或 Vulkan)。

2.渲染循环

a.许多无效的东西和多余的决策需要优化

b.并行运行的循环和/或它们的jobify部分 。如果可能的话,使用原生的命令缓冲创建API。

c.让代码更简单更统一。分析出常用的功能。更多的可测试性。

3.着色器/材质的运行

a.数据在内存中的布局并不是特别好

b.想要清理复杂的代码。增加可测试性。

c. “固定功能着色器(Fixed function shaders)”的概念在运行时不应该存在。见【Generating Fixed Function Shaders at Import Time】。

d.基于文本的着色器格式是愚蠢的.见【Binary Shader Serialization】

限制

无论我们优化/清理代码,我们都应该尽可能保持他们的功能可以工作。一些很少使用的功能或特殊的情况可能被改变或破坏,但这只是作为最后的手段。

还有一点需要考虑,如果一些代码看起来很复杂,它也许由于以下几个原因产生的。其中之一就是“有人写的代码太复杂”(太棒了!我要简化它)。另一个可能是“有一些代码因为一些原因在过去是复杂的,但现在不是了”(太棒了! 我要简化它)。

但是也有可能代码做了复杂的事情,例如它需要处理一些棘手的情况。开始从头“重写”代码很容易,但在某些情况下一旦你开始让你的又新又好的代码做旧代码所做的一切时,它可能变得复杂。

计划

增加一段CPU的代码,通过几方面改善它的性能:1)“只是使它更快”和2)使它更并行。

我想首先关注“只是使它更快”部分。因为我也想简化代码,又想到要做很多棘手的事情。简化数据,使数据流更加清晰,使代码更简单往往还是做第二步(“更并行”)更容易。

首先我会看着更高水平的渲染逻辑(“渲染循环(rendering loops)”)和材质/材料运行,团队中的其他人将考虑简化和处理抽象渲染API,并尝试“更并行”的方法。

进行渲染性能测试,我们会需要一些实际的内容去测试。我看了现有的几个游戏和演示,让他们的CPU被限制 (通过减少GPU负载-低分辨率渲染;减少多边形数,减少阴影贴图;减少或消除后期处理;减少纹理分辨率)。让CPU有更高的负荷,我复制了部分场景,所以要比原来的渲染得更多。

渲染测试非常简单,比如“嘿,我有100000个cubes!”但这并不是一个现实的例子。“只是大量使用相同材质的大量的对象”是一个非常不同的渲染情况,从用不同参数的成千上万的材质,数以百计的不同的着色器,几十个渲染目标的变化,阴影贴图&定期渲染,对象的alpha混合,动态生成几何体等。

另一方面,测试一个“完整的游戏”也非常麻烦,特别是它有需要交互的地方,缓慢加载所有关卡,或不限制CPU。

当测试CPU性能时, 在多个设备上测试很有帮助。我通常在PC  Windows 系统(i7 5820 k),在Mac笔记本(2013 rMBP), iOS设备怎样都好我现在在用 (iPhone 6)上进行测试。在控制台上测试将会很棒,我一直听说到他们有很棒的分析工具,或多或少固定的时钟和cpu——但我并没有devkits。也许这意味着我应该弄一个。

注释

接下来,我运行了标准的项目看了分析的数据(包括unity分析器和第三方评测器不活跃的困/工具) ,也看了代码看它做什么。此时,每当我看到了一些奇怪的事情于是我把它写下来供以后调查:

以下来自上图翻译

setPassWithShader  在某些点来避免PPtr dererf的最优化方式。现在他看起来总是做PPtr dererf,然后只要调用SetPass(又做了一次dererf)。

材质显示列表不断的重建>1的每像素光。不需要储存多于一个列表的材质

GetTextureDecodeValues被调用了很多次(建立像素光cookie的一些东西),结束无用的线性gamma转换

材质显示列表不断地重建由于未赋值的全局贴图属性而产生连锁反应(_Cube ,没有赋值),在我们的属性丢失了的时候同时需要找出为什么我们会失败并做记录

GpuProgramParameters::MakeReady是做什么的?为什么把它区分?

为什么STL maps被属性表使用?

1.    只使用健全的&简单的数据布局

2.    相关的怪事:

1.    为什么TexEnv 从属性表中分离?

2.    SetRectTextureID-为什么,什么

3.    贴图 像素宽度/HDR 解码性能的一部分在设备状态中执行

4.    NotifyMipBiasChanged 有很多复杂的事情,原不明

IsPassSuitable在渲染循环中一次又一次的被调用。也许在渲染循环中要建立direct pass 指针表?

一次性提供所有贴图取代在某一时间SetTexture

在内存中安排属性表数据来匹配真实不变的缓冲布局。可能需要几个不同关键的字布局

TextureID转换为long(mac/linux中是64位)被ps4特殊提交3cbd28d4d6cd

1.    看起来像只在ps4上的优化,直接存储一个指针到TextureID。如果可以的话无论任何地方都这么做,或者只在ps4把它做成long(intptr_t更好)

为什么ChannelAssigns 和VertexComponent在所有时间都能通过吗?似乎没有什么用处

渲染循环分类是非常昂贵的。基于哈希分配(渲染循环分配)开启并完成它。

上面的一些缺陷可能由某些原因产生,在这种情况下,我添加注释去解释它们。可能当时有一些原因,但现在没有了。在这两种情况下源控制日志/注释功能是非常有帮助的,并问写代码的人当初为什么会这样。上面的列表的一半也许因为我以这种方式写很多年了,这意味着我必须记住这些原因,即使他们“在当时似乎是一个好主意”。

这就是介绍。下一次,会对上面的清单做点什么!

下一篇待译

          ------译自 wolf96    http://blog.csdn.net/wolf96

时间: 2024-10-09 17:24:49

Unity5内部渲染的优化1:介绍的相关文章

Unity5内部渲染的优化2:清理

译自aras的博客,总共3篇文章,讲述unity5优化自己渲染器的过程 吸取大神调试与优化经验,了解unity5内部渲染器的优化方法 前篇:Unity5内部渲染的优化1:介绍 介绍过去后,让我们来进行实际工作 在以前的文章已经提到的,首先我尝试想起/找出现有代码,做一些分析并且写下突出的地方. 分析多个项目主要揭示了两件事: 1.    渲染代码使用多线程真的比使用我们现有的"一个主线程和一个渲染线程" 更广阔.这里有一个从unity5的timeline profiler的截屏: 在这

Unity5内部渲染的优化3:移除固定功能

译自aras的博客,总共3篇文章,讲述unity5优化自己渲染器的过程 吸取大神调试与优化经验,了解unity5内部渲染器的优化方法 第一篇:Unity5内部渲染的优化1:介绍 第二篇:Unity5内部渲染的优化2:清理 上篇文章写了关于清理和优化.从那时起,我已经转变到做一些unity5.1的工作了,移除了固定功能着色器Fixed Function Shaders和一些别的事. 固定功能是什么 以前,GPU还没有"可编程着色器programmable shaders":通过启用和禁用

浏览器渲染速度优化

前言: 要实现网站的大提速,必须在各个环节进行精确的设置和安排.网站一旦打开速度变慢,往常,站长们第一时间肯定会认为“服务器慢”,其实看完本章后,你会发现或许结果并不完全是这样.影响网站速度的因素千差万别,服务器仅是其中一小部分因素而已. 有一种常见的情况,同样的服务器,网站与网站之间的打开速度也千差万别,这就和网站的制作工艺有相当大的关系:本节重点讲一下网站制作工艺优化. 我们可以大致将影响网络速度的因素分为五个来进行分别优化: 一.服务器硬件配置和设置: 二.服务器的线路及带宽: 三.用户电

react+redux渲染性能优化原理

大家都知道,react的一个痛点就是非父子关系的组件之间的通信,其官方文档对此也并不避讳: For communication between two components that don't have a parent-child relationship, you can set up your own global event system. Subscribe to events in componentDidMount(), unsubscribe in componentWillU

Hive优化策略介绍

作为企业Hadoop应用的核心产品之一,Hive承载着公司95%以上的离线统计,甚至很多企业里的离线统计全由Hive完成: Hive在企业云计算平台发挥的作用和影响越来越大,如何优化提速已经显得至关重要: Hive作业的规模决定着优化层级,一个Hive作业的优化和一万个Hive作业的优化截然不同: 后续文章将从如下三个方面进行hive的优化介绍: 1)  架构方面(高效.全局.局部)----最有效的优化,好的架构能让作业性能提高很多 a)  分表:(日志表量大而且作业访问次数多,造成耗时较长:将

Oracle的优化器介绍

Oracle优化器介绍 本文讲述了Oracle优化器的概念.工作原理和使用方法,兼顾了Oracle8i.9i以及最新的10g三个版本.理解本文将有助于您更好的更有效的进行SQL优化工作. RBO优化器 RBO是一种基于规则的优化器,随着CBO优化器的逐步发展和完善,在最新的10g版本中Oracle已经彻底废除了RBO.正在使用Oracle8i或9i的人们或多或少的都会碰到RBO,因此在详细介绍CBO之前,我们有必要简单回顾一下古老的RBO优化器. 在RBO中Oracle根据可用的访问路径和访问路

网站安全狗”响应内容保护“网页错误返回页面优化功能介绍

网站安全狗最新版本(主程序版本号:3.2.08157)在“资源保护”模块多了一个功能叫做:响应内容保护.如下图所示: <ignore_js_op> 该模块的主要功能是,当我们访问网站时,不合理的访问,或者网站自身的问题,会出现各种的错误返回页面.从安全的角度上讲,这就可以给攻击者提供判断的依据,为了防止这种情况,网站安全狗对网页错误的返回页面做了优化处理,并将此资源进行了回收利用,加入了百度推广的相关广告信息. <ignore_js_op> 该页面的推广信息为您搜索的相关类似信息.

机器学习几种常见优化算法介绍

机器学习几种常见优化算法介绍 https://blog.csdn.net/class_brick/article/details/78949145 1. 梯度下降法(Gradient Descent) 2. 牛顿法和拟牛顿法(Newton's method & Quasi-Newton Methods) 3. 共轭梯度法(Conjugate Gradient) 4. 启发式优化方法 5. 解决约束优化问题--拉格朗日乘数法 我们每个人都会在我们的生活或者工作中遇到各种各样的最优化问题,比如每个企

php-fpm优化参数介绍

1.php-fpm优化参数介绍他们分别是:pm.pm.max_children.pm.start_servers.pm.min_spare_servers.pm.max_spare_servers. pm:表示使用那种方式,有两个值可以选择,就是static(静态)或者dynamic(动态).在更老一些的版本中,dynamic被称作apache-like.这个要注意看配置文件的说明. 下面4个参数的意思分别为: pm.max_children:静态方式下开启的php-fpm进程数量pm.star