日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

extjs 渲染之前的方法_Unity通用渲染管线(URP)系列(十一)——后处理(Bloom)...

發(fā)布時(shí)間:2025/3/12 63 豆豆
生活随笔 收集整理的這篇文章主要介紹了 extjs 渲染之前的方法_Unity通用渲染管线(URP)系列(十一)——后处理(Bloom)... 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

200+篇教程總?cè)肟?#xff0c;歡迎收藏:

放牛的星星:[教程匯總+持續(xù)更新]Unity從入門到入墳——收藏這一篇就夠了?zhuanlan.zhihu.com本文重點(diǎn)內(nèi)容:
1、創(chuàng)建簡(jiǎn)單的post-FX棧
2、修改渲染后的圖像
3、需要的時(shí)候完成后處理的呈現(xiàn)
4、制作Bloom的效果

這是關(guān)于創(chuàng)建自定義腳本渲染管道的教程系列的第11部分。它增加了對(duì)后處理的支持,目前只支持bloom。

本教程是CatLikeCoding系列的一部分,原文地址見文章底部。

本教程使用Unity 2019.4.4f1制作。

發(fā)光吧!

1 Post-FX Stack

大多數(shù)情況下,渲染的圖像不會(huì)按原樣顯示。圖像經(jīng)過了后期處理,并獲得了各種效果(簡(jiǎn)稱FX)。常見的FX包括光暈,顏色分級(jí),景深,運(yùn)動(dòng)模糊和色調(diào)映射。這些FX作為堆棧應(yīng)用,有指定的順序,一個(gè)在另一個(gè)之上。在本教程中,我們將創(chuàng)建一個(gè)簡(jiǎn)單的post-FX棧,該棧最初僅支持Bloom。

1.1 設(shè)置資產(chǎn)

一個(gè)項(xiàng)目可能需要多個(gè)post-FX棧配置,因此我們首先創(chuàng)建一個(gè)PostFXSettings資產(chǎn)類型來存儲(chǔ)一個(gè)棧的設(shè)置。

在本教程中,我們將使用單個(gè)棧,方法是在RP上通過向CustomRenderPipelineAsset添加配置選項(xiàng)將其提供給RP,然后將其傳遞給RP的構(gòu)造函數(shù)。

然后,CustomRenderPipeline必須追蹤FX設(shè)置,并將它們與其他設(shè)置一起在渲染過程中傳遞給相機(jī)渲染器。

CameraRenderer.Render最初對(duì)設(shè)置不執(zhí)行任何操作,因?yàn)槲覀冞€沒有棧。

現(xiàn)在我們可以創(chuàng)建一個(gè)空的post-FX Setting資產(chǎn),并將其分配給管道資產(chǎn)。

分配 post FX Setting

1.2 棧對(duì)象

我們將為棧使用和Lighting、Shadows相同的方法。為它創(chuàng)建一個(gè)類,該類有Buffer,Context,Camera和post-FX settings,并使用公共Setup方法對(duì)其進(jìn)行初始化。

接下來,添加一個(gè)公共屬性以指示棧是否處于活動(dòng)狀態(tài),只有在有設(shè)置的情況下,情況才如此。想法是,如果未提供設(shè)置,則應(yīng)跳過后處理。

最后,我們需要一個(gè)公共的Render方法來渲染棧。通過使用適當(dāng)?shù)闹骱?jiǎn)單地繪制一個(gè)覆蓋整個(gè)圖像的矩形,即可對(duì)整個(gè)圖像應(yīng)用效果。現(xiàn)在我們沒有著色器,因此我們只需要復(fù)制到目前為止渲染的任何內(nèi)容到相機(jī)的幀緩沖區(qū)即可。這可以通過在命令緩沖區(qū)上調(diào)用Blit,并將源和目標(biāo)的標(biāo)識(shí)符傳遞給Blit來完成。這些標(biāo)識(shí)符可以以多種格式提供。我們使用整數(shù)作為源,并為其添加一個(gè)參數(shù),并使用BuiltinRenderTextureType.CameraTarget作為目標(biāo)。然后執(zhí)行并清除緩沖區(qū)。

