今天我們先講URP的Renderer Feature,Renderer Feature可讓我們向URP Renderer添加額外的渲染通道,支持我們進行Asset資產配置來重寫從而可以自定義渲染的順序、渲染的對象、材質等等。
我們先來新建一個Renderer Feature ,首先你得有一個或者新建一個URP工程,創建Universal Render Pipeline Asset同時會生成一個Universal Render Pipeline Asset_Renderer, 創建完成後我們把Universal Render Pipeline Asset導入到Graphics Settings中。
接著我們點擊生成的Renderer,然後Add Renderer Feature點Render Objects,我們就創建好一個Renderer Feature了。
我們在 Project 窗口中也可以查看,點擊渲染器旁邊的小三角,可以看到新建的Renderer Feature 已經是我們Renderer渲染器的子集(這裡Renderer Feature我們已經重命名為Toon Outline)。
我們可以看到 Render Objects 的 Renderer Feature 包含一些屬性;我們一個個過一下。
01 Name:首先是這個Feature的名字;
02 Event (事件):當Unity執行這個Renderer Feature 的時候,這個事件Event在通用渲染管線中的執行順序;
03 Filters:這個設置允許我們給這個Renderer Feature 去配置要渲染哪些對象;這裡面有兩個參數,一個是Queue,一個是Layer Mask。
Queue:這個Feature選擇渲染透明物體還是不透明物體;
Layer Mask:這個Feature選擇渲染哪個圖層中的對象;
04 Shader Passes Name:如果shader中的一個pass具有 LightMode Pass 這個標記的話,那我們的Renderer Feature僅處理 LightMode Pass Tag 等於這個Shader Passes Name的Pass。
05 Overrides:使用這個Renderer Feature 進行渲染時,這部分的設置可讓我們配置某些屬性進行重寫覆蓋。
Material:渲染對象時,Unity會使用該材質替換分配給它的材質。
Depth:選擇此選項可以指定這個Renderer Feature如何影響或使用深度緩衝區。此選項包含以下各項:
Write Depth:寫入深度,此選項定義渲染對象時這個Renderer Feature是否更新深度緩衝區。
Depth Test:深度測試,決定renderer feature是否渲染object的片元。Stencil:選中此複選框後,Renderer將處理模板緩衝區值。
Camera:選擇此選項可讓您覆蓋以下「攝像機」屬性:
Field of View:渲染對象時,渲染器功能使用此Field of View(視場),而不是在相機上指定的值。
Position Offset:渲染對象時,Renderer Feature將其移動此偏移量。Restore:選中此選項,在此Renderer Feature中執行渲染過程後,Renderer Feature將還原原始相機矩陣。實戰一:使用Renderer Feature來進行描邊
實戰是加深理論的最好途徑,所以接下來要進行實戰演練,我們來看下這些屬性的使用情況,做一個簡單的遊戲場景角色的描邊效果來展示下。
當然描邊的方法有很多種,這裡我們介紹的方法是先畫模型的背面,然後使其根據法線的方向產生一定的偏移量,這些偏移量就顯示為模型周圍的輪廓,然後我們對其進行用戶自定義的著色。
首先,我們是僅要為遊戲角色Character來進行描邊的操作,所以我們需要在Layer Masks上設置為Character Layer層;
然後我們創建Renderer Feature ,並將Name改為Toon Outline。
接著我們來看看Event這個屬性,它是決定我們渲染哪個階段,這裡我們選擇After Rendering Opaques,在渲染完不透明物體之後。
然後我們來看下Filters的兩個參數一個是Queue,一個是Layer Mask。Queue:我們創建的這個Feature選擇是渲染透明物體還是不透明物體,這裡我們選擇Opaques;Layer Mask:我們創建的這個Feature選擇是渲染哪個圖層中的對象;這裡當然是選擇我們的Character Layer。
最後我們看下Overrides中的Material參數將材質進行替換,以定義我們如何在Character Layer上渲染對象。(關於這裡的材質創建我使用的是Universal Rendering Examples 中的OutlineHull,Shader使用的是ToonBasicOutline,具體的連結見文末,這裡算是個伏筆,後面會帶大家使用URP 已經支持的Shader Graph來進行製作 )
到這裡的話,使用Renderer Feature 製作的描邊效果的流程就已經結束了。為了更進一步說明Renderer Feature中的Event 屬性對整個渲染的影響,我們嘗試將描邊的順序改為渲染的最後一步:後處理之後進行描邊處理,從而得到如下圖的效果。
實戰二:使用多Renderer Feature
來進行FPS遊戲攝像機FOV的修改
前面我們小試牛刀,演示了使用一個簡單的Renderer Feature 進行的描邊操作的功能;為了更深入一步了解Renderer Feature的作用以及各個屬性的意義,我們增加一點難度,這裡再演示一個案例。
這個案例要實現什麼效果呢?過去我們製作射擊類遊戲,經常要做的一件事情是這把槍用不同的FOV單獨渲染。如果槍不進行特殊處理,使用和場景相同的FOV去畫的話,畫出來會很窄,佔屏幕面積小,不美觀。如下圖所示;
所以過去製作FPS的遊戲經常要單獨畫槍,它的FOV可能會小一點,這樣它佔的屏幕空間會更大。在內置渲染管線Pipeline裡,我們要用二個相機,一個相機畫槍,一個相機畫場景,這樣可以設置不同的FOV即視角。但是這樣的問題是即使加入一個Camera什麼都不做,仍有很大的消耗。現在有了URP,我們就可以用一個Camera來解決了。
這裡面我使用了三個Renderer Feature去實現了這個效果。第一個Render Feature畫槍上不透明的部分,後面二個Render Feature畫半透明的部分比如一些玻璃冷凝管、液體。
和上一個案例我們僅作用於角色Character一樣, 這裡我們還是要新建一個layer,因為我們要僅針對於槍的部分去修改它的FOV(這裡我們設置Renderer Feature FOV是40,然後主場景相機的FOV是80),所以這裡我們創建First Person Objects Layer。如圖所示我們將Terraformer_1P_Rig Layer設置為First Person Objects。
值得注意的是在我們自己新建的這個FPSSetupP1的Renderer設置裡面(紅色大括號所示),其中Filtering屬性定義渲染器Renderer繪製哪些圖層。這塊渲染的是除槍以外的圖層,也就是我們定義的First Person Objects Layer以外的圖層,比如場景、UI、後期處理等,所以這裡的Filtering設置我們要忽略First Person Objects 這個層。如下圖所示:
因為我們要畫不透明物體,所以這塊我們需要對Stencil進行重寫覆蓋,這裡我們打上勾表示渲染器將處理模板緩衝區值。「Value」和「Compare Function」在這裡很重要,因為我們現有隻想在值等於0的情況下寫入像素,我們會將槍的Stencil值設為1。
說完了Renderer部分的設置,也就是渲染非槍的區域,我們來說下渲染槍的部分,也就是三個Renderer Feature。他們渲染的部分效果如下:很明顯的可以看到第一個Feature是畫槍不透明的部分,第二個Feature是畫的是與槍不透明部分重合的半透明處,第三個Feature畫的是與槍不透明部分不重合區域的半透明處。
我們來看第一個Renderer Feature,我們命名為GunOpaques,顧名思義就是畫槍上不透明的部分。
因為我們要畫整個不透明物體武器,我們要在URP Forward Opaque Pass之前執行,故這裡的Event 我們要設置為Before Rendering Opaques。另外Filters 這裡,因為我們需要畫不透明物體和畫First Person Objects層,所以這裡我們Queue和LayerMask設置為Opaque和First Person Objects。
我們不需要替換材質,所以Overrides中的Material這裡不用選擇,勾選Stencil並將Stencil的值設置為1,Compare Function設置為始終返回true,Replace的意思是將參考值1寫入緩衝區。FOV的值我們改為40;到這我們GunOpaques就設置完成了。
第二個Renderer Feature GunTransparents渲染與不透明部分重疊的武器的透明部分,有點繞口,如下圖所示:
我們來看下Renderer Feature的設置,因為我們是渲染透明物體,所以這裡的Event 我們要設置為After Rendering Transparents。Filters 這裡設置為Transparents,LayerMask為First Person Objects層。因為要畫在不透明物體上的(上一步中槍的不透明部分Stencil我們已經寫為1),所以這裡的Stencil的Value為1,Compare Function 為Equal。FOV 改為40。GunTransparents設置完成;
第三個Renderer Feature GunTransparentsOverlay渲染武器的透明部分,該部分與不透明部分不重疊,但無論深度如何,始終在場景上進行渲染。
這個與第二個Renderer Feature設置類似,但有一處得說下就是渲染武器的透明部分,而且該部分與不透明部分不重疊,所以這裡的Stencil的值沒有被在畫不透明物體的時候重寫為1,故這裡的值應該為0。另外無論深度如何,始終在場景上進行渲染,所以這裡的Depth Test 我們設置為Always。
最終的效果如下右圖所示:
講到這裡的話這個案例就講完了。我們使用Renderer Feature成功的解決了在內置渲染管線FPS遊戲中需要額外攝像機渲染武器的問題,我想通過這兩個Renderer Feature的案例大家已經熟悉如何在URP通用渲染管線中使用Renderer Feature了吧!
我在QQ開設了一個學習交流群,歡迎大家加入。任何與URP相關的問題,都可以在群裡@我哦。
群名稱:Unity URP學習交流群
下一期會帶大家手把手寫Scriptable Renderer Feature以及更多與URP相關的內容,歡迎大家來Unity社區關注我哦。
https://unity.cn/u/li-peng-peng-2?section=works&tab=article以下是本篇文章所用到的技術資料連結:
[1] URP手冊
https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@10.2/manual/index.html[2] URP官方案例
https://github.com/Unity-Technologies/UniversalRenderingExamples長按關注
第一時間了解Unity引擎動向,學習最新開發技巧