国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【unity基礎(chǔ)】關(guān)于學(xué)習(xí)通用渲染管線(UniversalRenderPipeline)入門級(jí)的分享筆記

這篇具有很好參考價(jià)值的文章主要介紹了【unity基礎(chǔ)】關(guān)于學(xué)習(xí)通用渲染管線(UniversalRenderPipeline)入門級(jí)的分享筆記。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、主要分享和學(xué)習(xí)的內(nèi)容

????????文章是學(xué)習(xí)入門級(jí)別的文章,定位偏向于個(gè)人學(xué)習(xí)筆記,文章內(nèi)有錯(cuò)誤的點(diǎn)希望大家理性指出,感謝各位。因?yàn)閁RP本身是一個(gè)比較雜的東西,涉及到的東西也非常的多,下面主要是對(duì)于Unity URP的創(chuàng)建、簡(jiǎn)單使用(資深級(jí)別使用起來可能會(huì)設(shè)計(jì)到渲染方方面面的知識(shí),各種渲染效果,后處理等等),相關(guān)概念,原理,源碼解析,以及URP自帶Shader腳本的解析(主要是Lit腳本)。

簡(jiǎn)單枚舉一下學(xué)習(xí)的內(nèi)容:
1.URP的概念,創(chuàng)建和使用
2.URP的運(yùn)行邏輯和源碼解析
3.URP自帶Shader腳本和Lit腳本涉及的渲染知識(shí)整理

二、URP的概念,創(chuàng)建和使用

1.URP的概念

I.URP是什么

URP全稱,Universal Render Pipeline 通用渲染管線,是SRP(Scriptable Render Pipeline,可編輯渲染管線)的一個(gè)模型,它的前身是LWRP(Light Weight Render Pipeline,輕量渲染管線),在Unity的2019.3版本中,正式將LWRP改名為URP,LWRP名字也正式退出了歷史的舞臺(tái)。URP主要是應(yīng)用在移動(dòng)端上面。

II.使用URP渲染管線的優(yōu)勢(shì)

可擴(kuò)展性
Unity中最早提出SRP就是為了提高渲染管線的可編輯性,能夠給用戶提供管線自定義的空間以致
滿足不同項(xiàng)目的需求。而URP是SRP的一個(gè)模型,本身就對(duì)功能進(jìn)行模塊化了。這樣我們可以添加不同的功能模塊來滿足對(duì)應(yīng)的需求。

性能對(duì)比
性能上最大的區(qū)別就是URP是單Pass前向渲染管線,而內(nèi)置管線是多Pass前向渲染管線。所謂的前向渲染,就是在渲染物體受點(diǎn)光光照的時(shí)候,分別對(duì)每個(gè)點(diǎn)光對(duì)該物體產(chǎn)生的影響進(jìn)行計(jì)算,最后將所有光的渲染結(jié)果相加得到最終物體的顏色。內(nèi)置管線的做法是,用多個(gè)pass來渲染光照,第一個(gè)pass只渲染主光源,然后多出來的光每個(gè)光用一個(gè)pass單獨(dú)渲染。這也是為什么我們?cè)谧鍪钟蔚臅r(shí)候很少會(huì)用點(diǎn)光源。因?yàn)閷?duì)于內(nèi)置管線來說,每多一盞光,整個(gè)場(chǎng)景的drawcall就會(huì)翻倍,這個(gè)性能開銷基本是無法接受的。
URP的做法則是,在一個(gè)pass當(dāng)中,對(duì)這個(gè)物體受到的所有光源通過一個(gè)for循環(huán)一次性計(jì)算。這么做的好處有:
一個(gè)物體的光照可以在一次DrawCall中計(jì)算完畢
省去了多個(gè)Pass的上下文切換以及光柵化等開銷
但是這么做的壞處也很明顯:
只支持1盞直光
單個(gè)物體最多支持4盞點(diǎn)光
單個(gè)相機(jī)最多支持16盞燈光
因此,有了URP之后,只要控制好點(diǎn)光的范圍,我們?cè)谑钟卫锩嬉部梢宰龆帱c(diǎn)光照明了,例如釋放一個(gè)火球照亮周圍物件,這在內(nèi)置管線里基本是可以放棄的功能

支持SRP Batch
在所有SRP管線中,都可以使用SRP Batcher,這個(gè)功能可以將沒有進(jìn)行靜態(tài)合并,也沒法通過Instancing渲染的使用相同Shader的物體,通過CBuffer去保存每個(gè)物體材質(zhì)球的參數(shù),進(jìn)而在不進(jìn)行SetPassCall的情況下完成繪制。這個(gè)功能的效果是,可以大幅降低相同DrawCall情況下單個(gè)DrawCall的開銷,當(dāng)這個(gè)功能開啟的時(shí)候,你會(huì)發(fā)現(xiàn),也許你的場(chǎng)景有500個(gè)DrawCall,但實(shí)際上SetPassCall只有不到100,在相同情況下的渲染性能是要高于內(nèi)置管線不少的。不過Shader要支持SRP Batcher還是有些條件的,詳細(xì)的大家去參考SRP Batcher的文檔吧。

容易對(duì)渲染功能的更新
打比方,我們使用內(nèi)置渲染管線的功能而且要更新內(nèi)置渲染管線的東西時(shí)候,需要對(duì)Unity版本的管線,但是我們使用URP的時(shí)候,只需要管線一下URP包就可以了。

2.Universal的安裝,創(chuàng)建流程記錄

步驟一,點(diǎn)擊Unity菜單欄的window,打開下面的Package Manager
通用渲染管線,unity,學(xué)習(xí),筆記
步驟二,打開Package Manager面板后搜索Universal RP,并且進(jìn)行安裝。等待安裝結(jié)束即可
通用渲染管線,unity,學(xué)習(xí),筆記
步驟三,點(diǎn)擊Unity菜單欄Assets->Create->Rendering->URP Asset(with Universal Renderer),點(diǎn)擊之后就可以創(chuàng)建出來了一個(gè)Asset文件和一個(gè)Data文件。關(guān)于Asset文件和Data文件的關(guān)系需要放到下面提一嘴。
通用渲染管線,unity,學(xué)習(xí),筆記
步驟四,點(diǎn)擊Unity菜單欄Project Setting。點(diǎn)擊打開Project Setting面板的Graphics,把上個(gè)步驟創(chuàng)建好的URP的Asset資源文件放到下面截圖的Scriptable Render Pipeline Setting上面,Unity會(huì)自動(dòng)生成Universal RP的Global Setting文件和內(nèi)置管線自帶的Shader不能用的時(shí)候就表明成功了。
通用渲染管線,unity,學(xué)習(xí),筆記
打開Framedebugger(window->analysis->framedebugger)就能看到對(duì)應(yīng)的調(diào)用接口和自定義管線了。
通用渲染管線,unity,學(xué)習(xí),筆記

