Problems encountered in upgrading the project to URP

It has been nearly a year since Untiy launched SRP. Among them, it was officially announced that LWRP was in production ready at the end of 2018 and ready to make products, so it was renamed URP, but HDRP still needs the arrival of 2019.4 to reach the full version. However, in my opinion, URP cannot be said to be production ready and it is still in the transition from toy to production stage. And sometimes I feel that the Unity official's technical route is occasionally ambiguous and swaying from side to side. For example, Unity 2018's new Camera.AddCommandBuffer is used for custom rendering, which was abolished in Unity 2019 and replaced it with Render Feature /ScriptableRenderPass, but this thing is also in the experimental stage.

Whether SRP can directly improve the performance of the project without any modification, the answer is that it can directly reduce the performance of the CPU to the GPU preparation stage by about 10%. It is not possible to directly improve the rendering performance of the GPU. For projects that do not use any lighting and are in low-end machines such as Opengl ES2.0, there is basically no GPU performance improvement.

Take two examples with a large number of bugs in the currently used SRP

1. [In order to call GetTransformInfoExpectUpToDate, RendererUpdateManager.UpdateAll must be called first.] Inexplicable built-in rendering error, unable to modify by yourself.

Official Issue link

https://issuetracker.unity3d.com/issues/errors-message-at-editor-play?_ga=2.202176470.695125147.1571176891-1511937231.1511185188

2. After using the rendering command Blit, RenderTarget cannot automatically restore the original RenderTarget, you need to manually restore SetRenderTarget, which has not been encountered in the previous CommandBuffer

Switch to a place where SRP can be directly optimized in the middle of the project

1. Camera Culling optimization

 

https://connect.unity.com/p/unityzhi-zuo-ren-zhuan-chang-unity-aaayou-xi-shen-du-you-hua-zhu-ti-yan-jiang

According to the official optimization reference, after using SRP, you can control the camera Culling (cropping) behavior. For projects that have their own shadow cameras based on the projector, you can reuse the Culling results of the main camera. For the model RT camera on the UI, you can do nothing. Culling

2. Camera Stack optimization

SRP has abandoned the implementation of multiple cameras and can no longer use multiple cameras (for example, our project has 1 GamePlay, 1 HUD, and 1 UI camera. Using the official SRP template, the background color of the UI camera will cover the scene content), the reason for

If only 1 camera is used, the rendering result can be directly written into BackBuffer

If there are multiple cameras, because the second camera needs the result of the first camera to fill the canvas before rendering, at least a temporary buffer of RenderTexture is needed, and it needs to be cropped for different Viewports, etc., the timing of writing backBuffer Will also delay

Reasons for the official document to abandon the Camera Stack

https://docs.google.com/document/d/1GDePoHGMngJ-S0Da0Fi0Ky8jPxYkQD5AkVFnoxlknUY/edit

3.UI OverDraw optimization

After using the same camera to draw the UI, you can consider adding a template test to the UI to block the UI from the part of the scene, and the scene may not be drawn.

 

4.UI batch merge (Opengl 3.0+ Unity2019.2+ with SRP Batcher)

For scene special effects, SRP batcher is basically missed. He has a limit on the capacity of Cbuffer.

For the UI, if you customize the Shader globally, you can use SRP Batcher, but it is still experimental.

 

Finally, let's talk about how to implement an XRay after the function Camera.AddCommandBuffer is replaced with ScriptableRenderPass in Unity 2019

When using CommandBuffer, only camera.AddCommandBuffer(CameraEvent.AfterForwardOpaque, m_XRayBuffer) is needed;

Then XRayBuffer.drawRenderer(renderer, XrayMat)

 

In 2019, you need to create the XrayRenderPassFeature class to achieve

public class XRayRenderPassFeature : ScriptableRendererFeature

 

ScriptableRendererFeature has 2 interfaces to be implemented into

Creata() creates an interface that implements a specific Xray Pass

AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) will add the pass of Chuangjiao to the renderer queue

 

Implement a CustomRenderPass in XRayRenderPassFeature: ScriptableRenderPass to write specific Xray logic

Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) preparation phase

Execute(ScriptableRenderContext context, ref RenderingData renderingData) rendering phase

FrameCleanup(CommandBuffer cmd) cleaning phase

 

The basic implementation is in Configure

 

CommandBuffer xraycmd = CommandBufferPool.Get(m_profilerTag); xraycmd.DrawMesh(m_drawMesh, m_xrayTarget.transform.localToWorldMatrix, m_xrayMaterial); context.ExecuteCommandBuffer(xraycmd); CommandBufferPool.Release(xraycmd);

 

The general process is that the Renderer will sort with other built-in passes such as skybox, point light, depth, etc. according to the renderPassEvent of the pass, and then call the interface before, after rendering, and after rendering.

 

Add one to implement XRay based on the official SRP FPS Demo

https://github.com/Unity-Technologies/UniversalRenderingExamples

1. Add the Feature just created in the FpsSetup prefab

2. Write a simple ZTest Greater Shader to draw the occluded part

 

Shader "Unlit/XrayShader" { SubShader { Tags { "RenderType"="Opaque" "LightMode"="LightweightForward" } LOD 100 Pass { ZTest greater offset -1,-1 HLSLPROGRAM #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. Place a sample Cube in the scene and name it XRayTarget

Finally run the game

 

Finally, if you use a custom ScriptableRendererFeature, you also need to write the corresponding Editor code yourself, which is much more cumbersome than before.

 

If you write SRP yourself, RenderPassFeature needs to maintain the pass list by yourself, or you can just implement a custom ForwardRenderer, which can reduce the repetitive wheel of many functions.

Guess you like

Origin blog.csdn.net/mango9126/article/details/112010895