99国产精品欲av蜜臀,可以直接免费观看的AV网站,gogogo高清免费完整版,啊灬啊灬啊灬免费毛片

網(wǎng)易首頁 > 網(wǎng)易號 > 正文 申請入駐

基于URP搭建Linear色彩空間下的UI渲染管線

0
分享至


【USparkle專欄】如果你深懷絕技,愛“搞點研究”,樂于分享也博采眾長,我們期待你的加入,讓智慧的火花碰撞交織,讓知識的傳遞生生不息!

這是侑虎科技第1779篇文章,感謝作者七塊君供稿。歡迎轉(zhuǎn)發(fā)分享,未經(jīng)作者授權(quán)請勿轉(zhuǎn)載。如果您有任何獨到的見解或者發(fā)現(xiàn)也歡迎聯(lián)系我們,一起探討。(QQ群:793972859)

作者主頁:

https://www.zhihu.com/people/Na-Ka-4921

一、前言

自Unity支持Linear色彩空間以來,Unity的3D渲染的光影層次變得更加準確細膩,但是Linear色彩空間下UI的渲染卻因此變得糟糕。絕大多數(shù)的UI資產(chǎn)都是在sRGB色彩空間里制作完成的,UI圖片的格式也都是基于sRGB,所以Linear色彩空間下,基于sRGB的UI圖片的Alpha得不到正確的混合,使得UI圖片的不透明度得不到正確的呈現(xiàn)。

為了匹配Linear色彩空間下的Alpha混合,有些團隊限制使用半透明資產(chǎn);有些是在Ps里盲調(diào),再到Unity里做驗證,直到看起舒服為止;或是在Ps里改變圖片色彩空間。這些做法無疑都是限制了UI制作流程。

現(xiàn)在的URP基于可編程渲染管線,支持自定義管線。要想徹底解決UI渲染問題,可以在Unity管線層面,做出合理的管線設(shè)計,維持UI設(shè)計師正常的sRGB資產(chǎn)制作流程。

二、管線效果對比


左邊: Photoshop效果 | 中間: 自定義UI管線效果 | 右邊: Unity URP默認效果

三、管線的設(shè)計思路


1. 在原有Linear色彩空間的Buffer里渲染3D圖形;

2. 將渲染完成的3D圖像轉(zhuǎn)移至Gamma色彩空間的UI Buffer中;

3. 在Gamma色彩空間的UI Buffer中繼續(xù)渲染UI圖片;

4. 將最終的渲染結(jié)果轉(zhuǎn)回到Linear,并最終輸出。

因為UI圖片的Alpha Blend是在Gamma空間下完成的,所以不存在錯誤的混合結(jié)果,兼容了Linear色彩空間的3D渲染和Gamma色彩空間下的UI渲染。

四、管線的具體實現(xiàn)

管線流程

思路有了,那么再結(jié)合URP現(xiàn)有的流程,詳細方案如下:


3D使用Base的Main Camera渲染,UI使用Overlay的UI Camera渲染,并把UI Camera塞到Main Camera的Stack當中。


URP在使用Post-Processing(后處理)時,本身在3D渲染完就會有一次Uber Post Process的Pass,以及不管有沒有后處理,在最終畫面渲染完都會有一次Final Blit的Pass(如果開了FXAA,則是Final Post)。只要我們在這兩個Pass里做色彩空間轉(zhuǎn)換,幾乎不會產(chǎn)生多少額外的性能開銷。只有在不使用Post-Processing時,才需要在3D渲染完成時額外補一個Pass做色彩空間轉(zhuǎn)換。

另外,Uber Post Process和Final Blit都會用到"Hidden/Universal Render Pipeline/Blit"這個Shader著色, 因此可以在Blit Shader的片元著色器里加入色彩空間轉(zhuǎn)換的函數(shù)和全局的Keyword宏,以方便在管線中利用Command Buffer設(shè)置keyword進行色彩空間轉(zhuǎn)換。

Shader("Hidden/Universal Render Pipeline/Blit"):

half4 Fragment(Varyings input) : SV_Target {        UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);        half4 col = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_SourceTex, input.uv);     #ifdef _LINEAR_TO_SRGB_CONVERSION        col = LinearToSRGB(col);     #endif     #ifdef _SRGB_TO_LINEAR_CONVERSION        col = SRGBToLinear(col);     #endif        return col; }