本案例中,我們不需要手動(dòng)開始和結(jié)束緩沖區(qū)樣本,因?yàn)槲覀兛梢酝耆鎿Q目標(biāo)位置,因此不需要調(diào)用ClearRenderTarget。

1.3 使用棧

現(xiàn)在,CameraRenderer需要一個(gè)棧實(shí)例,并在Render中調(diào)用它的Setup,就像它對(duì)其Lighting對(duì)象所做的一樣。

到目前為止,我們始終直接渲染到攝像機(jī)的幀緩沖區(qū),該緩沖區(qū)既可以用于顯示,也可以用于配置的渲染紋理。我們沒有直接控制權(quán),只能寫入它們。因此,要為活動(dòng)棧提供源紋理,我們需要使用渲染紋理作為相機(jī)的中間幀緩沖區(qū)。獲取一個(gè)并將其設(shè)置為渲染目標(biāo)的方法類似于陰影貼圖,只是我們將使用RenderTextureFormat.Default格式。在清除渲染目標(biāo)之前執(zhí)行此操作。

如果我們有一個(gè)活動(dòng)棧,還可以添加一個(gè)Cleanup方法來釋放紋理。也可以將lighting的clearup移到那里。

在render的末尾,submitting之前調(diào)用clearup。如果棧處于活動(dòng)狀態(tài),則在此之前直接渲染棧。

此時(shí),結(jié)果看起來應(yīng)該沒有什么不同,但是增加了一個(gè)額外的繪制步驟,從中間幀復(fù)制到最終幀緩沖區(qū)。它在幀調(diào)試器中列為Draw Dynamic。

渲染 FX 棧

1.4 強(qiáng)制清除

當(dāng)繪制到中間幀緩沖區(qū)時(shí),我們的渲染器會(huì)填充有任意數(shù)據(jù)的紋理。幀調(diào)試器處于活動(dòng)狀態(tài)時(shí),你可以看到此信息。Unity確保幀調(diào)試器在每個(gè)幀的開始都獲得一個(gè)清理后的幀緩沖區(qū),但是當(dāng)渲染到我們自己的紋理時(shí),我們會(huì)避開它。通常,這會(huì)導(dǎo)致我們?cè)谇耙粠慕Y(jié)果之上進(jìn)行繪制,但這并不能一定保證。攝像機(jī)的清除標(biāo)志設(shè)置為天空盒還是純色都沒關(guān)系,因?yàn)槲覀儽WC可以完全覆蓋以前的數(shù)據(jù)。但是其他兩個(gè)選項(xiàng)不起作用。為防止出現(xiàn)隨機(jī)結(jié)果,除非使用天空盒,否則當(dāng)棧處于活動(dòng)狀態(tài)時(shí),請(qǐng)始終清除深度并清除顏色。

請(qǐng)注意,這會(huì)使得無法在不使用后FX堆棧的情況下,清除之前在另一個(gè)像機(jī)渲染結(jié)果上進(jìn)行渲染。有許多解決方法,但這超出了本教程的范圍。

1.5 Gizmos

目前,我們正在同時(shí)繪制所有g(shù)izmos,但是在FX前或者后渲染的控件之間存在一些區(qū)別。因此,讓我們將DrawGizmos方法一分為二。

然后我們可以在正確的時(shí)間在Render中繪制它們。

請(qǐng)注意,當(dāng)3D圖標(biāo)用于Gizmos時(shí),當(dāng)棧處于活動(dòng)狀態(tài)時(shí),它們將不再被對(duì)象遮擋。發(fā)生這種情況是因?yàn)閳?chǎng)景窗口依賴于我們沒有使用的原始幀緩沖區(qū)的深度數(shù)據(jù)。之后,我們將結(jié)合post FX i來介紹深度。

3D gizmos 有和沒有FX

1.6 自定義畫法

我們當(dāng)前使用的Blit方法會(huì)繪制一個(gè)四邊形網(wǎng)格(兩個(gè)三角形),該網(wǎng)格覆蓋了整個(gè)屏幕空間。但是我們只畫一個(gè)三角形就可以得到相同的結(jié)果,工作量少了一點(diǎn)。我們甚至不需要將單個(gè)三角形的網(wǎng)格發(fā)送到GPU,可以按程序生成它。

