Unity 可編程渲染管線, LWRP輕量級渲染管線(Light Weight Render Pipeline)出來有一段時間了, 今天寫一遍文章回梧,詳細(xì)的介紹一下可編程渲染管線與LWRP輕量級渲染管線相關(guān)內(nèi)容嗜暴,幫助大家搞懂這些概念湿故,并建立起一個學(xué)習(xí)可編程渲染管線/輕量級渲染管線的思維。整個文章我將會分成4個部分來個大家講解:
(1): 什么是渲染管線與向前渲染;
(2): 什么是可編程渲染管線;
(3): 輕量級渲染管線與它的基本使用;
(4): 輕量級渲染管線Shader 模板結(jié)構(gòu);
每個Unity版本沼填,實(shí)現(xiàn)的輕量級渲染管線LWRP的代碼可能都不一樣,但是思路原理基本都差不多。
1: 什么是渲染管線與向前渲染
我本人非常反對高大上的概念包裝驰坊,唯獨(dú)游戲中的"渲染"是例外之一。通俗點(diǎn)說渲染就是烘托出相應(yīng)的環(huán)境(光照,陰影哮独,遮擋拳芙,反射察藐,折射等),把物體在特定的環(huán)境中繪制出來舟扎。Unity引擎里把引擎中完成整個游戲場景分飞,人物, 環(huán)境,光照等游戲畫面繪制相關(guān)睹限,最終把畫面繪制到屏幕上的整套邏輯與相關(guān)代碼(普通代碼與Shader代碼)稱為渲染管線譬猫。
Unity引擎的渲染管線主要分為"渲染核心庫"與"渲染策略"兩個部分, “渲染核心庫”是Unity把基于OpenGL/DirectX把渲染相關(guān)的接口函數(shù)封裝成API,這部分Unity引擎寫好后作為核心的API渲染庫羡疗∪痉”渲染策略”指的是Unity引擎繪制整個游戲場景的時候,如何處理多相機(jī)顺囊,多光源肌索,陰影投射,物體繪制特碳,霧,自發(fā)光等诚亚。這個就叫做渲染策略,渲染管線基于一種渲染策略午乓,調(diào)用渲染核心庫中的API站宗,把整個游戲場景繪制出來。
早期的Unity引擎益愈,把整個渲染管線都內(nèi)置在引擎里面梢灭,沒有開放給開發(fā)者,只有少數(shù)的一些大廠蒸其,獲得了Unity引擎源碼授權(quán)敏释,能修改和定制里面的渲染管線相關(guān)代碼。Unity內(nèi)置的渲染管線有: 向前渲染摸袁,延時渲染等钥顽,目前這兩種用的比較多。Unity引擎默認(rèn)使用"向前渲染"靠汁。接下來我說一下向前渲染管線中的一個渲染策略,為了后面對比輕量級渲染管線做好鋪墊蜂大。向前渲染管線可以處理任意多的光源,處理多光源的時候,每個重要光源蝶怔,都會調(diào)用一次Shader里面的Pass來完成渲染奶浦,有幾個重要光源就會渲染幾次,這樣大大降低了多光源時候的繪制效率踢星。所以之前我們很多手機(jī)游戲上面都用靜態(tài)光照來渲染場景澳叉,獲得逼真的光照效果,因?yàn)橄蚯颁秩竟芫€多光源的實(shí)時計(jì)算開銷實(shí)在太大。靜態(tài)光照有一個問題就是無法獲得實(shí)時光照的效果耳高。
2: 什么是可編程渲染管線
前面?zhèn)€講解了渲染管線與內(nèi)置的先前渲染管線扎瓶,我們會發(fā)現(xiàn)內(nèi)置的渲染管線的策略有時候不滿足我們的要求,比如我們需要實(shí)時光照泌枪,又需要好的性能概荷,那么向前渲染每個光照都走一次Pass顯然不合適,做手機(jī)游戲碌燕,可能只要4個光源就可以了误证,不用支持任意多的光源,隨著unity可以開發(fā)越來越多的游戲平臺修壕,不同平臺愈捅,不同類型的游戲越來越需要能修改渲染管線相關(guān)的策略,到達(dá)好的效果慈鸠,同時有好的性能蓝谨。Unity新版本推出了可編程渲染管線,把渲染管線里面的渲染API核心庫開放給開發(fā)者青团,允許開發(fā)者自己定制渲染策略譬巫。Unity引擎提供了一整套可以定制渲染管線的機(jī)制,所以叫做可編程渲染管線SRP(Scriptable Render Pipeline)督笆。
3: 輕量級渲染管線與它的基本使用
內(nèi)置的渲染管線是針對通用情況芦昔,比如支持任意數(shù)目的光源等,所以很多策略并不是特定的環(huán)境下娃肿,針對特定應(yīng)用場景而得到的最佳的策略咕缎,現(xiàn)在手機(jī)游戲非常的廣泛,還有很多其它的游戲平臺料扰,需要好的渲染效果的同時凭豪,需要一個好的性能。比如我就希望有多光源的實(shí)時光照晒杈,我的角色到了光源附近能渲染出光的效果出來墅诡,而不是使用靜態(tài)光照那樣。同時我們又不需要任意多的光源桐智,只要限定一個光源數(shù)目即可,比如4個烟馅。這樣就可以通過定制渲染管線,提升性能说庭,比如我們最多支持4個光源,我把所有光源的計(jì)算一起放到一個Pass里面,這樣提升性能的同時郑趁,又獲得實(shí)時的光照刊驴,雖然對光源的數(shù)目做了一些限制(輕量化),卻獲得了效果和性能的一個靈活的平衡。Unity 針對手游等應(yīng)用領(lǐng)域,開發(fā)了輕量級渲染管線(LWRP),后來基于輕量級渲染管線又衍生出來另外一個渲染管線Universal Render Pipeline(URP,這邊文章我們用的是URP的代碼)捆憎。
渲染管線的渲染策略被定制了舅柜,渲染的時候需要Shader來配合最終繪制物體出來,所以不同的渲染管線Shader會不一樣躲惰,我們之前學(xué)習(xí)的Shader開發(fā)都是針對向前渲染管線的致份,比如輕量級渲染管線所有光照計(jì)算都在一個Pass,那么之前向前渲染的Shader肯定就不能直接使用了。所以當(dāng)我們定制了新的渲染管線以后础拨,還要基于新的渲染管線的策略重新開發(fā)一個Shader包(PBR Shader, 粒子, 霧,天空盒等)氮块,這個Shader包能滿足大部分的3D游戲開發(fā)的需求,同時我們也可以基于新的渲染管線的策略來開發(fā)自己的Shader诡宗。
總結(jié)一下定制渲染管線的主要的3個點(diǎn):
(1) 渲染核心功能的API滔蝉,由引擎開放給開發(fā)者調(diào)用;
(2) 定制渲染策略,開發(fā)者根據(jù)自己游戲的情況來定制自己的渲染管線塔沃,達(dá)到最好性能;
(3) 基于渲染管線的渲染策略蝠引,開發(fā)出對應(yīng)的Shader包;
完全從頭到尾定制一個渲染管線并不容易,幸運(yùn)的是Unity引擎為我們做好了輕量級的渲染管線蛀柴,滿足我們做手機(jī)游戲的絕大部分的需求螃概。我們只要使用就可以了,如何使用輕量級渲染管線名扛,這里我們已URP為例:
(1) 安裝URP的相關(guān)的Unity Package, 不同的Unity的版本可能URP的代碼版本不一樣谅年。
(2) 使用URP渲染管線來代替內(nèi)置的渲染管線。先創(chuàng)建一個渲染管線的Asset文件肮韧,配置好相關(guān)數(shù)據(jù)融蹂,創(chuàng)建成功后,在Grpahics下面的Scriptable Render Pipeline選擇這個Asset文件弄企,切換渲染管線成功超燃。系統(tǒng)會根據(jù)Asset文件的描述來創(chuàng)建出渲染管線出來。如圖:
(3) 創(chuàng)建角色拘领,場景意乓,創(chuàng)建材質(zhì)的時候,使用渲染URP渲染管線相關(guān)的Shader;
4: 輕量級渲染管線Shader 模板結(jié)構(gòu)
Unity可編程渲染管線(包括輕量級渲染管線)的Shader開發(fā)仍然使用的是ShaderLab的語法結(jié)構(gòu)约素,開發(fā)語言和普通的Shader開發(fā)不一樣,使用的是HLSL編程語言届良。同時有些渲染管線還支持Shader Graphic開發(fā)。作為程序員,我個人還是建議自己手寫代碼圣猎,比起生成的Shader的代碼,手寫代碼能減少冗余士葫,更高效。我們打開URP渲染管線里面 PBR Shader如下圖:
仍然是基于ShaderLab, 和普通的Shader結(jié)構(gòu)送悔,沒有區(qū)別慢显。
我們來看幾個重要的Pass, 體會一下和向前渲染管線的不同爪模。先來看主要的繪制Pass,處理光照計(jì)算的,正如紅線標(biāo)注的一樣荚藻,所有的光源在一個Pass里面計(jì)算完成屋灌。
看下陰影投射的Pass:
看下HLSL代碼,和Cg差不多应狱,所以學(xué)習(xí)的時候不用由心里負(fù)擔(dān), 打開LitForwardPass.hlsl,這個文件就是URP里面PBR Shader具體實(shí)現(xiàn)的代碼共郭。截圖如下,數(shù)據(jù)結(jié)構(gòu)這些和Cg沒有太大的差別侦香,如圖:
由于篇幅有限落塑,沒有辦法把Shader詳細(xì)代碼的講解一遍,為此我還提供了本文對應(yīng)的代碼與視頻講解(里面詳細(xì)講解了Shader結(jié)構(gòu))罐韩,需要的可以進(jìn)入unity學(xué)習(xí)交流小組來學(xué)習(xí)教程,并獲取課程源碼憾赁。 URP渲染管線效果截圖如下: