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