3.Universal RP Asset和Universal RP Data

Universal RP Asset也就是拖拽進(jìn)Project Setting面板的Graphics選項(xiàng)里面的Scriptable Render Pipeline Settings的資源文件,它是URP管線資產(chǎn),也就是存放設(shè)置數(shù)據(jù)的地方可以進(jìn)行各種設(shè)置。通過Unity的官方文檔給出來的解釋,我們可以認(rèn)為Universal RP Asset是一個(gè)可編輯腳本的對(duì)象,其實(shí)是一個(gè)handler。比如說一個(gè)handler(Asset)打開陰影的設(shè)置,另外一個(gè)handler關(guān)閉陰影的設(shè)置,我們可以透過選擇不同的handler(Asset)來實(shí)現(xiàn)不同需求,比如說移動(dòng)端和PC端來說,移動(dòng)端的性能較弱,實(shí)時(shí)陰影的性能開銷高,那么就選擇關(guān)閉陰影的handler(Asset)放置到Scriptable Render Pipeline Setting設(shè)置中。

這里主要整理一下URP的Asset文件設(shè)置的東西,當(dāng)然這些東西可以通過Unity的URP文檔中去查詢。

I.Rendering項(xiàng)

這一項(xiàng)主要是設(shè)置控制渲染幀的核心部分。下面為該項(xiàng)設(shè)置的截圖
通用渲染管線,unity,學(xué)習(xí),筆記
Depth Texture 使URP可以創(chuàng)建_CameraDepthTexture。然后,URP為場(chǎng)景中所有攝像機(jī)都默認(rèn)使用此深度紋理??梢栽贑amera的Inspector中為單個(gè)攝像機(jī)覆蓋此項(xiàng)內(nèi)容。

Opaque Texture啟動(dòng)此選項(xiàng)可為場(chǎng)景中所有攝像機(jī)都創(chuàng)建一個(gè)_CameraOpaqueTexture作為默認(rèn)設(shè)置。此設(shè)置的功能很像內(nèi)置渲染管線中的GrabPass。Opaque Texture在URP渲染任何透明網(wǎng)格之前立即提供場(chǎng)景的快照。您可以在透明著色器使用它來創(chuàng)建毛玻璃、水折射或熱浪等效果。

Opaque Downsampling 將不透明紋理上的采樣模式設(shè)置為一下三個(gè)選項(xiàng)之一:
None:使用與攝像機(jī)相同的分辨率生成不透明通道的副本。
2x Bilinear:使用雙線性濾波生成二分之一分辨率圖像。
4x Box:使用盒狀濾波生成四分之一分辨率圖像。這會(huì)產(chǎn)生柔和模糊的副本。
4x Bilinear:使用雙線性濾波生成四分之一分辨率圖像。

Terrain Holes如果禁用此選項(xiàng),URP 會(huì)在您針對(duì) Unity Player 進(jìn)行構(gòu)建時(shí)移除所有地形孔洞著色器變體,從而減少構(gòu)建時(shí)間。

II.Quality項(xiàng)

通用渲染管線,unity,學(xué)習(xí),筆記
HDR啟用此選項(xiàng)可以默認(rèn)為場(chǎng)景中的每個(gè)攝像機(jī)以高動(dòng)態(tài)范圍 (HDR) 執(zhí)行渲染。使用 HDR 時(shí),圖像中最亮的部分可以大于 1。這提供了更廣泛的光強(qiáng)度,使光照看起來更逼真。有了它,即使在明亮的光線下,您仍然可以看到細(xì)節(jié)并獲得更少的飽和度。如果需要多種光照或使用泛光效果,這非常有用。如果目標(biāo)硬件是低端硬件,可以禁用此屬性以便跳過 HDR 計(jì)算,從而獲得更好的性能。

MSAA 默認(rèn)情況下,在渲染時(shí)為場(chǎng)景中的每個(gè)攝像機(jī)使用多重采樣抗鋸齒 (Multi Sample Anti-aliasing) 技術(shù)。這樣可以柔化幾何體的邊緣,使它們不會(huì)出現(xiàn)鋸齒狀或閃爍現(xiàn)象。在下拉菜單中,選擇每個(gè)像素使用的樣本數(shù):2x、4x 或 8x。選擇的樣本越多,對(duì)象邊緣越平滑。如果想跳過 MSAA 計(jì)算,或者在 2D 游戲中不需要此類計(jì)算,請(qǐng)選擇 Disabled。注意:在不支持 StoreAndResolve 存儲(chǔ)操作的移動(dòng)平臺(tái)上,如果在 URP 資源中選擇了 Opaque Texture,Unity 會(huì)在運(yùn)行時(shí)忽略 Anti Aliasing (MSAA) 屬性(如同 Anti Aliasing (MSAA) 設(shè)置為 Disabled 一樣)。

Render Scale 此滑動(dòng)條用于縮放渲染目標(biāo)分辨率(而不是當(dāng)前設(shè)備的分辨率)。如果出于性能原因要以較小的分辨率進(jìn)行渲染或需要升級(jí)渲染來提高質(zhì)量,請(qǐng)使用此屬性。這只會(huì)縮放游戲渲染。UI 渲染保留采用設(shè)備的原始分辨率。

Lighting
通用渲染管線,unity,學(xué)習(xí),筆記
這些設(shè)置會(huì)影響場(chǎng)景中的光源。
如果禁用其中某些設(shè)置,則會(huì)從著色器變量中剝離相關(guān)的關(guān)鍵字。如果您確定不會(huì)在游戲或應(yīng)用程序中使用某些設(shè)置,則可以禁用它們來提高性能并縮短構(gòu)建時(shí)間。

Main Light 這些設(shè)置會(huì)影響場(chǎng)景中的主方向光。為選擇此項(xiàng),可以在 Lighting Inspector 中將其指定為 Sun Source。如果不指定太陽光源 (Sun Source),URP 會(huì)將場(chǎng)景中最亮的方向光視為主光源。可以在 Pixel Lighting 和 None 選項(xiàng)之間進(jìn)行選擇。如果選擇 None,即使設(shè)置了太陽光源,URP 也不會(huì)渲染主光源。

** Cast Shadows** 選中此復(fù)選框可以使主光源在場(chǎng)景中投射陰影。

Shadow Resolution 此屬性可以控制主光源的陰影貼圖紋理的大小。高分辨率可提供更清晰、細(xì)節(jié)更多的陰影。如果內(nèi)存或渲染時(shí)間受限,請(qǐng)嘗試降低分辨率。

Additional Lights 在此處可以選擇附加的光源來補(bǔ)充主光源。選項(xiàng)包括 Per Vertex、Per Pixel 和 Disabled。
關(guān)于陰影故障排除我會(huì)另外寫一篇學(xué)習(xí)文章。

Per Object Limit 此滑動(dòng)條可以設(shè)置影響每個(gè)游戲?qū)ο蟮母郊庸庠磾?shù)量限制。

III.Shadows項(xiàng)

這些設(shè)置可讓您配置陰影的外觀和行為方式,并在視覺質(zhì)量和性能之間找到良好的平衡。
通用渲染管線,unity,學(xué)習(xí),筆記
Max Distance Unity 渲染陰影時(shí)與攝像機(jī)之間的最大距離。Unity 不會(huì)渲染超出此距離的陰影。
注意:此屬性采用公制單位,無論 Working Unit 屬性中的值如何,均是如此。

Working Unit Unity 度量陰影級(jí)聯(lián)距離的單位。

Depth Bias 使用此設(shè)置可減輕陰影暗斑。

Normal Bias 使用此設(shè)置可減輕陰影暗斑。

Cascade Count 陰影級(jí)聯(lián)的數(shù)量。使用陰影級(jí)聯(lián)可以避免靠近攝像機(jī)的陰影過于粗糙,并使陰影分辨率保持在合理的較低值。有關(guān)更多信息,請(qǐng)參閱陰影級(jí)聯(lián)頁面。增加級(jí)聯(lián)數(shù)會(huì)降低性能。級(jí)聯(lián)設(shè)置僅影響主光源。

Soft Shadows 選中此復(fù)選框可啟用對(duì)陰影貼圖的額外處理,以使它們看起來更平滑。
啟用后,Unity 使用以下陰影貼圖過濾方法:
桌面平臺(tái):5x5 帳篷過濾器,移動(dòng)平臺(tái):4 抽頭過濾器。
性能影響:高。
禁用此選項(xiàng)后,Unity 會(huì)使用默認(rèn)的硬件過濾方法對(duì)陰影貼圖進(jìn)行一次采樣。

IV.Post-processing項(xiàng)

此部分用于微調(diào)全局后期處理設(shè)置。
Post Processing 此復(fù)選框?yàn)楫?dāng)前 URP 資源開啟(選中復(fù)選框)或關(guān)閉(清除復(fù)選框)后期處理。
如果清除此復(fù)選框,Unity 會(huì)從構(gòu)建中排除后期處理著色器和紋理,除非以下條件之一成立:
構(gòu)建中的其他資源是指與后期處理相關(guān)的資源。
另一個(gè) URP 資源啟用了 Post Processing 屬性。

Post Process Data 該資源引用了供渲染器用于后期處理的著色器和紋理。
注意:只有高級(jí)自定義用例才需要更改此屬性。

Grading Mode 選擇要用于項(xiàng)目的顏色分級(jí)模式。
? High Dynamic Range:此模式最適合類似于電影制作工作流程的高精度分級(jí)。Unity 在色調(diào)映射之前應(yīng)用顏色分級(jí)。
? Low Dynamic Range:此模式遵循更經(jīng)典的工作流程。Unity 在色調(diào)映射之后應(yīng)用有限范圍的顏色分級(jí)。

LUT Size 設(shè)置通用渲染管線用于顏色分級(jí)的內(nèi)部和外部查找紋理 (LUT) 的大小。更大的大小提供更高的精度,但有潛在的性能和內(nèi)存使用成本。不能混合和搭配 LUT 大小,因此請(qǐng)?jiān)陂_始顏色分級(jí)過程之前確定好大小。
默認(rèn)值為 32,可以確保速度與質(zhì)量之間的良好平衡。

三、URP的運(yùn)行邏輯,原理和源碼解析記錄

1.關(guān)于SRP的自定義管線

在閱讀URP的代碼之前,需要對(duì)SRP進(jìn)行一遍熟悉。
首先我們可以通過一下代碼進(jìn)行SRP的Asset文件的創(chuàng)建

[CreateAssetMenu(menuName = "Rendering/Custom Render Pipeline")]
public class CustomRenderPipelineAsset : RenderPipelineAsset
{
    protected override RenderPipeline CreatePipeline()
    {
        return new CutomRenderPipeline();
    }
}

public class CutomRenderPipeline : RenderPipeline
{
    protected override void Render(ScriptableRenderContext context, Camera[] cameras)
    {
        
    }
}

創(chuàng)建好以上的兩個(gè)腳本之后,就可以直接創(chuàng)建一個(gè)CustomRenderPipeline的一個(gè)Asset文件了,點(diǎn)擊Unity的工具欄里面的Assets/Create/Rendering/CustomRenderPipeline進(jìn)行對(duì)Asset文件進(jìn)行創(chuàng)建,創(chuàng)建好再把創(chuàng)建好的Asset文件配置到Project Settings面板的Graphics選項(xiàng)里面的Scriptable Render Pipeline Settings里面。如下圖:
通用渲染管線,unity,學(xué)習(xí),筆記
切換Scriptable Render Pipeline Settings成功之后,Unity的Scene面板和Game面板什么都沒有就說明切換成功了,這個(gè)時(shí)候需要我們?nèi)ゾ帉懸幌翪utomRenderPipeline 腳本里面的Render方法,對(duì)渲染指令進(jìn)行提交等操作?,F(xiàn)在我們看一下CutomRenderPipeline重寫的Render方法,參數(shù)為ScriptableRenderContext和Camera數(shù)組,其實(shí)我可以理解為這里的ScriptableRenderContext 是一個(gè)配置,Camera數(shù)組里面的所有相機(jī)都會(huì)使用ScriptableRenderContext的對(duì)象進(jìn)行渲染流程。更改CutomRenderPipeline的Render方法之后,代碼如下:

public class CutomRenderPipeline : RenderPipeline
{
    protected override void Render(ScriptableRenderContext context, Camera[] cameras)
    {
        //把當(dāng)前攝像機(jī)的屬性設(shè)置到全局的Shader屬性中(比如view矩陣,project矩陣等數(shù)據(jù))
        context.SetupCameraProperties(cameras[0]);
        
        //配置完攝像機(jī)屬性后,利用攝像機(jī)屬性對(duì)天空盒子的繪制
        context.DrawSkybox(cameras[0]);
        
        //把當(dāng)前進(jìn)行過的命令進(jìn)行一次提交
        context.Submit();
    }
}

這樣我們就能把天空盒子給繪制出來了。
通用渲染管線,unity,學(xué)習(xí),筆記

2.關(guān)于CommandBuffer

CommandBuffer->命令緩沖,其實(shí)CommandBuffer對(duì)象就是用來收集CPU向GPU發(fā)送的渲染指令,把需要進(jìn)行的指令在一個(gè)合適的時(shí)間點(diǎn)里面對(duì)GPU進(jìn)行發(fā)送。CommandBuffer的對(duì)象一般是通過CommandBufferPool進(jìn)行實(shí)例化的,這里稍微修改一下CustomPipeline的Render方法,代碼如下:

public class CutomRenderPipeline : RenderPipeline
{
    private string m_commandBufferName = "我是一個(gè)測(cè)試用的CommandBuffer";
    protected override void Render(ScriptableRenderContext context, Camera[] cameras)
    {
        CommandBuffer cmd = CommandBufferPool.Get(m_commandBufferName);
        //把當(dāng)前攝像機(jī)的屬性設(shè)置到全局的Shader屬性中(比如view矩陣,project矩陣等數(shù)據(jù))
        context.SetupCameraProperties(cameras[0]);
        //對(duì)RT的深度緩存,顏色緩存進(jìn)行清理
        cmd.ClearRenderTarget(true,true,Color.clear);
        //執(zhí)行buffer
        context.ExecuteCommandBuffer(cmd);
        //清理
        cmd.Clear();
        //配置完攝像機(jī)屬性后,利用攝像機(jī)屬性對(duì)天空盒子的繪制
        context.DrawSkybox(cameras[0]);
        //把當(dāng)前進(jìn)行過的命令進(jìn)行一次提交
        context.Submit(); 
    }
}

上面僅僅是使用CommandBuffer對(duì)象進(jìn)行了清理render target原理顏色上的清理。

3.繪制當(dāng)前相機(jī)觀察的物體

下面會(huì)對(duì)場(chǎng)景上的物體進(jìn)行渲染處理,我們首先得對(duì)攝像機(jī)不能看到的東西進(jìn)行剔除,雖然GPU也會(huì)方面剔除,在程序這邊剔除能減少一下CPU和GPU之間的通訊帶寬壓力,故編寫如下代碼

private bool Cull(ScripttableRenderContext context,Camera camera){
    if(camera.tryGetCullingParameters(out ScriptableCullingParameters p)){
        m_cullingResults = context.Cull(ref p);
        return true;
    }
    
    return false;
}

修改后CustomRenderPipeline類的整體代碼為

public class CutomRenderPipeline : RenderPipeline
{
    private string m_commandBufferName = "我是一個(gè)測(cè)試用的CommandBuffer";
    private static ShaderTagId m_unlitShaderTagId = new ShaderTagId("SRPDefaultUnlit");
    private CullingResults m_cullingResults;

    protected override void Render(ScriptableRenderContext context, Camera[] cameras)
    {
        if (!Cull(context, cameras[0]))
        {
            return;
        }
        Setup(context,cameras[0]);
        DrawVisibleGeometry(context, cameras[0]);
        DrawSkyBox(context,cameras[0]);
        context.Submit();
    }

    private bool Cull(ScriptableRenderContext context, Camera camera)
    {
        if (camera.TryGetCullingParameters(out ScriptableCullingParameters p))
        {
            m_cullingResults = context.Cull(ref p);
            return true;
        }

        return false;
    }

    private void Setup(ScriptableRenderContext context, Camera camera)
    {
        context.SetupCameraProperties(camera);
        CommandBuffer cmd = CommandBufferPool.Get(m_commandBufferName);
        cmd.ClearRenderTarget(true, true, Color.clear);
        context.ExecuteCommandBuffer(cmd);
        cmd.Clear();
    }

    //繪制圖像
    private void DrawVisibleGeometry(ScriptableRenderContext context, Camera camera)
    {
        var sortingSetting = new SortingSettings(camera);
        var drawingSetting = new DrawingSettings(m_unlitShaderTagId, sortingSetting);
        var filteringSetting = new FilteringSettings(RenderQueueRange.all);
        context.DrawRenderers(m_cullingResults, ref drawingSetting, ref filteringSetting);  
    }
    
    //繪制天空盒子
    private void DrawSkyBox(ScriptableRenderContext context, Camera camera)
    {
        context.DrawSkybox(camera);
    }
}

由上面的代碼,因?yàn)檫@個(gè)時(shí)候點(diǎn)擊打開Frame Debug,發(fā)現(xiàn)確實(shí)會(huì)對(duì)物體進(jìn)行了渲染。
通用渲染管線,unity,學(xué)習(xí),筆記
但是這里發(fā)現(xiàn)物體的材質(zhì)Shader出現(xiàn)物體了。
通用渲染管線,unity,學(xué)習(xí),筆記
這是因?yàn)槲疑厦娴拇a選擇使用SRPDefaultUnlit的pass進(jìn)行著色,而因?yàn)榘惭b的URP的包,所以目前場(chǎng)景默認(rèn)使用的材質(zhì)都是Lit,Lit的pass的名字叫ForwardLit,因?yàn)槟壳耙褂肧PRDefaultUnlit進(jìn)行著色的話,需要我們重新制作一個(gè)材質(zhì),那就是,我們選擇無光照的Color/Unlit即可。如下兩張圖:
通用渲染管線,unity,學(xué)習(xí),筆記
通用渲染管線,unity,學(xué)習(xí),筆記
到這里SRP腳本就完成了簡(jiǎn)單的編寫學(xué)習(xí)。當(dāng)然更詳細(xì)的可以去參考Catlike Coding里面查看,里面說明更加詳細(xì),會(huì)更加詳細(xì)說明多相機(jī)處理,多個(gè)層級(jí)剔除,半透明渲染和不透明渲染等等的說明介紹。

3.慢慢剖析URP運(yùn)行邏輯和原理

這一小節(jié)主要是記錄一下個(gè)人在閱讀URP源代碼的時(shí)候的一些心得。
先來點(diǎn)看開一下Unity下載的包,里面有Editor文件和Runtime文件還有其他的shader文件、shader庫等等。其實(shí)這里主要是查看一下Runtime文件里面的代碼,Editor其實(shí)是對(duì)Unity進(jìn)行自定義編輯進(jìn)行擴(kuò)展的代碼。
通用渲染管線,unity,學(xué)習(xí),筆記
在啟動(dòng)游戲之后打開Frame Debuger,會(huì)看到我抓了一幀之后他所執(zhí)行的東西
通用渲染管線,unity,學(xué)習(xí),筆記
我們可以看到我們只有一個(gè)主相機(jī)所以我們的URP執(zhí)行了主相機(jī)相關(guān)的渲染命令,添加另外一個(gè)相機(jī)的時(shí)候會(huì)發(fā)現(xiàn)URP會(huì)多執(zhí)行另外一個(gè)攝像機(jī)的渲染命令,這里肯定是對(duì)所有相機(jī)都執(zhí)行了一次遍歷。首先,我們?cè)诘诙?jié)簡(jiǎn)單的學(xué)習(xí)了一下SRP擴(kuò)展的編寫,我們首先找到URP里面繼承了RenderPipeline的類,因?yàn)榛旧献远x渲染管線以繼承RenderPipelineAsset為入口創(chuàng)建RenderPipeline類的子類對(duì)象,再通過重寫Render方法去進(jìn)行提交渲染指令。這里我們先找到UniversalRenderPipelineAsset類,再看看里面的CreatePipeline()方法如下:

protected override RenderPipeline CreatePipeline()
        {
            if (m_RendererDataList == null)
                m_RendererDataList = new ScriptableRendererData[1];

            // If no default data we can't create pipeline instance
            if (m_RendererDataList[m_DefaultRendererIndex] == null)
            {
                // If previous version and current version are miss-matched then we are waiting for the upgrader to kick in
                if (k_AssetPreviousVersion != k_AssetVersion)
                    return null;

                if (m_RendererDataList[m_DefaultRendererIndex].GetType().ToString()
                    .Contains("Universal.ForwardRendererData"))
                    return null;

                Debug.LogError(
                    $"Default Renderer is missing, make sure there is a Renderer assigned as the default on the current Universal RP asset:{UniversalRenderPipeline.asset.name}",
                    this);
                return null;
            }

            DestroyRenderers();
            var pipeline = new UniversalRenderPipeline(this);
            CreateRenderers();

            // Blitter can only be initialized after renderers have been created and ResourceReloader has been
            // called on potentially empty shader resources
            foreach (var data in m_RendererDataList)
            {
                if (data is UniversalRendererData universalData)
                {
                    Blitter.Initialize(universalData.shaders.coreBlitPS, universalData.shaders.coreBlitColorAndDepthPS);
                    break;
                }
            }

            return pipeline;
        }

可以看到里面都是一些獲取UniversalURP data的一些操作。這里往下查看一下創(chuàng)建的UniversalRenderPipeline,主要是再看這個(gè)方法的Render方法都做了些什么操作。

#if UNITY_2021_1_OR_NEWER
        /// <inheritdoc/>
        protected override void Render(ScriptableRenderContext renderContext, List<Camera> cameras)
#else
        /// <inheritdoc/>
        protected override void Render(ScriptableRenderContext renderContext, Camera[] cameras)
#endif
        {
#if RENDER_GRAPH_ENABLED
            useRenderGraph = asset.enableRenderGraph;
#else
            useRenderGraph = false;
#endif

            SetHDRState(cameras);

            // When HDR is active we render UI overlay per camera as we want all UI to be calibrated to white paper inside a single pass
            // for performance reasons otherwise we render UI overlay after all camera
            SupportedRenderingFeatures.active.rendersUIOverlay = HDROutputIsActive();

            // TODO: Would be better to add Profiling name hooks into RenderPipelineManager.
            // C#8 feature, only in >= 2020.2
            using var profScope = new ProfilingScope(null, ProfilingSampler.Get(URPProfileId.UniversalRenderTotal));

#if UNITY_2021_1_OR_NEWER
            using (new ProfilingScope(null, Profiling.Pipeline.beginContextRendering))
            {
                BeginContextRendering(renderContext, cameras);
            }
#else
            using (new ProfilingScope(null, Profiling.Pipeline.beginFrameRendering))
            {
                BeginFrameRendering(renderContext, cameras);
            }
#endif

            GraphicsSettings.lightsUseLinearIntensity = (QualitySettings.activeColorSpace == ColorSpace.Linear);
            GraphicsSettings.lightsUseColorTemperature = true;
            GraphicsSettings.defaultRenderingLayerMask = k_DefaultRenderingLayerMask;
            SetupPerFrameShaderConstants();
            XRSystem.SetDisplayMSAASamples((MSAASamples)asset.msaaSampleCount);

#if UNITY_EDITOR
            // We do not want to start rendering if URP global settings are not ready (m_globalSettings is null)
            // or been deleted/moved (m_globalSettings is not necessarily null)
            if (m_GlobalSettings == null || UniversalRenderPipelineGlobalSettings.instance == null)
            {
                m_GlobalSettings = UniversalRenderPipelineGlobalSettings.Ensure();
                if(m_GlobalSettings == null) return;
            }
#endif

#if DEVELOPMENT_BUILD || UNITY_EDITOR
            if (DebugManager.instance.isAnyDebugUIActive)
                UniversalRenderPipelineDebugDisplaySettings.Instance.UpdateFrameTiming();
#endif

            SortCameras(cameras);
#if UNITY_2021_1_OR_NEWER
            for (int i = 0; i < cameras.Count; ++i)
#else
            for (int i = 0; i < cameras.Length; ++i)
#endif
            {
                var camera = cameras[i];
                if (IsGameCamera(camera))
                {
                    RenderCameraStack(renderContext, camera);
                }
                else
                {
                    using (new ProfilingScope(null, Profiling.Pipeline.beginCameraRendering))
                    {
                        BeginCameraRendering(renderContext, camera);
                    }
#if VISUAL_EFFECT_GRAPH_0_0_1_OR_NEWER
                    //It should be called before culling to prepare material. When there isn't any VisualEffect component, this method has no effect.
                    VFX.VFXManager.PrepareCamera(camera);
#endif
                    UpdateVolumeFramework(camera, null);

                    RenderSingleCameraInternal(renderContext, camera);

                    using (new ProfilingScope(null, Profiling.Pipeline.endCameraRendering))
                    {
                        EndCameraRendering(renderContext, camera);
                    }
                }
            }

            s_RenderGraph.EndFrame();

#if UNITY_2021_1_OR_NEWER
            using (new ProfilingScope(null, Profiling.Pipeline.endContextRendering))
            {
                EndContextRendering(renderContext, cameras);
            }
#else
            using (new ProfilingScope(null, Profiling.Pipeline.endFrameRendering))
            {
                EndFrameRendering(renderContext, cameras);
            }
#endif

#if ENABLE_SHADER_DEBUG_PRINT
            ShaderDebugPrintManager.instance.EndFrame();
#endif
        }

根據(jù)上面代碼首先對(duì)HDR的狀態(tài)進(jìn)行設(shè)置,進(jìn)行一些狀態(tài)上的設(shè)置。Render最核心的內(nèi)容無非就是BeginRender(開始渲染)—>遍歷攝像機(jī)數(shù)組---->EndRendering(結(jié)束渲染)
而遍歷攝像機(jī)里面主要又是把主相機(jī)和堆疊相機(jī)分開處理(堆疊相機(jī)可以看下面相關(guān)的資料官方的手冊(cè)描述的很清楚),如果是堆疊相機(jī)就正常走完流程 BeginCamera -> RenderingCamera ->EndCamera,RenderingCamera 這過程基本上都是發(fā)生在RenderCameraStack方法里面,這里主要是研究一下攝像機(jī)內(nèi)部循環(huán)里面這段代碼判斷。上面這段代碼可以看到,只要是游戲的相機(jī)基本上都會(huì)進(jìn)入RenderCameraStack方法里面,下面是RenderCameraStack方法代碼片段,下面主要要做的東西基本是找到堆疊相機(jī)的最后一個(gè)相機(jī),讓相機(jī)堆疊里面的最后一個(gè)相機(jī)為最終輸出屏幕的相機(jī),其他的相機(jī)都輸出到,毫無疑問里面底層都是使用CommandBuff收集命令,通過CommadBuff和Context提交命令,使用一個(gè)RT放前面相機(jī)的輸入顏色,最終把最后一個(gè)相機(jī)作為輸出的最終相機(jī)。

/// <summary>
        /// Renders a camera stack. This method calls RenderSingleCamera for each valid camera in the stack.
        /// The last camera resolves the final target to screen.
        /// </summary>
        /// <param name="context">Render context used to record commands during execution.</param>
        /// <param name="camera">Camera to render.</param>
        static void RenderCameraStack(ScriptableRenderContext context, Camera baseCamera)
        {
            using var profScope = new ProfilingScope(null, ProfilingSampler.Get(URPProfileId.RenderCameraStack));

            baseCamera.TryGetComponent<UniversalAdditionalCameraData>(out var baseCameraAdditionalData);

            // Overlay cameras will be rendered stacked while rendering base cameras
            if (baseCameraAdditionalData != null && baseCameraAdditionalData.renderType == CameraRenderType.Overlay)
                return;

            // Renderer contains a stack if it has additional data and the renderer supports stacking
            // The renderer is checked if it supports Base camera. Since Base is the only relevant type at this moment.
            var renderer = baseCameraAdditionalData?.scriptableRenderer;
            bool supportsCameraStacking = renderer != null && renderer.SupportsCameraStackingType(CameraRenderType.Base);
            List<Camera> cameraStack = (supportsCameraStacking) ? baseCameraAdditionalData?.cameraStack : null;

            bool anyPostProcessingEnabled = baseCameraAdditionalData != null && baseCameraAdditionalData.renderPostProcessing;
            int rendererCount = asset.m_RendererDataList.Length;

            // We need to know the last active camera in the stack to be able to resolve
            // rendering to screen when rendering it. The last camera in the stack is not
            // necessarily the last active one as it users might disable it.
            int lastActiveOverlayCameraIndex = -1;
            if (cameraStack != null)
            {
                var baseCameraRendererType = baseCameraAdditionalData?.scriptableRenderer.GetType();
                bool shouldUpdateCameraStack = false;

                cameraStackRequiresDepthForPostprocessing = false;

                for (int i = 0; i < cameraStack.Count; ++i)
                {
                    Camera currCamera = cameraStack[i];
                    if (currCamera == null)
                    {
                        shouldUpdateCameraStack = true;
                        continue;
                    }

                    if (currCamera.isActiveAndEnabled)
                    {
                        currCamera.TryGetComponent<UniversalAdditionalCameraData>(out var data);

                        // Checking if the base and the overlay camera is of the same renderer type.
                        var currCameraRendererType = data?.scriptableRenderer.GetType();
                        if (currCameraRendererType != baseCameraRendererType)
                        {
                            Debug.LogWarning("Only cameras with compatible renderer types can be stacked. " +
                                             $"The camera: {currCamera.name} are using the renderer {currCameraRendererType.Name}, " +
                                             $"but the base camera: {baseCamera.name} are using {baseCameraRendererType.Name}. Will skip rendering");
                            continue;
                        }

                        var overlayRenderer = data.scriptableRenderer;
                        // Checking if they are the same renderer type but just not supporting Overlay
                        if ((overlayRenderer.SupportedCameraStackingTypes() & 1 << (int)CameraRenderType.Overlay) == 0)
                        {
                            Debug.LogWarning($"The camera: {currCamera.name} is using a renderer of type {renderer.GetType().Name} which does not support Overlay cameras in it's current state.");
                            continue;
                        }

                        if (data == null || data.renderType != CameraRenderType.Overlay)
                        {
                            Debug.LogWarning($"Stack can only contain Overlay cameras. The camera: {currCamera.name} " +
                                             $"has a type {data.renderType} that is not supported. Will skip rendering.");
                            continue;
                        }

                        cameraStackRequiresDepthForPostprocessing |= CheckPostProcessForDepth();

                        anyPostProcessingEnabled |= data.renderPostProcessing;
                        lastActiveOverlayCameraIndex = i;
                    }
                }
                if (shouldUpdateCameraStack)
                {
                    baseCameraAdditionalData.UpdateCameraStack();
                }
            }

            // Post-processing not supported in GLES2.
            anyPostProcessingEnabled &= SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLES2;

            bool isStackedRendering = lastActiveOverlayCameraIndex != -1;

            // Prepare XR rendering
            var xrActive = false;
            var xrRendering = baseCameraAdditionalData?.allowXRRendering ?? true;
            var xrLayout = XRSystem.NewLayout();
            xrLayout.AddCamera(baseCamera, xrRendering);

            // With XR multi-pass enabled, each camera can be rendered multiple times with different parameters
            foreach ((Camera _, XRPass xrPass) in xrLayout.GetActivePasses())
            {
                if (xrPass.enabled)
                {
                    xrActive = true;
                    UpdateCameraStereoMatrices(baseCamera, xrPass);
                }


                using (new ProfilingScope(null, Profiling.Pipeline.beginCameraRendering))
                {
                    BeginCameraRendering(context, baseCamera);
                }
                // Update volumeframework before initializing additional camera data
                UpdateVolumeFramework(baseCamera, baseCameraAdditionalData);
                InitializeCameraData(baseCamera, baseCameraAdditionalData, !isStackedRendering, out var baseCameraData);
                RenderTextureDescriptor originalTargetDesc = baseCameraData.cameraTargetDescriptor;

#if ENABLE_VR && ENABLE_XR_MODULE
                if (xrPass.enabled)
                {
                    baseCameraData.xr = xrPass;

                    // Helper function for updating cameraData with xrPass Data
                    // Need to update XRSystem using baseCameraData to handle the case where camera position is modified in BeginCameraRendering
                    UpdateCameraData(ref baseCameraData, baseCameraData.xr);

                    // Handle the case where camera position is modified in BeginCameraRendering
                    xrLayout.ReconfigurePass(baseCameraData.xr, baseCamera);
                    XRSystemUniversal.BeginLateLatching(baseCamera, baseCameraData.xrUniversal);
                }
#endif
                // InitializeAdditionalCameraData needs to be initialized after the cameraTargetDescriptor is set because it needs to know the
                // msaa level of cameraTargetDescriptor and XR modifications.
                InitializeAdditionalCameraData(baseCamera, baseCameraAdditionalData, !isStackedRendering, ref baseCameraData);

#if VISUAL_EFFECT_GRAPH_0_0_1_OR_NEWER
                //It should be called before culling to prepare material. When there isn't any VisualEffect component, this method has no effect.
                VFX.VFXManager.PrepareCamera(baseCamera);
#endif
#if ADAPTIVE_PERFORMANCE_2_0_0_OR_NEWER
                if (asset.useAdaptivePerformance)
                    ApplyAdaptivePerformance(ref baseCameraData);
#endif
                // update the base camera flag so that the scene depth is stored if needed by overlay cameras later in the frame
                baseCameraData.postProcessingRequiresDepthTexture |= cameraStackRequiresDepthForPostprocessing;

                RenderSingleCamera(context, ref baseCameraData, anyPostProcessingEnabled);
                using (new ProfilingScope(null, Profiling.Pipeline.endCameraRendering))
                {
                    EndCameraRendering(context, baseCamera);
                }

                // Late latching is not supported after this point
                if (baseCameraData.xr.enabled)
                    XRSystemUniversal.EndLateLatching(baseCamera, baseCameraData.xrUniversal);

                if (isStackedRendering)
                {
                    for (int i = 0; i < cameraStack.Count; ++i)
                    {
                        var currCamera = cameraStack[i];
                        if (!currCamera.isActiveAndEnabled)
                            continue;

                        currCamera.TryGetComponent<UniversalAdditionalCameraData>(out var currAdditionalCameraData);
                        // Camera is overlay and enabled
                        if (currAdditionalCameraData != null)
                        {
                            // Copy base settings from base camera data and initialize initialize remaining specific settings for this camera type.
                            CameraData overlayCameraData = baseCameraData;
                            overlayCameraData.camera = currCamera;
                            overlayCameraData.baseCamera = baseCamera;

                            UpdateCameraStereoMatrices(currAdditionalCameraData.camera, xrPass);

                            using (new ProfilingScope(null, Profiling.Pipeline.beginCameraRendering))
                            {
                                BeginCameraRendering(context, currCamera);
                            }
#if VISUAL_EFFECT_GRAPH_0_0_1_OR_NEWER
                            //It should be called before culling to prepare material. When there isn't any VisualEffect component, this method has no effect.
                            VFX.VFXManager.PrepareCamera(currCamera);
#endif
                            UpdateVolumeFramework(currCamera, currAdditionalCameraData);

                            bool lastCamera = i == lastActiveOverlayCameraIndex;
                            InitializeAdditionalCameraData(currCamera, currAdditionalCameraData, lastCamera, ref overlayCameraData);

                            xrLayout.ReconfigurePass(overlayCameraData.xr, currCamera);

                            RenderSingleCamera(context, ref overlayCameraData, anyPostProcessingEnabled);

                            using (new ProfilingScope(null, Profiling.Pipeline.endCameraRendering))
                            {
                                EndCameraRendering(context, currCamera);
                            }
                        }
                    }
                }

                if (baseCameraData.xr.enabled)
                    baseCameraData.cameraTargetDescriptor = originalTargetDesc;
            }

            if (xrActive)
            {
                CommandBuffer cmd = CommandBufferPool.Get();
                XRSystem.RenderMirrorView(cmd, baseCamera);
                context.ExecuteCommandBuffer(cmd);
                context.Submit();
                CommandBufferPool.Release(cmd);
            }

            XRSystem.EndLayout();
        }

四、URP自帶Shader腳本和Lit腳本涉及的渲染知識(shí)整理

后面整理。

五、相關(guān)資料閱讀鏈接

Unity官方閱讀Universal RP文檔
Unity Universal RP Manual手冊(cè)
Catlike Coding的Scriptable RP教程
走進(jìn)LWRP(Universal RP)的世界文章來源地址http://www.zghlxwxcb.cn/news/detail-751567.html

到了這里,關(guān)于【unity基礎(chǔ)】關(guān)于學(xué)習(xí)通用渲染管線(UniversalRenderPipeline)入門級(jí)的分享筆記的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 如何通過代碼在Unity設(shè)置URP通用渲染管線資源的畫質(zhì)選項(xiàng)、后處理效果、渲染分辨率、抗鋸齒效果、Renderer Features等效果并制作一個(gè)可以設(shè)置它們的UI

    如何通過代碼在Unity設(shè)置URP通用渲染管線資源的畫質(zhì)選項(xiàng)、后處理效果、渲染分辨率、抗鋸齒效果、Renderer Features等效果并制作一個(gè)可以設(shè)置它們的UI

    ? ?Hello喔 這里是沒有魚的貓先生,本期文章的主題佬們有看到標(biāo)題了 QWQ ? ?當(dāng)使用Urp管道項(xiàng)目時(shí),我們需要在一個(gè)Urp通用管線資源的項(xiàng)目中修改它的各種效果以玩家自己設(shè)置不同的畫質(zhì)需求,那下面這個(gè)通用腳本便誕生了,它也許并不適用于所有的場(chǎng)景,但是相信應(yīng)用過它

    2024年02月09日
    瀏覽(33)
  • Unity | HDRP高清渲染管線學(xué)習(xí)筆記:HDRP光照系統(tǒng)(一)

    目錄 一、Light組件 1. Angular Diameter 2. Light Appearance 3. Intensity(光照強(qiáng)度) 4. Indirect Multiplier(間接光倍數(shù)) 5. Volumetrics(體積霧) 6. Shadows(陰影) 6.1 Shadow Map(陰影貼圖) 6.2 Contact Shadow(接觸陰影) 二、Reflection Probe組件(反射探針) 1. Type(反射貼圖生成的方式) 三、Lig

    2024年02月14日
    瀏覽(19)
  • Unity | HDRP高清渲染管線學(xué)習(xí)筆記:HDRP光照系統(tǒng)(二)

    Unity | HDRP高清渲染管線學(xué)習(xí)筆記:HDRP光照系統(tǒng)(二)

    目錄 一、光源類型和模式 1.?Light組件 1.1 General(通用設(shè)置) 1.1.1 LightLayer(光照層) 1.2?Emission(發(fā)光設(shè)置) 1.3 Shadows(陰影) 二、Light Layer(光源分層) 三、光照探針? 1. Light Probe Group組件 2. 使用光照探針的基本步驟 3. Mesh Renderer組件LightProbes下Blend Probes VS Use Proxy Volume 3

    2024年02月07日
    瀏覽(23)
  • Unity-3DRPG游戲 學(xué)習(xí)筆記(1)--使用URP渲染管線

    Unity-3DRPG游戲 學(xué)習(xí)筆記(1)--使用URP渲染管線

    教程地址: Unity2020 3DRPG游戲開發(fā)教程|Core核心功能01:Create Project 創(chuàng)建項(xiàng)目導(dǎo)入素材|Unity中文課堂_嗶哩嗶哩_bilibili 創(chuàng)建URP通用渲染管線(2021版本) 1. 打開:Windows--Package Manager--左上角下拉選擇Unity Registry--搜索Universal RP--Install 2.?Project窗口--Assets--右鍵Create--Rendering--URP Asstes

    2024年02月11日
    瀏覽(25)
  • Unity | HDRP高清渲染管線學(xué)習(xí)筆記:材質(zhì)系統(tǒng)Lit著色器

    Unity | HDRP高清渲染管線學(xué)習(xí)筆記:材質(zhì)系統(tǒng)Lit著色器

    目錄 一、Lit著色器 1. Surface Options 2. Surface Inputs(表面輸入) 3. Transparency Inputs 二、HDRP渲染優(yōu)先級(jí) 目錄 一、Lit著色器 1. Surface Options 2. Surface Inputs(表面輸入) 3. Transparency Inputs 4.?Emission Inputs(自發(fā)光輸入) 二、HDRP渲染優(yōu)先級(jí) ???????我們可以把現(xiàn)實(shí)世界中的物體分成不

    2024年02月12日
    瀏覽(23)
  • Unity | HDRP高清渲染管線學(xué)習(xí)筆記:HDRP配置文件(HDRP Asset)

    Unity | HDRP高清渲染管線學(xué)習(xí)筆記:HDRP配置文件(HDRP Asset)

    目錄 一、Frame Settings(幀設(shè)置) 二、Volume 三、HDRP配置文件、幀設(shè)置和Volume之間的關(guān)系 四、HDRP配置文件 1.Rendering (1)Color Buffer Format(顏色緩存格式) (2)Lit Shader Mode(Lit著色器模式) (3)Motion Vectors(運(yùn)動(dòng)矢量) 2.Post-processing Quality Settings(后處理質(zhì)量設(shè)置) 五、針對(duì)

    2024年02月16日
    瀏覽(29)
  • Unity | HDRP高清渲染管線學(xué)習(xí)筆記:Lightmapping(光照烘焙)與Lightmap(光照貼圖)

    Unity | HDRP高清渲染管線學(xué)習(xí)筆記:Lightmapping(光照烘焙)與Lightmap(光照貼圖)

    目錄 相關(guān)概念 1.漸進(jìn)式光照貼圖烘焙 1.1 漸進(jìn)式光照貼圖烘焙對(duì)模型的要求 1.2 漸進(jìn)式光照貼圖烘焙對(duì)硬件的要求 1.3 漸進(jìn)式光照貼圖烘焙支持的Unity渲染管線 1.4 進(jìn)行漸進(jìn)式光照貼圖烘焙結(jié)果 1.5 漸進(jìn)式光照貼圖烘焙的CPU版本和GPU版本 1.6 Lighting窗口Lightmapping Settings參數(shù)介紹

    2024年02月11日
    瀏覽(37)
  • Unity3D學(xué)習(xí)記錄01:URP渲染管線以及3D游戲場(chǎng)景設(shè)置

    Unity3D學(xué)習(xí)記錄01:URP渲染管線以及3D游戲場(chǎng)景設(shè)置

    以下內(nèi)容所使用的版本均為Unity2022.3 先在 Window-Package Manager-Unity Registry 里面搜索添加Universal RP ? Unity中,創(chuàng)建渲染管線的方式為Asset文件夾下右鍵 Create-Readering-URP Asset(with Universal Asset) 會(huì)創(chuàng)建以下兩個(gè)Pipeline: ?接著在圖中的設(shè)置里添加這兩個(gè)渲染管線(Project Setting在Edit窗口下

    2024年02月08日
    瀏覽(102)
  • Unity URP渲染管線與內(nèi)置渲染管線的性能差別

    首先,我們來了解一下Unity的內(nèi)置渲染管線。內(nèi)置渲染管線是Unity較早版本中使用的默認(rèn)渲染管線,它使用的是傳統(tǒng)的圖形渲染技術(shù)。內(nèi)置渲染管線提供了一系列的渲染功能,如陰影、反射、抗鋸齒等。但是,由于其較為龐大且復(fù)雜的設(shè)計(jì),它的性能相對(duì)較低。在高質(zhì)量圖形效

    2024年02月08日
    瀏覽(33)
  • Unity Shader 學(xué)習(xí)筆記(4)URP渲染管線帶陰影PBR-Shader模板 -- 新增可自定義陰影顏色

    Unity Shader 學(xué)習(xí)筆記(4)URP渲染管線帶陰影PBR-Shader模板 -- 新增可自定義陰影顏色

    材質(zhì)面板截圖 功能實(shí)現(xiàn)(URP渲染管線下): 1、進(jìn)一步優(yōu)化Shader結(jié)構(gòu)和算法; 2、包含PBR材質(zhì); 3、投射和接收陰影,并升級(jí) 支持自定義陰影顏色 ; 4、支持點(diǎn)光源照射(但不支持點(diǎn)光源陰影)。 通用渲染截圖 自定義陰影顏色截圖 完整代碼: 寫在最后: 1、在我的上一篇文

    2024年02月12日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包