這有顯著的區(qū)別嗎?
這樣做的明顯好處是將頂點(diǎn)從六個(gè)減少到三個(gè)。但是,更重要的區(qū)別是,它消除了四邊形的兩個(gè)三角形相交處的對(duì)角線。由于GPU將片元并行地分成小塊,因此某些片元最終會(huì)沿三角形的邊緣造成浪費(fèi)。由于四邊形有兩個(gè)三角形,沿對(duì)角線的片元塊將渲染兩次,因此效率低下。除此之外,渲染單個(gè)三角形可以具有更好的本地緩存一致性。

減少重復(fù)渲染的塊

在我們的RP的Shaders文件夾中創(chuàng)建一個(gè)PostFXStackPasses.hlsl文件。我們將棧中的所有Pass放入其中。我在其中定義的第一件事是Varyings結(jié)構(gòu),該結(jié)構(gòu)僅需要包含剪輯空間位置和屏幕空間UV坐標(biāo)。

接下來,創(chuàng)建一個(gè)默認(rèn)的頂點(diǎn)Pass,僅將頂點(diǎn)標(biāo)識(shí)符作為參數(shù)。這是具有SV_VertexID語義的無符號(hào)整數(shù)uint。使用ID生成頂點(diǎn)位置和UV坐標(biāo)。X坐標(biāo)為-1,-1、3。Y坐標(biāo)為-1、3,-1。要使可見的UV坐標(biāo)覆蓋0–1范圍,請(qǐng)對(duì)U使用0、0、2,對(duì)V使用0、2、0。

覆蓋了剪輯空間的三角形

添加片元Pass并進(jìn)行簡(jiǎn)單的復(fù)制,使其最初返回UV坐標(biāo)以用于調(diào)試。

在同一文件夾中創(chuàng)建一個(gè)附帶的著色器文件。所有Pass均不使用任何剔除并忽略深度,因此我們可以將這些指令直接放在Subshader塊中。我們也總是包含Common和PostFXStackPasses文件。現(xiàn)在唯一的途徑就是使用我們創(chuàng)建的頂點(diǎn)和片元函數(shù)進(jìn)行復(fù)制。我們還可以使用Name指令為其命名,這在將同一著色器中的多個(gè)Pass組合在一起時(shí)非常方便,因?yàn)閹{(diào)試器會(huì)將其用作遍歷標(biāo)簽,而不是數(shù)字。最后,將其菜單項(xiàng)放在Hidden文件夾下,以便在為材質(zhì)選擇著色器時(shí)不顯示該菜單項(xiàng)。

簡(jiǎn)單地通過其設(shè)置將著色器手動(dòng)鏈接到我們的棧上。

分配 Post FX 著色器

但是渲染時(shí)我們需要材質(zhì),因此添加一個(gè)公共屬性,可以使用該屬性直接從設(shè)置資產(chǎn)中獲取材質(zhì)。我們將根據(jù)需要?jiǎng)?chuàng)建它,并將其設(shè)置為隱藏而不保存在項(xiàng)目中。同樣,由于材質(zhì)是按需創(chuàng)建的,因此無法與資產(chǎn)一起序列化。

由于通過名稱而不是數(shù)字來尋址Pass很方便,因此可以在PostFXStack中創(chuàng)建一個(gè)Pass枚舉,最初只包含Copy Pass。

現(xiàn)在我們可以定義自己的Draw方法。給它兩個(gè)RenderTargetIdentifier參數(shù)以指示應(yīng)該從何處繪制到何處,以及一個(gè)pass參數(shù)。在其中,通過_PostFXSource紋理使源可用,像以前一樣將目標(biāo)用作渲染目標(biāo),然后繪制三角形。我們通過使用未使用的矩陣,棧材質(zhì)和pass作為參數(shù)調(diào)用緩沖區(qū)上的DrawProcedural來做到這一點(diǎn)。之后又有兩個(gè)需要解決的問題。首先是我們要繪制的形狀,即MeshTopology.Triangles。第二個(gè)是我們想要多少個(gè)頂點(diǎn),單個(gè)三角形是三個(gè)。

