Search Unity

URP 7.2.1 Camera Stack decrease performance on Android

Discussion in 'Universal Render Pipeline' started by GunLengend, Feb 28, 2020.

  1. GunLengend

    GunLengend

    Joined:
    Sep 24, 2014
    Posts:
    54
    The game running smoothly on a cheap-low Android device. After migrating to URP 7.2.1 with all minimum setting in Unity 2019.3.0f6, performance decrease down to 30FPS (no vsync, no setTargetFrameRate).
    The Profiler and Frame Debugger Show an expected result on Editor but everything go crazy on Android device.

    There are no such things like post-processing, the game screen just has two cameras using camera stack (FPS) game with specific layers renderer.

    After several builds of testing, the issue may come from Camera stacking features. There are few things below will give the details:

    1. The FPS and total MS time:
    See picture 1 and 2, you can see the FPS dropdown to 40 and the MS add extra 10ms when use stack camera compare to no stack camera
    Stacked.jpg
    Picture1. Stacked camera with base camera render the map, overlay camera render only weapon layer.

    NoStacked .jpg
    Picture2. No stack camera even the overlay camera only has 5 drawcalls, all unlit.
    2. The profiler said stacked camera given double times for rendering and calculation: NoStacked 1.PNG Picture 3. No stack camera only takes about 5-6ms

    Stacked.PNG
    Picture 4. The stack camera takes it 2 times! About 10-11ms
    3. The URP Asset settings are really basic and minimum, no post-processing or luxury calculation added. See attached image named URP Setting
    4. The WeaponRenderer and MapRenderer are specific for the layer mask
    5. The camera setting is basically default and minimum

    Then please help me figure out why Camera renderer like double times even Frame Debugger didn't say that?
     

    Attached Files:

    Last edited: Mar 2, 2020
    mowax74, longvtpt and Devil_Inside like this.
  2. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,026
    By default Application.targetFrameRate is 30 for mobile. So with VSync disabled, that's what you should get if you don't set target frame rate manually.
     
    DevBaro likes this.
  3. GunLengend

    GunLengend

    Joined:
    Sep 24, 2014
    Posts:
    54
    Let me add clarify here, the targetFrameRate already set for 60, and without VSync. The game still runs at 60FPS when using Built-in Render
    The key here that why SRP Batcher does a good job but the performance decrease on Android? It does not make sense.

    Here is my configuration for camera stacking:
    MapRenderer.png WeaponRenderer.PNG MapCamera.PNG WeaponCamera.PNG
     
    Last edited: Mar 2, 2020
    thexdd and Devil_Inside like this.
  4. GunLengend

    GunLengend

    Joined:
    Sep 24, 2014
    Posts:
    54
    Bump this thread for update information!
     
  5. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,026
    Ah, then I misunderstood your problem.
    Can you please make a bug report so that we can investigate?
    Thanks!
     
  6. phil_lira

    phil_lira

    Unity Technologies

    Joined:
    Dec 17, 2014
    Posts:
    584
    When using camera stacking, the pipeline will create a working render texture that will be shared for all cameras. So essentially it will never render directly to framebuffer and will require a final blit pass to resolve to framebuffer. There are some optimizations improved planned to camera stacking in this sense. Opening a bug report is the way to go here, we will prioritize it.

    In your case however, if you just need to use camera stacking to render the gun with a different projection, I strongly recommend rendering it by injecting a `RenderObjects` feature and overriding camera instead.

    This will be more efficient as you will only do culling once per-camera and we have an example of how to do it here:
    https://github.com/Unity-Technologies/UniversalRenderingExamples/wiki/FPS-Demo
     
  7. GunLengend

    GunLengend

    Joined:
    Sep 24, 2014
    Posts:
    54
    I already try but look like the gun still touch and go through the wall even I set the render queue higher.
    RendererObject.PNG

    About the camera stack, bug case is 1224525
     
    Last edited: Mar 3, 2020
    phil_lira likes this.
  8. GunLengend

    GunLengend

    Joined:
    Sep 24, 2014
    Posts:
    54
    Bump this thread to update bug case 1224525
     
  9. BattleAngelAlita

    BattleAngelAlita

    Joined:
    Nov 20, 2016
    Posts:
    400
    >In your case however, if you just need to use camera stacking to render the gun with a different projection, I strongly recommend rendering it by injecting a `RenderObjects` feature and overriding camera instead.
    At now RenderFeatures is useless for FPS Weapon rendering because it's only allow to setup fov, but not a near/far plane.
     
  10. GunLengend

    GunLengend

    Joined:
    Sep 24, 2014
    Posts:
    54
    Just for Render on top is ok, but FPS it's not simple like that. I'm facing with ZoomIn/Out issue and moreover
     
  11. BattleAngelAlita

    BattleAngelAlita

    Joined:
    Nov 20, 2016
    Posts:
    400
    >I'm facing with ZoomIn/Out issue and moreover
    This because you can't change fov from script? Actually you can
    Code (CSharp):
    1.     public RenderObjects renderObjPass;
    2.     renderObjPass.settings.cameraSettings.cameraFieldOfView = fov;
     
  12. GunLengend

    GunLengend

    Joined:
    Sep 24, 2014
    Posts:
    54
    No, it's about zoomIn/out need different config for scope. Which lead into: Error.PNG

    If I fix this, the gun never on top of the environment.

    For easy understanding, I have a DepthMask which attached to the scope object, a part of a gun to render the environment and clear the scope mesh.
    When changing the GunOpaques to BeforeRenderingPostProcessing queue the problem can be solved but the gun clipping the environment due to it should be BeforeRenderOpaques.

    Rework on the scope or detach LensClipping which using for the attached DepthMask can solve the problem, but extra works are required and that's not what I expected for the team.
     
    Last edited: Mar 4, 2020
  13. GunLengend

    GunLengend

    Joined:
    Sep 24, 2014
    Posts:
    54
    Update information about it just because I don't want to spam on the thread creation, following the demo and set it up, a little extra work needs to be done with DepthMask shader but the key here that both URP 7.1.8 and 7.2.1 still given bad performance vs built-in, see the picture below:
    URP-721-Vulkan.jpg
    Picture 1. URP 7.2.1 with RendererObject to render GunTransparent and GunOpaques.

    The gun uses URP unlit shader and batched into one SRPBatch but adds extra 6 ms for both URP 7.1.8 and 7.2.1. Both using Vulkan with Graphics Job and Multithread Rendering enable. Remember picture 2. on the #1 post, render the everything except the gun given 60 FPS with 16.5~ ms
    NoStacked .jpg
    Picture 2. URP 7.2.1 render everything except the gun.

    And also there are lots of differences between 7.2.1 and 7.1.8 as you can see below :
    URP-721-Vulkan-Profiler.png
    Picture 3. URP 7.2.1 profiler

    URP-718-Vulkan-Profiler.PNG
    Picture 4. URP 7.1.8 profiler

    As you see, the URP 7.2.1 does some extra work like RenderCameraStack() cost extra 1.2ms even no camera stacked and only Base camera on the screen and RenderCamera has given more than ~3.3ms which is crazy on mobile! Both caused by add RenderObject.

    I'm looking for stable URP for our project which at least given equal performance versus built-in, or fallback is needed just because our game is live production and we hope next update will release with URP.
     
    Last edited: Mar 6, 2020
    Ruslank100 likes this.
  14. GunLengend

    GunLengend

    Joined:
    Sep 24, 2014
    Posts:
    54
    Bump this thread to update information about RenderObject.
     
    mowax74 and BeyondHelp like this.
  15. Ziqin-Qu

    Ziqin-Qu

    Joined:
    Feb 10, 2015
    Posts:
    2
    I have the same issue. Is there any plan to fix the camera stacking performance issue?
     
    mowax74 likes this.
  16. marcrem

    marcrem

    Joined:
    Oct 13, 2016
    Posts:
    340
    still nothing on this????
     
  17. SnaiperoG

    SnaiperoG

    Joined:
    Apr 6, 2015
    Posts:
    66
    God damn, Epic's please buy this small indie studio
     
    mowax74 likes this.
  18. Mal_Duffin

    Mal_Duffin

    Joined:
    Jan 22, 2015
    Posts:
    71
    Did this performance issue on Android ever get resolved?
     
  19. KospY

    KospY

    Joined:
    May 12, 2014
    Posts:
    153
    Any news about this?
     
  20. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,278
    @phil_lira This is a big issue, is there any news?
     
  21. mGMM

    mGMM

    Joined:
    Apr 3, 2017
    Posts:
    6
    I also have this issue in 2021.1.23f. Even with the overlay camera rendering nothing I get a 30% FPS decrease.
     
  22. Mal_Duffin

    Mal_Duffin

    Joined:
    Jan 22, 2015
    Posts:
    71
    This was an issue when we made a quick mobile test for Crooks Like Us, on Android.

    We're about to look at a mobile port again, and it would be great if there was a solution to this, and we could keep our existing URP overlay camera without this massive hit in FPS.
     
  23. huangdongxc

    huangdongxc

    Joined:
    Mar 22, 2020
    Posts:
    6
    I have the same issue.
    Unity Version: 2020.3.22

    Any Update about this?
     
  24. ArteastUFO

    ArteastUFO

    Joined:
    May 19, 2017
    Posts:
    10
    Same problem, is there any news on this?
    Unity Version: 2020.3
     
  25. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,278
    @phil_lira any updates? Myself and many others are unable to use the camera stacking feature entirely due to it being so extraordinarily expensive.
     
    IgorBoyko likes this.
  26. IgorBoyko

    IgorBoyko

    Joined:
    Sep 28, 2020
    Posts:
    90
    Also bump, losing around 10-15 FPS on Pixel 4a and similar devices. This is horrible for mobile platforms

    UPD: both Unity 2020.3 with URP 10 and Unity 2021.2 with URP 12
     
    Last edited: Feb 25, 2022
  27. Octay

    Octay

    Joined:
    Mar 3, 2019
    Posts:
    2
    Same problem here, with Unity 2021.1 and URP 11.
    When I use a base camera along with a overlay camera, the framerate drops from 60 to 30-40, but only on mobile.
     
  28. firfur

    firfur

    Joined:
    Nov 9, 2020
    Posts:
    5
    Same problem here, I dont have any stacked cameras but still giving 7-10 ms for no reason. Solve this pls Unity.
     
  29. Zilk

    Zilk

    Joined:
    May 10, 2014
    Posts:
    333
    Odd that there are no replies on this. I see the same issue on our game.
     
  30. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,278
    I think it's pretty clear that unity has little interest in supporting camera stack for mobile devices
     
  31. Zilk

    Zilk

    Joined:
    May 10, 2014
    Posts:
    333
    That's perfect, seeing how 99.99% of all games release on mobiles are made with Unity :D
    Anyhow, same terrible performance is showing on Switch (which is basically a glorified mobile).

    What's the pipeline doing in the camera stack that is so damn expensive? Is it checking if the stack changes every frame or what's going on? Sometimes I wish that the automagic functions existing in Unity that eats performance would have a performance mode that would require some manual scripting work when something changes. There are several cases like this here and there.
     
  32. StaggartCreations

    StaggartCreations

    Joined:
    Feb 18, 2015
    Posts:
    2,266
    Camera stacking will use at least 2 cameras. Each camera has to perform culling of all the scene geometry, to figure out what it actually needs to renderer. This operation is pretty expensive, especially for large and densely populated environment. In URP, each camera pretty much has to go through the process of executing the renderer. There's definitely some overhead, since not everything about this 2nd camera is unique.

    Basically, adding an extra camera to the scene, and setting the culling mask to "Nothing" also incurs a performance cost, even through it'll practically not end up doing anything. It's figuring out that it doesn't have to render anything that's taking time.

    I'm not sure if this can replace all cases for camera stacking, but a set up as outlined here using the Render Objects feature will be much much faster.
     
  33. Zilk

    Zilk

    Joined:
    May 10, 2014
    Posts:
    333
    Yeah I get that adding a camera should and will have a performance impact. However comparing to the built-in render pipeline I can't really understand why the URP cameras as so much more expensive than the built-in ones.

    This kind of feels like the post process volume system that is just about as unoptimized as it can be by running the default mode. And this is because Unity supposes that everything within a profile can be changed in runtime, which it can. However a dirty system that needs to be manually set would reduce the cost of this system a lot. And this kinda goes for a lot of features in Unity, it does a lot of calculations and expensive operations on the assumption that everything might have changed.
     
    Alverik likes this.
  34. swantonb

    swantonb

    Joined:
    Apr 10, 2018
    Posts:
    172
    A bit dissapointed that there's no decent camera stacking to this day. 2021.2 and urp 12, stack 2 cameras, set culling mask to nothing on both of them and get a 1ms rendering time. Not bad!

    Joke aside, seriously, camera stacking is important for various reasons, why not just fix it? I am getting a 2+ms overhead just for rendering a gun, some attachments and some arms on that camera. Let me be clear, the whole map rendering is 4ms, out of which 2ms go to the weapon+hands. It's unacceptable.
     
  35. SnaiperoG

    SnaiperoG

    Joined:
    Apr 6, 2015
    Posts:
    66
  36. phil_lira

    phil_lira

    Unity Technologies

    Joined:
    Dec 17, 2014
    Posts:
    584
    Hey all, I just checked the case submitted above: 1224525. This didn't quality through QA triage as it was missing a repro project. I'd appreciate if you can submit a bug with a repro project.

    I remember we fixed a performance issue in Camera Stacking that affected mostly mobile devices. The issue caused the camera buffer in some situations to be stored and later loaded in each camera. This fixed landed in 2021 but I don't have now the PR/case on my memory to search exactly the version.

    On Camera Stacking, each camera is rendered separately, this will cause extra culling + any passes that the camera might require (depth/normals/shadows etc). Switching to different render targets will cause buffers to be stored and possibly loaded again. The performance cost can be even more considerable when using camera stacking with MSAA. These limitation are not specific to URP, Built-in RP also handles multiple camera separately and depending on settings it will be expensive. If you have a repro scene that shows built-in RP rendering faster than URP with stacking that would be extremely useful for us to have reported as a bug.
     
  37. nomadshiba

    nomadshiba

    Joined:
    Jun 22, 2015
    Posts:
    27
    For anyone looking for a solution for changing the rendering order.
    You can use RenderObjects Renderer Feature to override Stencil buffer.

    Example, lets say you have 3 layers you wanna render in order.
    First, go to ForwardRenderer object in your Assets
    And under the Filtering section uncheck the layers you wanna change rendering order of from the LayerMask.

    Here ^ I unchecked Default(Layer0), Layer1 and Layer2

    Then there is button at the bottom saying Add Rendering Feature, click on that
    And select RenderObjects, we are gonna add a RenderObjects feature for every layer, so 3 of them.

    (Note that the order of RenderObjects inside the ForwardRenderer is important. Stuff if you wanna render a layer at the top, it should also be at the top here as well)

    I name the first one Layer 0 since its gonna render the Default layer.

    Here ^ I select Default layer only inside the Layer Mask.
    And I override the Stencil buffer. Make its value 3 because its gonna be on top of other 2 layers.

    And Layer 1 goes like this:

    Here ^ I select Layer 1 as the LayerMask and override the Stencil -> Value to 2, everything else is the same

    And Layer 2 looks like this:

    Layer2 selected as LayerMask and Stencil -> Value is 1

    So end result rendering order top to bottom will be like this:
    - Layer 0
    - Layer 1
    - Layer 2

    With this approach you only change the rendering order of things, you don't have multiple cameras.
    So for UI and stuff you need to add them as a child to your camera, so they are always in-front of the camera.

    How does this really work?
    Stencil buffer normally used by Shaders but we want to change it for everything in a layer. So we use RenderObjects to override them.

    How does Stencil Buffer work in this example?
    Stencil buffer is similar to Depth Buffer/Texture, telling to Shader if it can write to a pixel or not.
    So for example we first render Layer 0.
    - So our Stencil -> Value is 3.
    - Stencil Value for the current pixel is 0 because its empty atm.
    - We check if 3 >= 0, which is TRUE, so a PASS
    - We say when PASS happens Replace the value.
    - So it changes the Stencil Value for current pixel from 0 to 3.
    - But it leaves the parts there is nothing to render as 0 because Compare Function didnt work for those parts because we dont have nothing to render for those pixels.
    Then we Render Layer 1 which is under Layer 0
    - So our Stencil -> Value is 2.
    - Stencil Value for the current pixel can be 0 or 3 atm since for the pixel Layer 0 rendered stuff at its 3.
    - So if Stencil Value for current pixel is 0. We do a comparison for 2 >= 0 this is a PASS, so Stencil Value for those pixels becomes 2. And we can render there.
    - But if the Stencil Value for current pixel is 3. So if the Layer 0 Rendered something to that pixel. We do a comparison for 2 >= 3 which is a FAIL, so we Keep that pixel same. So we dont render over places where Layer 0 rendered at.
    - and same stuff for Layer 2
     
  38. GunLengend

    GunLengend

    Joined:
    Sep 24, 2014
    Posts:
    54
    Thank you for the reply, but the project you mentioned above is a live production project that is really hard to attach and share without permission. Second, it was 2 years ago so I am no longer working on that project anymore, but the issue is still here, with a new project, Unity 2021.3.8f1, and the latest URP
     
  39. Mal_Duffin

    Mal_Duffin

    Joined:
    Jan 22, 2015
    Posts:
    71
    Hi @GunLengend

    > but the issue is still here, with a new project, Unity 2021.3.8f1, and the latest URP

    Are you able to upload the files from that new project, along with proof that the issue is still there?
     
  40. GunLengend

    GunLengend

    Joined:
    Sep 24, 2014
    Posts:
    54
    I have some screenshots and benchmarks when optimizing the project, this is again, a release version of live production and I can't share the project source code or any sensitive info, but I can share the screenshot and benchmark. Will update soon.
     
    Mal_Duffin likes this.
  41. cftcimert

    cftcimert

    Joined:
    Apr 4, 2018
    Posts:
    14
    The issue is still here with Unity 2021.3.30f1 and the latest URP
     
  42. swantonb

    swantonb

    Joined:
    Apr 10, 2018
    Posts:
    172
    Yup same is for 2022.3.12 and URP 14