管線部分(Uber Post Process):

var cmd = CommandBufferPool.Get(); using (new ProfilingScope(cmd, m_ProfilingRenderPostProcessing)) {     cmd.EnableShaderKeyword(ShaderKeywordStrings.LinearToSRGBConversion);       Render(cmd, ref renderingData);                    cmd.DisableShaderKeyword(ShaderKeywordStrings.LinearToSRGBConversion); } context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd);

3D Buffer和UI Buffer的格式:

值得注意的是,Unity默認渲染3D圖形的Buffer格式是RGBA111110Float:


如果在這個格式的Buffer里直接利用shader轉(zhuǎn)換色彩空間(LinearToSRGB)會造成3D圖像嚴重的色深精度丟失。所以需要一個和sRGB色彩信息契合的格式來儲存Shader轉(zhuǎn)換后色彩空間后的圖像信息,所以我選擇了RGBA32UNorm作為后續(xù)UI Buffer的格式,使用不同格式轉(zhuǎn)換色彩后的色深對比如下:


可以看出來,使用RGBA32UNorm能更好地儲存轉(zhuǎn)換后的色深精度。

轉(zhuǎn)換Buffer的方法,我這里未在ForwardRenderer里為UI重新聲明創(chuàng)建RT,以及根據(jù)是否是UI相機,讓Final Blit Pass選擇接受不同的Render Target:

RenderTargetHandle m_UguiTaget; ...... m_UguiTaget.Init("_UIColorTexture"); ...... void CreateCameraRenderTarget(ScriptableRenderContext context, ref RenderTextureDescriptor descriptor, bool createColor, bool createDepth) {     ......     {         var uiDescriptor = descriptor;         uiDescriptor.useMipMap = false;         uiDescriptor.autoGenerateMips = false;         uiDescriptor.depthBufferBits = 24;         uiDescriptor.graphicsFormat = GraphicsFormat.R8G8B8A8_UNorm;         cmd.GetTemporaryRT(m_UguiTaget.id, uiDescriptor, FilterMode.Bilinear);     }     ...... } ...... public override void Setup(ScriptableRenderContext context, ref RenderingData renderingData) {     ......     if (!cameraTargetResolved)     {          RenderTargetHandle finalTarget = isUICamera ? m_UguiTaget : m_ActiveCameraColorAttachment;         m_FinalBlitPass.Setup(cameraTargetDescriptor, finalTarget);         EnqueuePass(m_FinalBlitPass);     }     ...... }

并在UGUI Pass(DrawObjectsPass)里,依據(jù)是否畫UI來重新設(shè)置Render Target:

/* Add by: Takeshi, Set UI Render target */ if (m_IsGameViewUI && m_UguiTarget != default) {     cmd.SetRenderTarget(m_UguiTarget.Identifier());     context.ExecuteCommandBuffer(cmd);     cmd.Clear(); } /* End Add */ context.DrawRenderers(renderingData.cullResults, ref drawSettings, ref filterSettings, ref m_RenderStateBlock);

注:UGUI Pass后面會講到。

UI的分辨率

因為在3D物體渲染完畢時切換了Buffer,在這里有一次全面重置Buffer尺寸的機會,我們可以修改接下來UI Buffer的分辨率,以達到即使降低3D的渲染質(zhì)量,也依然能保證UI以滿屏幕分辨率渲染。

在前面ForwardRenderer的CreateCameraRenderTarget()方法里創(chuàng)建UI RT時指定新的寬高尺寸:

var uiDescriptor = descriptor; uiDescriptor.useMipMap = false; uiDescriptor.autoGenerateMips = false; uiDescriptor.depthBufferBits = 24; uiDescriptor.height = Screen.height; /* 設(shè)置 UI Render Target 的高度 */ uiDescriptor.width = Screen.width;   /* 設(shè)置 UI Render Target 的寬度 */ uiDescriptor.graphicsFormat = GraphicsFormat.R8G8B8A8_UNorm; cmd.GetTemporaryRT(m_UguiTaget.id, uiDescriptor, FilterMode.Bilinear);


UGUI Pass