最后,用我們自己的方法替換對(duì)Blit的調(diào)用。

1.7 不要總是應(yīng)用 FX

現(xiàn)在,我們應(yīng)該看到場(chǎng)景窗口中出現(xiàn)了屏幕空間UV坐標(biāo)。游戲窗口中也可以看到。刷新一次后,還可以在材質(zhì)預(yù)覽中,甚至在反射探針中看到。

反射探針 應(yīng)用了FX

我們的想法是將后FX應(yīng)用于適當(dāng)?shù)南鄼C(jī),而不是其他任何東西。可以通過檢查PostFXStack.Setup中是否有Game或Scene攝像機(jī)來強(qiáng)制執(zhí)行此操作。如果不是,我們將設(shè)置設(shè)為null,這將停用該相機(jī)的棧。

除此之外,還可以通過其工具欄中的效果下拉菜單在場(chǎng)景窗口中切換后處理。可以同時(shí)打開多個(gè)場(chǎng)景窗口,可以單獨(dú)啟用或禁用后期效果。為了支持此功能,請(qǐng)使用ApplySceneViewState方法為PostFXStack創(chuàng)建一個(gè)編輯器局部類,該方法在構(gòu)建中不執(zhí)行任何操作。它的編輯器版本檢查我們是否正在處理場(chǎng)景攝像機(jī),如果當(dāng)前繪制的場(chǎng)景視圖的狀態(tài)禁用了圖像效果,則禁用棧。

在Setup結(jié)束時(shí)調(diào)用此方法。

1.8 拷貝

通過使復(fù)制過程返回源顏色來完成棧。為此創(chuàng)建一個(gè)GetSource函數(shù),進(jìn)行采樣。我們將始終使用線性鉗位采樣器,以便我們可以明確聲明它。

我們最終將原始圖像取回來了,但是在某些情況下,通常是在場(chǎng)景窗口中,它是顛倒的。這取決于圖形API以及源和目標(biāo)的類型。發(fā)生這種情況是因?yàn)槟承﹫D形API的紋理V坐標(biāo)從頂部開始,而另一些圖形API的紋理V坐標(biāo)從底部開始。Unity通常會(huì)隱藏它,但是在涉及渲染紋理的所有情況下都不能這樣做。幸運(yùn)的是,Unity指示是否需要通過_ProjectionParams向量的X分量進(jìn)行手動(dòng)翻轉(zhuǎn),該向量應(yīng)在UnityInput中定義。

如果值為負(fù),我們需要翻轉(zhuǎn)DefaultPassVertex中的V坐標(biāo)。

2 Bloom

Bloom 的post效果用于使物體發(fā)光。這是物理學(xué)的基礎(chǔ),但是典型的Bloom效果是藝術(shù)而非現(xiàn)實(shí)的。不真實(shí)的發(fā)光非常明顯,也因此可以很好地證明了我們的后FX棧有效。在下一個(gè)教程中,討論HDR渲染時(shí),我們將看到更加逼真的Bloom。現(xiàn)在,我們的目標(biāo)是完成LDR光暈發(fā)光效果。

2.1 Bloom金字塔

Bloom表示顏色的散射,可以通過模糊圖像來完成。明亮的像素會(huì)滲入相鄰的較暗像素,因此看起來會(huì)發(fā)光。使紋理模糊的最簡(jiǎn)單,最快的方法是將其復(fù)制到寬度和高度一半的另一個(gè)紋理中。Copy Pass的每個(gè)樣本最終在四個(gè)源像素之間進(jìn)行采樣。通過雙線性濾波,可以平均2×2像素的塊。

雙線性下采樣4X4到2X2

此操作執(zhí)行一次只會(huì)模糊一點(diǎn)。因此,我們需要重復(fù)此過程,逐漸降低采樣率直至達(dá)到所需的水平,從而有效地構(gòu)建紋理金字塔。

帶有4個(gè)紋理的金字塔,每級(jí)維度減半

我們需要跟蹤棧中的紋理,但是有多少層取決于金字塔中有多少層,而這又取決于源圖像的大小。讓我們?cè)赑ostFXStack中最多定義16個(gè)級(jí)別,這足以將65,536×65,526的紋理一直縮小到單個(gè)像素。

為了跟蹤金字塔中的紋理,我們需要紋理標(biāo)識(shí)符。我們將使用屬性名稱_BloomPyramid0,_BloomPyramid1,依此類推。但是,我們不要明確地寫下所有這十六個(gè)名稱。相反,我們將在構(gòu)造函數(shù)方法中獲取標(biāo)識(shí)符,并且僅跟蹤第一個(gè)標(biāo)識(shí)符。之所以可行,是因?yàn)镾hader.PropertyToID只是簡(jiǎn)單地按照請(qǐng)求新屬性名稱的順序順序分配標(biāo)識(shí)符。我們只需要確保立即請(qǐng)求所有標(biāo)識(shí)符,因?yàn)閿?shù)字在應(yīng)用程序會(huì)話中是固定的,無論是在編輯器中還是在構(gòu)建中。

現(xiàn)在創(chuàng)建一個(gè)DoBloom方法,該方法將bloom效果應(yīng)用于給定源標(biāo)識(shí)符。首先將攝像機(jī)的像素寬度和高度減半,然后選擇默認(rèn)的渲染紋理格式。最初,我們將從源復(fù)制到金字塔中的第一個(gè)紋理。追蹤那些標(biāo)識(shí)符。

然后循環(huán)遍歷所有金字塔級(jí)別。每次迭代都首先檢查一個(gè)級(jí)別是否會(huì)退化。如果是,我們到此為止。如果未獲得新的渲染紋理,請(qǐng)復(fù)制到該紋理,使其成為新的源,增加目標(biāo),然后再次將尺寸減半。在循環(huán)外部聲明循環(huán)迭代器變量,稍后我們將需要它。

金字塔完成后,將最終結(jié)果復(fù)制到攝像機(jī)目標(biāo)。然后遞減迭代器并向后循環(huán),釋放我們要求的所有紋理。

現(xiàn)在,我們可以使用Bloom效果替換Render中的簡(jiǎn)單Copy。

2.2 可配置的Bloom

我們現(xiàn)在的模糊次數(shù)太多了,但最終結(jié)果幾乎是一致的。你可以通過框架調(diào)試器檢查中間步驟。但這些步驟作為結(jié)束似乎也沒有什么問題,因此讓我們可以盡早停止。

三次迭代后的下采樣

我們可以通過兩種方式做到這一點(diǎn)。首先,我們可以限制模糊迭代的次數(shù)。其次,我們可以將縮小比例限制設(shè)置為更高的值。通過在PostFXSettings內(nèi)添加帶有它們選項(xiàng)的BloomSettings配置結(jié)構(gòu)來支持這兩種方法。通過getter屬性使其公開可用。

默認(rèn)的Bloom設(shè)置

讓PostFXStack.DoBloom使用這些設(shè)置來限制自己。

限制下采樣次數(shù),三次和5次

2.3 高斯過濾

使用小型2×2濾波器進(jìn)行下采樣會(huì)產(chǎn)生非常塊狀的結(jié)果。通過使用更大的濾波器內(nèi)核(例如大約9×9高斯濾波器),可以大大提高效果。如果我們將其與雙線性下采樣相結(jié)合,我們會(huì)將其有效倍增至18×18。這就是Universal RP和HDRP發(fā)揮作用的原因。

盡管此操作混合了81個(gè)樣本,但它是可分離的,這意味著可以將其分為水平和垂直Pass,將單個(gè)行或列混合為九個(gè)樣本。因此,我們只需要采樣18次,但是每次迭代需要繪制兩次。

可分離的過濾器如何工作?
這是一個(gè)可以用對(duì)稱行向量乘以其轉(zhuǎn)置來創(chuàng)建的過濾器。

可分離的3X3過濾 和相關(guān)的權(quán)重

讓我們從水平Pass開始。在PostFXStackPasses中為其創(chuàng)建一個(gè)新的BloomHorizontalPassFragment函數(shù)。它累積了以當(dāng)前UV坐標(biāo)為中心的九個(gè)樣本行。我們還將同時(shí)下采樣,因此每個(gè)偏移步長(zhǎng)都是源紋理像素寬度的兩倍。從左側(cè)開始的樣本權(quán)重為0.01621622、0.05405405、0.12162162、0.19459459,然后為中心的權(quán)重為0.22702703,另一側(cè)的權(quán)重相反。

這些權(quán)重從何而來?
權(quán)重是從Pascal三角形得出的。對(duì)于適當(dāng)?shù)?×9高斯濾波器,我們選擇三角形的第9行,即1 8 28 56 70 56 28 81。但是,這使得在濾波器邊緣的樣本貢獻(xiàn)太弱而無法察覺, 因此,我們向下移至第十三行并切掉其邊緣,得出66 220 495 792 924 792 495 220220。這些數(shù)字的總和為4070,因此將每個(gè)數(shù)字除以得出最終權(quán)重。

還要為其添加一個(gè)Pass到PostFXStack著色器。我將其放在Copy Pass的上方,以使其保持字母順序。

再次以相同的順序?yàn)槠涮砑右粋€(gè)條目到PostFXStack.Pass枚舉。

現(xiàn)在,在DoBloom中進(jìn)行下采樣時(shí),可以使用Bloom-horizontal pass。

水平高斯 3和5次

限制,結(jié)果顯然是水平拉伸的,但是看起來很有希望。我們可以通過復(fù)制BloomHorizontalPassFragment,重命名并從行切換到列來創(chuàng)建垂直通道。我們?cè)诘谝粋€(gè)Pass中進(jìn)行了下采樣,但是這次我們保持相同的大小以完成高斯濾波,因此紋理像素大小的偏移量不應(yīng)增加一倍。

也添加Pass和枚舉項(xiàng)。從現(xiàn)在開始,我將不再顯示這些步驟。

現(xiàn)在,我們需要在每個(gè)金字塔等級(jí)的中間增加一個(gè)步驟,為此,我們還需要保留紋理標(biāo)識(shí)符。可以通過簡(jiǎn)單地將PostFXStack構(gòu)造函數(shù)中的循環(huán)限制加倍來實(shí)現(xiàn)。由于我們還沒有引入其他著色器屬性名稱,因此標(biāo)識(shí)符將全部按順序排列,否則將需要重新啟動(dòng)Unity。

現(xiàn)在,在DoBloom中,目標(biāo)標(biāo)識(shí)符必須從每個(gè)下采樣步驟開始,增加一個(gè),然后增加兩個(gè)。然后可以在中間放置紋理。水平繪制到中間,然后垂直繪制直到達(dá)到目標(biāo)。我們還需要釋放其他紋理,這是最簡(jiǎn)單的方法,即從上一個(gè)金字塔源向后工作。

水平到下一個(gè)級(jí)別 然后進(jìn)行垂直操作

完全的高斯,3和5次

現(xiàn)在,我們的下采樣濾波已經(jīng)完成,并且看起來比簡(jiǎn)單的雙線性濾波要好得多,但需要更多的紋理樣本。幸運(yùn)的是,通過使用雙線性濾波以適當(dāng)?shù)钠屏吭诟咚共蓸狱c(diǎn)之間進(jìn)行采樣,我們可以減少一些采樣量。這樣可以將9個(gè)采樣減少到5個(gè)。我們可以在BloomVerticalPassFragment中使用此技巧。偏移在兩個(gè)方向上分別為3.23076923和1.38461538,權(quán)重為0.07027027和0.31621622。

我們不能在BloomHorizontalPassFragment中執(zhí)行此操作,因?yàn)槲覀円呀?jīng)在該P(yáng)ass中使用了雙線性過濾來進(jìn)行下采樣。其九個(gè)樣本中的每個(gè)樣本平均2×2源像素。

2.4 疊加模糊

使用bloom金字塔的頂部作為最終圖像產(chǎn)生的統(tǒng)一的混合,看起來并不像任何發(fā)光的東西。我們可以通過逐步向上采樣,再向下采樣金字塔,在一張圖像中累積所有的層次來得到想要的結(jié)果。

疊加上采樣,恢復(fù)紋理

我們可以使用添加混合來組合兩個(gè)圖像,但是讓我們對(duì)所有通道使用相同的混合模式,而不是添加第二個(gè)源紋理。在PostFXStack中聲明它的標(biāo)識(shí)符。

然后,在完成DoBloom中的金字塔后,不再直接執(zhí)行最終的Draw。相反,釋放用于上一次迭代的水平繪制的紋理,并將目標(biāo)設(shè)置為用于水平繪制的紋理低一層。

當(dāng)循環(huán)返回時(shí),我們將在相反的方向上再次繪制每個(gè)迭代,并將每個(gè)級(jí)別的結(jié)果作為第二個(gè)來源。這只能發(fā)揮第一次的作用,因此我們需要提前停止一步。之后,以原始圖像作為輔助來源繪制到最終目標(biāo)上。

為了使它起作用,我們需要使用第二個(gè)源可用于著色器通道。

并引入一個(gè)新的bloom組合通道,以采樣并添加兩個(gè)紋理。和以前一樣,我只展示片元程序代碼,而不顯示新的著色器通道或新的枚舉項(xiàng)。

上采樣時(shí)使用新的Pass。

疊加上采樣,3次和5次

我們終于有了一個(gè)看起來一切都在發(fā)光的效果。但是我們的新方法只有在至少有兩次迭代的情況下才有效。如果最終只執(zhí)行一次迭代,則應(yīng)該跳過整個(gè)上采樣階段,而只需要釋放用于第一次水平Pass的紋理。

如果我們最終完全跳過bloom,我們就需要中止并執(zhí)行一個(gè)Copy來替代。

2.5 三線性上采樣

盡管高斯濾波器會(huì)產(chǎn)生平滑的結(jié)果,但在上采樣時(shí)我們?nèi)詴?huì)執(zhí)行雙線性濾波,這可能會(huì)使輝光看起來像塊狀。這在原始圖像中的收縮較高的地方(尤其是在運(yùn)動(dòng)時(shí))尤為明顯。

黑色背景上的白色輝光顯得塊狀化

我們可以通過切換到雙三次過濾來消除這些失真。對(duì)此沒有硬件支持,但是我們可以使用在Core RP Library的Filtering include文件中定義的SampleTexture2DBicubic函數(shù)。通過傳遞紋理和采樣器狀態(tài),UV坐標(biāo)以及交換了尺寸對(duì)的紋理像素尺寸矢量,使用它來創(chuàng)建自己的GetSourceBicubic函數(shù)。除此之外,它還具有一個(gè)用于最大紋理坐標(biāo)的參數(shù),該參數(shù)僅為1,其后是另一個(gè)未使用的參數(shù),該參數(shù)僅為零。

在bloom-combine傳遞中使用新功能,因此我們使用雙三次濾波來上采樣。

三線性上采樣返回平滑的輝光

三線性采樣產(chǎn)生更好的結(jié)果,但是需要四個(gè)加權(quán)的紋理樣本或一個(gè)樣本。因此,讓我們通過著色器布爾值將其設(shè)為可選。這對(duì)應(yīng)于Universal RP和HDRP的High Quality光暈切換。

為其添加一個(gè)切換選項(xiàng)到PostFXSettings.BloomSettings。

雙線性上采樣切換

在開始進(jìn)行上采樣之前,將其傳遞給PostFXStack.DoBloom中的GPU。

2.6 減半分辨率

由于所有紋理采樣和繪制,Bloom可能需要大量時(shí)間才能生成。降低成本的一種簡(jiǎn)單方法是以一半的分辨率生成它。由于效果很柔和,所以我們可以避免這種情況。這將改變效果的外觀,因?yàn)槲覀儗?shí)際上是在跳過第一次迭代。

首先,在決定跳過bloom時(shí),我們應(yīng)該提前一步考慮。降低限制加倍為初始檢查。

其次,我們需要為將要用作新起點(diǎn)的一半大小的圖像聲明紋理。它不是Bloom金字塔的一部分,因此我們將為其聲明新的標(biāo)識(shí)符。我們將其用于預(yù)過濾步驟,因此請(qǐng)適當(dāng)命名。

返回DoBloom,將源復(fù)制到預(yù)過濾紋理,并將其用于金字塔的開始,同時(shí)將寬度和高度也減半。上金字塔后,我們不需要預(yù)過濾紋理,因此可以在那時(shí)釋放它。

一半分辨率的Bloom,2次和4次

2.7 閾值

Bloom通常在藝術(shù)上用于僅使某些東西發(fā)光,但是我們的效果目前適用于所有對(duì)象,不管它有多亮。盡管從物理上講沒有意義,但是我們可以通過引入亮度閾值來限制影響效果的因素。

我們不能突然消除效果中的顏色,因?yàn)檫@會(huì)在預(yù)期會(huì)逐漸過渡的地方引入清晰的邊界。相反,我們將顏色乘以一個(gè)權(quán)重

其中b為其亮度,t 為配置閾值。我們將使用最大的顏色的RGB通道為b。當(dāng)閾值為0時(shí),結(jié)果總是1,這將保持顏色不變。隨著門檻的增加,體重曲線會(huì)向下彎曲,在b <= t 處為零。由于這條曲線的形狀,它被稱為膝蓋曲線。

閾值設(shè)置為0.25,0.5,0.75,和1

該曲線在某個(gè)角度處達(dá)到零,這意味著盡管過渡過程比夾具更平滑,但仍存在一個(gè)陡峭的截止點(diǎn)。這就是為什么它也被稱為硬膝蓋的原因。我們可以通過改變重量來控制膝蓋的形狀

并且K就是膝蓋,設(shè)置為0~1的滑動(dòng)區(qū)間。

閾值為1,膝蓋為0,,0.25,0.5,0.75,1

讓我們將閾值和拐點(diǎn)滑塊添加到PostFXSettings.BloomSettings中。我們將配置的閾值視為伽瑪值,因?yàn)樗谝曈X上更直觀,因此在將其發(fā)送到GPU時(shí),必須將其轉(zhuǎn)換為線性空間。我們將其設(shè)為開放式,即使閾值大于零將在此時(shí)消除所有顏色,因?yàn)槲覀儍H限于LDR。

我們將通過一個(gè)名為_BloomThreshold的向量將閾值發(fā)送到GPU。在PostFXStack中為其聲明標(biāo)識(shí)符。

我們可以計(jì)算權(quán)重函數(shù)的常數(shù)部分,并將其放入向量的四個(gè)分量中,以使著色器更簡(jiǎn)單:

我們將在新的預(yù)過濾器通道中使用它,該通道將替換DoBloom中的初始復(fù)制通道,從而在將圖像大小減半的同時(shí)將閾值應(yīng)用于2×2像素的平均值。

將閾值向量和一個(gè)將其應(yīng)用于顏色的函數(shù)添加到PostFXShaderPasses,然后是使用它的新的Pass函數(shù)。

四次迭代 閾值和Knee為0.5

2.8 強(qiáng)度

我們通過添加強(qiáng)度滑塊來控制光暈的整體強(qiáng)度來結(jié)束本教程。我們不會(huì)給它一個(gè)限制,因此可以根據(jù)需要將整個(gè)圖像放大。

沒有上限的強(qiáng)度設(shè)置

如果強(qiáng)度設(shè)置為零,我們可以跳過光暈,因此請(qǐng)?jiān)贒oBloom開始時(shí)進(jìn)行檢查。

否則,使用_BloomIntensity的新標(biāo)識(shí)符將強(qiáng)度傳遞給GPU。我們將在合并過程中使用它來加權(quán)低分辨率圖像,因此我們不需要?jiǎng)?chuàng)建額外的Pass。對(duì)于所有繪制(將最終繪制除去到相機(jī)目標(biāo)),將其設(shè)置為1。

現(xiàn)在,我們只需要將BloomCombinePassFragment中的低分辨率顏色乘以強(qiáng)度即可。

強(qiáng)度為0.5和5

下一章,介紹HDR。

本文翻譯自 Jasper Flick的系列教程

總結(jié)

以上是生活随笔為你收集整理的extjs 渲染之前的方法_Unity通用渲染管线(URP)系列(十一)——后处理(Bloom)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。