查看原文
其他

Unite 2017 | Unity可编程渲染管线剖析

2017-06-21 柳振东 Unity官方平台

Unity正在开发一套新的渲染管线,名叫Scriptable Render Pipeline,这套管线有望出现在Unity接下来的新版本中。更改渲染管线对游戏引擎来说绝非小事,那为什么我们要这样做,而新的管线和现有的又有什么区别呢?今天就由Unity技术支持工程师柳振东,来跟大家聊一聊这方面的话题。


现有管线的问题

先来看看Unity渲染管线的现状,Unity现在提供Forward和Deferred这两种主流的Render Path,然后用户在选定的Render Path上使用Standard Shader基本可以满足大部分的需求。对于一些定制的渲染需求,用户可以考虑使用Command Buffer来扩展现有的管线,还可以通过Custom Shader来扩展Standard Shader。而这种相对固定的渲染管线在实际使用中还是存在一些本质上的问题的。



可配置性

渲染管线本身是个黑盒,引擎本身只提供一些Hook Point来进行一定程度的定制

用户无法改变从根本上已经写死的逻辑流程,很多情况下当用户有特殊需求时,基本就是对各种配置进行不断试错的过程,而且很可能最后也没法实现理想的效果,也不知道到底是哪里出错了。

 

可发现性

各种设置选项的可组合数量随着特性的增加呈指数性增长,越来越难找到可能存在的Bug;不同设置组合的效果也不可能一一在参考文档中列举,有些时候很难找到正确的搭配选项。

 

灵活性

固定的管线逻辑能做的事情还是有限的,反之,用户也没法从管线中裁掉不需要的渲染部分逻辑。



另一方面,从引擎本身的开发来看,我们也有项目维护上的难题。一般来说,当我们发现渲染上需要一个新功能时,那就加进去,然后这部分代码就一直保留在里面。当然在这期间也会去做一些修改,但这样还是会积累起很多旧有的内容(比如Grab Pass)。代码愈加复杂也会导致更改一些逻辑可能会出现一些副作用,有时甚至有些Bug我们不能去修复,因为可能会破坏Unity的向后兼容性。

 

总的来说,Unity让各种不同的游戏或应用类型都用着同一套固定的渲染管线,从本质上来说就很难做到在任何场合都是最优化的,所以是时候在这方面做一些工作了。


新的发展方向

我们在管线设计的概念上做了转移,决定在C++端保留一个非常小的渲染内核通过API暴露出更多的选择性给C#端,也就是说,我们会提供一系列的C# API以及内置渲染管线的C#实现;这样一来,一方面可以保证C++端的代码都能严格通过各种白盒测试,另一方面C#端代码就可以在实际项目中调整,有任何问题也可以方便地进行调试。



对于新的渲染管线,我们遵循几个明确的设计目标。

 

精简设计

管线尽量精简,只做特定的管线需要做的事情。一方面我们维护更少的代码,用户在引擎端需要做的设置也更少;不同的模块互相独立,尽量减少耦合以减少集成测试和可能的Bug。


用户导向

渲染管线的代码可以直接存在于用户的项目里,用户更容易调试,使问题在用户端就可以得到解决,而不是发现Bug后只能提交到官方等待修复;另一方面也让用户的主动性更大,能够做更有创意的设计。


性能最优化

根据不同平台与应用场合,内置的多条渲染管线做到高度定制化,性能优化只需考虑当前适用平台。


避免黑盒

现有的管线太智能,以至于有些时候不知道该怎么设置,新管线需要尽量保证API的明确性,拒绝黑科技,让用户对渲染流程的把控可以非常清晰。

 

图1 C++与C#端分工

                                         

新的管线对用户而言主要是C# 端的API以及由这些API编写的一系列定制化的内置渲染管线。而在内部实现上,引擎C++端会负责多线程实现性能关键的部分,如上图所示,而C#端负责更高层的渲染指令调度。

 

用户可以直接使用开源的内置管线,或者在内置管线的基础上进行修改,甚至直接编写定制化的管线。具体使用上渲染管线在工程中会生成特定的Asset,如下图所示,这个Asset序列化了这条管线的一些公共设置变量,并负责在运行时创建实际的渲染上下文;当这个Asset的设置变量在运行时发生变化,引擎会销毁当前上下文然后重新创建管线(这个操作在现有固定管线中无法做到)。


图2 管线的使用层设计

 

这里为了让大家感受下管线的编写方式,我们展示一个最简单管线的代码。其中最关键的是Render回调,这里仅仅是每帧清除Render Target,设定指定的背景色。另外值得关注的是这里用了Command Buffer,这个特性会在渲染中作为重要的指令打包方式,管线中每个Command Buffer都会作为一个Job放入Unity的Job system中并行执行。

 


现在5.6的beta版本提供了早期的Scriptable Render Pipeline实现,感兴趣的开发者可以点击[阅读原文]进入Unity官方中文社区(unitychina.cn),下载对应的Demo工程一睹为快。


更多Unity相关技术文章

Unity中可用于VR环境的空间化音效

Unity 5.6中的混合光照

Unity实验预览版支持为macOS开发VR及AR内容

基于Animation Instancing的大规模人群模拟

eaglEEye性能测试平台详解


Unity官方活动


2017年首次Unity官方问卷调查启动,完整填写并提交还有机会获得Unity限量双肩包一份,仅剩最后几天!


点击“阅读原文”进入Unity官方中文社区

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存