unity两个项目合并 同名_从实际项目升级中关于 Unity SRP 的一些评测
Untiy 推出SRP 已經(jīng)接近一年了,其中官方宣稱 LWRP 在2018年年底時已經(jīng)處于 production ready 既隨時可以做產品了,于是改名為URP, 不過 HDRP 還需要2019.4 的到來才能到達完整版。 不過在我看來 URP 還不能說是 production ready 還處于玩具階段。而且有時候覺得Unity官方對于技術路線偶爾會出現(xiàn)不明確,左右搖擺的情況。比如Unity 2018 新出的Camera.AddCommandBuffer 來做自定義渲染, 這在 Unity 2019 被廢除了,取而代之使用 Render Feature /ScriptableRenderPass 來實現(xiàn),不過這東西也處于實驗階段。
SRP不做任何修改是否可以直接提高項目性能,答案是可以直接減少CPU給GPU準備階段的性能大約10%左右。無法直接提升GPU的渲染性能,對于不使用任何光照的項目且處于Opengl ES2.0 這類低端機,基本沒有任何GPU性能提升。
以目前使用的SRP 有大量Bug 舉兩個例子
1. [In order to call GetTransformInfoExpectUpToDate, RendererUpdateManager.UpdateAll must be called first.] 莫名的內置渲染錯誤,無法自己修改。
官方Issue鏈接
https://issuetracker.unity3d.com/issues/errors-message-at-editor-play?_ga=2.202176470.695125147.1571176891-1511937231.1511185188
2. 使用渲染指令Blit 后,會導致RenderTarget 無法自動恢復原始RenderTarget,需要手動還原SetRenderTarget,這個在之前的CommandBuffer 里都不曾遇到
在項目中期切換到SRP可以直接優(yōu)化的地方
1.相機Culling優(yōu)化
https://connect.unity.com/p/unityzhi-zuo-ren-zhuan-chang-unity-aaayou-xi-shen-du-you-hua-zhu-ti-yan-jiang
根據(jù)官方優(yōu)化參考,使用SRP后,可以控制相機 Culling(裁剪)行為,對于項目中有自己實現(xiàn)基于投影器Projector的陰影相機可以復用主相機的 Culling結果, 對于UI上模型RT相機可以不做任何Culling
2.相機 Stack 優(yōu)化
SRP廢棄了多個相機的實現(xiàn),無法再使用多個相機 (比如我們項目1個GamePlay, 1個HUD, 1個UI相機的。使用官方SRP模板,UI相機背景色會蓋住場景內容),原因為
如果只使用1個相機,渲染結果可以直接寫入BackBuffer
如果有多個相機,由于第二個相機需要第一個相機結果填充畫布后再渲染,因此至少需要一張RenderTexture的臨時緩沖,且還需要針對不同的Viewport做裁剪等等,寫入backBuffer的時機也會延遲
官方文檔廢棄Camera Stack原因
https://docs.google.com/document/d/1GDePoHGMngJ-S0Da0Fi0Ky8jPxYkQD5AkVFnoxlknUY/edit
3.UI OverDraw 優(yōu)化
使用同一個相機繪制UI后,可以考慮給UI添加模板測試,將UI擋住場景的部分,場景可以不被繪制到。
4.UI 批次合并(Opengl 3.0+ Unity2019.2+ with SRP Batcher)
對于場景特效類,基本都無緣SRP batcher 他對Cbuffer的容量有限制
對于UI如果全局自定義Shader可以使用 SRP Batcher 不過目前還是實驗階段。
最后來說下 Camera.AddCommandBuffer 這個功能在 Unity 2019 替換為 ScriptableRenderPass 后如何實現(xiàn)一個XRay
使用 CommandBuffer時僅僅需要 camera.AddCommandBuffer(CameraEvent.AfterForwardOpaque, m_XRayBuffer);
然后再XRayBuffer.drawRenderer(renderer, XrayMat)即可
在2019里 需要創(chuàng)建XrayRenderPassFeature 類來實現(xiàn)
public class XRayRenderPassFeature : ScriptableRendererFeature
ScriptableRendererFeature有2個接口要實現(xiàn)分為
Creata() 創(chuàng)建一個實現(xiàn)具體Xray Pass的接口
AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) 將創(chuàng)角的pass 添加進renderer 隊列
在XRayRenderPassFeature 里實現(xiàn)一個 CustomRenderPass : ScriptableRenderPass 來編寫具體Xray邏輯
Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) 準備階段
Execute(ScriptableRenderContext context, ref RenderingData renderingData) 渲染階段
FrameCleanup(CommandBuffer cmd) 清理階段
基本實現(xiàn)都在Configure里
if (null != m_xrayMaterial) {CommandBuffer xraycmd = CommandBufferPool.Get(m_profilerTag);xraycmd.DrawMesh(m_drawMesh, m_xrayTarget.transform.localToWorldMatrix, m_xrayMaterial);context.ExecuteCommandBuffer(xraycmd);CommandBufferPool.Release(xraycmd); }大致流程是,Renderer 會根據(jù) pass 的 renderPassEvent 進行和內置其他pass 比如天空盒,點光,深度 等等其他pass 一起sort, 之后分別在渲染前,渲染,渲染后調用接口
以官方的SRP FPS Demo 基礎來實現(xiàn)XRay
git: https://github.com/Unity-Technologies/UniversalRenderingExamples
1.在FpsSetup 預制體里添加剛剛創(chuàng)建的Feature
2.編寫一個簡單ZTest Greater的Shader 用來繪制被遮擋的部分
Shader "Unlit/XrayShader" {SubShader{Tags { "RenderType"="Opaque" "LightMode"="LightweightForward" }LOD 100Pass{ZTest greateroffset -1,-1HLSLPROGRAM#pragma vertex vert#pragma fragment frag#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/core.hlsl"struct appdata{float4 vertex : POSITION;};struct v2f{float4 vertex : SV_POSITION;};v2f vert (appdata v){v2f o;o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);return o;}float4 frag (v2f i) : SV_Target{return float4(1,0,0,1);}ENDHLSL}} }3.在場景中放置一個示例Cube,取名為XRayTarget
最后運行游戲
Cube被遮擋的部分被繪制為紅色最后 使用自定義 ScriptableRendererFeature 的話,還需要自己編寫對應的Editor代碼,比之前繁瑣許多。
如果自己來編寫SRP的話,RenderPassFeature 需要自己維護pass列表來實現(xiàn), 也可以僅僅去實現(xiàn)自定義的ForwardRenderer,可以減少很多功能的重復造輪子。
總結
以上是生活随笔為你收集整理的unity两个项目合并 同名_从实际项目升级中关于 Unity SRP 的一些评测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tab-pane 怎么家点击事件_想起爆
- 下一篇: windows nginx站点分割日志_