Unity默認情況是UI在DrawTransparentObjects Pass里繪制,Game視圖因為有獨立的UI相機,所以問題不大,但是Scene視圖里只有一個相機,借助Render Doc可以看出UI和一般的半透明物體是混在一起的,想在UI和半透明物體之間插入自定義Pass是不可能的。理想狀態(tài)是:讓UI擁有屬于自己的Pass,方便后期維護管理。

在Forward Renderer中單獨聲明了一個DrawOjectsPass類型的UGUI Pass,構(gòu)造如下:

m_UguiPass = new DrawObjectsPass("UGUI", false,
RenderPassEvent.BeforeRenderingTransparents +1,
RenderQueueRange.transparent,
LayerMask.GetMask("UI"), m_DefaultStencilState,
stencilData.stencilReference);

用指定的Layer Mask ("UI")來作為這個Pass的渲染條件。使用"UI" layer的Transparent序列物體都會進入這個Pass。


注:不能忘了重新配置Forward Renderer Data, 要把"UI" Layer Mask在Transparent Layer Mask中去掉,否則UI會被DrawTransparentObjects和UGUI這兩個Pass重復(fù)繪制。


UI和半透明物體分離后,Scene視圖也可以方便的校色了。


UI圖片的色彩空間

在管線修復(fù)后,理論上UI圖片就不用勾選sRGB了,但是,我在這里做法是:UI圖片維持勾選sRGB,并在UI的Shader里反向矯正回打勾前的狀態(tài)。


UI Shader的Fragment:

float4 pixel(v2f IN) : SV_Target {     ......     half4 color;     ......     color.rgb = lerp(color.rgb,LinearToSRGB(color.rgb),_IsInUICamera);     // "One OneMinusSrcAlpha".     color.rgb *= color.a;     return color; }

將Linear的Color和sRGB的Color用一個全局變量"_IsInUICamera"為mask進行Lerp插值,全局變量"_IsInUICamera"在DrawObjectPass中實時全局賦值:

public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) {     // NOTE: Do NOT mix ProfilingScope with named CommandBuffers i.e. CommandBufferPool.Get("name").     // Currently there's an issue which results in mismatched markers.     CommandBuffer cmd = CommandBufferPool.Get();     using (new ProfilingScope(cmd, m_ProfilingSampler))     {         Camera camera = renderingData.cameraData.camera;         if (camera.CompareTag("UICamera"))             cmd.SetGlobalFloat(ShaderPropertyId.isInUICamera,1); #if UNITY_EDITOR         else if(m_FilteringSettings.layerMask == LayerMask.GetMask("UI") && renderingData.cameraData.isSceneViewCamera)             cmd.SetGlobalFloat(ShaderPropertyId.isInUICamera,1); #endif         else cmd.SetGlobalFloat(ShaderPropertyId.isInUICamera,0);         ......     }     ......  }

這樣確保只在UI相機渲染階段走sRGB的渲染流程,非UI相機一切照舊,規(guī)避掉因為UI校色而導(dǎo)致非UI相機渲染的UI圖片(*例如:世界空間下的UI)顏色不正確。

注:即UI相機中UI的顏色和不透明度都是正確的,非UI相機中的UI顏色正確但不透明度未被矯正。所以暫時不支持非UI相機的不透明度矯正,但也不影響正常使用。

重置UI組件默認Shader

UI組件,比如Image,在不使用自定義材質(zhì)時,會默認使用Shader "UI/Defaut",而這個Shader是內(nèi)置不可編輯的,對于我們使用了自定的UI Shader和后期對Shader框架進行擴展就很不方便,我們需要UI組件默認使用我們自己寫的Shader。


UI 組件 默認著色器

好在UI組件的源碼是可以編輯的,順著Image組件的源碼,可以看到Image類繼承了MaskableGraphic類,MaskableGraphic類又繼承了Graphic類,這個就是UI組件的根源了。可以看到Graphic類里有一段設(shè)置默認UI Shader的代碼。


修改一下:

static public Material defaultGraphicMaterial {     get     {         // Find Custom UI Shader         Shader uiShader = Shader.Find("UI/URP_Linear_Space_Default");         Material uiMaterial = new Material(uiShader);         if (s_DefaultUI == null)             //s_DefaultUI = Canvas.GetDefaultCanvasMaterial();             s_DefaultUI = uiMaterial;         return s_DefaultUI;     } }

這樣默認UI Shader就替換成我們自己的了,后面就可以愉快地搭建UI Shader框架了。


修改后 的默認UI Shader變成了我們的自定義著色器

五、尾聲

最后的最后,是我項目的GitHub地址:

https://github.com/TakeshiCho/UI_RenderPipelineInLinearSpace

文末,再次感謝 七塊君 的分享, 作者主頁: https://www.zhihu.com/people/Na-Ka-4921, 如果您有任何獨到的見解或者發(fā)現(xiàn)也歡迎聯(lián)系我們,一起探討。(QQ群: 793972859 )。

近期精彩回顧

特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺“網(wǎng)易號”用戶上傳并發(fā)布,本平臺僅提供信息存儲服務(wù)。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相關(guān)推薦
熱點推薦
外媒:在曼城決定不續(xù)約丁丁后,雙方的關(guān)系“陰云密布”

外媒:在曼城決定不續(xù)約丁丁后,雙方的關(guān)系“陰云密布”

雷速體育
2025-04-17 14:24:10
海南陵水縣一別墅區(qū)被指違建已獲確認,60歲舉報人曾兩度遭人蒙面襲擊

海南陵水縣一別墅區(qū)被指違建已獲確認,60歲舉報人曾兩度遭人蒙面襲擊

澎湃新聞
2025-04-16 20:08:27
單場63次犯規(guī)4技犯3違體!CBA外籍裁判:“晉粵之戰(zhàn)”強度太大了

單場63次犯規(guī)4技犯3違體!CBA外籍裁判:“晉粵之戰(zhàn)”強度太大了

狼叔評論
2025-04-17 14:21:05
中央定調(diào)!延遲退休新規(guī)實施,1970年前出生男性有福,可不受影響

中央定調(diào)!延遲退休新規(guī)實施,1970年前出生男性有福,可不受影響

王五說說看
2025-04-05 08:58:18
訂婚強奸案續(xù):被告家屬再申訴;中國婦女報發(fā)聲,女方值得肯定

訂婚強奸案續(xù):被告家屬再申訴;中國婦女報發(fā)聲,女方值得肯定

春序娛樂
2025-04-17 10:34:12
黃曉明罕見曬父子合影,擁抱貼臉好溫馨,小海綿身高出眾顏值像媽

黃曉明罕見曬父子合影,擁抱貼臉好溫馨,小海綿身高出眾顏值像媽

毗那夜迦
2025-04-15 01:00:03
三河市回應(yīng)“警徽改色”:適配墻體顏色

三河市回應(yīng)“警徽改色”:適配墻體顏色

觀察者網(wǎng)
2025-04-16 20:27:09
京東員工內(nèi)網(wǎng)發(fā)帖:家要被偷了兄弟們

京東員工內(nèi)網(wǎng)發(fā)帖:家要被偷了兄弟們

阿矗論古今
2025-04-15 22:46:58
三市公安局,主要領(lǐng)導(dǎo)調(diào)整

三市公安局,主要領(lǐng)導(dǎo)調(diào)整

上觀新聞
2025-04-17 11:50:11
套取騙取醫(yī)保基金!北京7家醫(yī)院被罰

套取騙取醫(yī)保基金!北京7家醫(yī)院被罰

環(huán)球網(wǎng)資訊
2025-04-17 11:33:17
森林北潑水節(jié)被“圍攻”,濕發(fā)濕身超誘人!難怪輕松拿捏浪子汪峰

森林北潑水節(jié)被“圍攻”,濕發(fā)濕身超誘人!難怪輕松拿捏浪子汪峰

鑫鑫說說
2025-04-17 10:53:58
網(wǎng)友:布彭扎出事前一天,在浙一碰到他來做檢查

網(wǎng)友:布彭扎出事前一天,在浙一碰到他來做檢查

懂球帝
2025-04-17 11:55:10
排除他殺,浙江外援布彭扎墜亡內(nèi)幕曝光,外媒:生前要看心理醫(yī)生

排除他殺,浙江外援布彭扎墜亡內(nèi)幕曝光,外媒:生前要看心理醫(yī)生

二哥聊球
2025-04-17 00:00:00
我方還沒出手,美債出現(xiàn)拋售潮,川普凌晨2點發(fā)言,對華態(tài)度反轉(zhuǎn)

我方還沒出手,美債出現(xiàn)拋售潮,川普凌晨2點發(fā)言,對華態(tài)度反轉(zhuǎn)

縱橫觀天下ZK
2025-04-16 18:03:06
網(wǎng)傳深圳一高中男教師多次與女學(xué)生發(fā)生關(guān)系,學(xué)校回應(yīng),網(wǎng)友炸鍋

網(wǎng)傳深圳一高中男教師多次與女學(xué)生發(fā)生關(guān)系,學(xué)校回應(yīng),網(wǎng)友炸鍋

小人物看盡人間百態(tài)
2025-04-15 14:20:04
剛剛,金價突破3300美元!有人從虧4萬到賺7萬元,金店老板焦慮:生意明顯差了!95后女生貸款30萬元買金?專家已提醒

剛剛,金價突破3300美元!有人從虧4萬到賺7萬元,金店老板焦慮:生意明顯差了!95后女生貸款30萬元買金?專家已提醒

每日經(jīng)濟新聞
2025-04-16 17:00:06
朝鮮67局女間諜,在東北活動,竟然因肯德基太好吃,暴露身份

朝鮮67局女間諜,在東北活動,竟然因肯德基太好吃,暴露身份

牛城王小帥
2024-09-29 11:20:12
北京三區(qū)發(fā)布雷電藍色預(yù)警:伴有短時大風(fēng) 局地有冰雹

北京三區(qū)發(fā)布雷電藍色預(yù)警:伴有短時大風(fēng) 局地有冰雹

新京報
2025-04-17 14:13:09
戳到美國七寸了!中國停止接收波音客機:特朗普發(fā)出脫鉤斷鏈哀鳴

戳到美國七寸了!中國停止接收波音客機:特朗普發(fā)出脫鉤斷鏈哀鳴

大風(fēng)文字
2025-04-16 17:01:44
楊瀚森,正式報名參加NBA選秀!本人回應(yīng)→

楊瀚森,正式報名參加NBA選秀!本人回應(yīng)→

魯中晨報
2025-04-17 14:55:05
2025-04-17 15:48:49
侑虎科技UWA incentive-icons
侑虎科技UWA
游戲/VR性能優(yōu)化平臺
1426文章數(shù) 983關(guān)注度
往期回顧 全部

科技要聞

余承東大講安全,絕口不提智駕"替你開車"

頭條要聞

媒體:5775億美元外匯儲備 賴清德備妥第3份對美投名狀

頭條要聞

媒體:5775億美元外匯儲備 賴清德備妥第3份對美投名狀

體育要聞

楊瀚森參加NBA選秀 與詹姆斯同一家經(jīng)紀公司

娛樂要聞

丁真官宣“新身份”謝霆鋒眼光有多絕

財經(jīng)要聞

特朗普吹牛 美國海關(guān)“打臉”

汽車要聞

一躍跳過障礙/秒切防御姿態(tài) 看懂嵐圖"開掛"絕技

態(tài)度原創(chuàng)

時尚
數(shù)碼
游戲
藝術(shù)
本地

50歲女人的“高級感”穿搭,都是基礎(chǔ)款、基礎(chǔ)色,卻高級耐看

數(shù)碼要聞

IDC:三星連續(xù)六年成為全球最大電競顯示器品牌

這位創(chuàng)始人不滿FS社新作:被《逃離塔科夫》帶偏了

藝術(shù)要聞

故宮珍藏的墨跡《十七帖》,比拓本更精良,這才是地道的魏晉寫法

本地新聞

云游湖北 | 七仙女都愛的山水,雙峰米酒一口上頭

無障礙瀏覽 進入關(guān)懷版 主站蜘蛛池模板: 巨野县| 藁城市| 大丰市| 灌云县| 乌拉特中旗| 福清市| 乌兰浩特市| 东兰县| 仁布县| 双牌县| 秦安县| 阜康市| 疏附县| 邯郸市| 临汾市| 右玉县| 溧水县| 黑河市| 文登市| 武平县| 上栗县| 杭州市| 永和县| 元谋县| 华坪县| 子洲县| 黎平县| 黔西县| 玉溪市| 仙游县| 阿克陶县| 香格里拉县| 祁阳县| 龙游县| 四平市| 房产| 临夏市| 隆回县| 新晃| 云浮市| 奉化市|