Search Unity

Is the a guide for performance tuning with Hybrid Renderer?

Discussion in 'Graphics for ECS' started by DK_A5B, Nov 6, 2020.

  1. DK_A5B

    DK_A5B

    Joined:
    Jan 21, 2016
    Posts:
    110
    Are there any guides or documentation for tuning performance with the Hybrid Renderer? I've been searching around the documentation and forum and I can't find any.

    For example, the standard Unity documentation includes the "Optimizing graphics performance" guide (https://docs.unity3d.com/2020.2/Documentation/Manual/OptimizingGraphicsPerformance.html). Obviously some of the tips in that are generally applicable (like keeping vertex count as low as possible, minimizing materials per scene, etc.), but I'm wondering how Hybrid Renderer changes things. I'm starting to bump up against my budget on my render thread, but I'm not really sure what potential optimizations there are or what potential bottlenecks I should be looking for that are specific to using the Hybrid Renderer.
     
    lic1227 likes this.
  2. Endlesser

    Endlesser

    Joined:
    Nov 11, 2015
    Posts:
    89
    Count me in, I take it for granted that it would be more performent than non-hybrid render, but it's getting even less performent and much need is a little hybrid render optimizing guidance and which puddles to be aware of to avoid.
     
    charleshendry likes this.
  3. SebastianAaltonen

    SebastianAaltonen

    Unity Technologies

    Joined:
    Feb 21, 2020
    Posts:
    112
    I will add a task for us to write a performance optimization chapter for the documentation.
     
  4. Endlesser

    Endlesser

    Joined:
    Nov 11, 2015
    Posts:
    89
    Cool! now we are in DOTS graphics zone:D.

    I think the most and first wanted approach is: How many steps do we have to go through when turning a Builtin/URP/HDRP scene into a Hybrid scene, here is mine somehow(perhaps most guys are doing so):

    1. Simply put a scene under Subscene or ConvertToEntity, and result is not quite ideal (lose 60%FPS)
    2. Take some research in HybridURPSamples, noticed that `Static``LOD``OcclusionCulling` might pull the trigger
    3. Convert old ones to `StaticOptimizeEntity``HLOD``SceneSectionComponent``OccluderComponent``OccludeeComponent`
    4. Run again and FPS drops to almost ZERO(then I found the possible cause is `OccluderComponent` and that's anthoer thread I opened)
    5, Run without `Occluder` and FPS still not improved, and here I am now(been 5 days since).

    Certainly HRV2 is no regressions, without a doubt, is just me couldn't get it out of malfunction.

    And there're some interesting read from some forum thread about performance in hybrid render:

    "HR v2 performs well for the rendering itself, keeping stuff persistent on the gpu. But it has some serious performance issues in other areas. Static stuff it can still do well as long as you aren't using too many LOD levels. Moving renderers I would use another api like DrawMeshInstanced for now."
    --snacktime

    "Many vertices itself not a problem, but many different meshes can be not so noticeable performant in comparison for now (I expect it to be on the same level as unity default renderer with Built-in and SRP pipelines)"
    --eizenhorn

    Plus with a few tests of mine, heavy mesh is considerably low performamce than mesh like `Cube``Capsule`, probably.

    I've been noticing Viking Village URP is released recently, say if you want it be hybrid, what will you do to get it done step by step:)?
     
  5. SebastianAaltonen

    SebastianAaltonen

    Unity Technologies

    Joined:
    Feb 21, 2020
    Posts:
    112
  6. SebastianAaltonen

    SebastianAaltonen

    Unity Technologies

    Joined:
    Feb 21, 2020
    Posts:
    112
    (Occlusion culling related stuff discussed in previous post.)

    HRV1 required static tags, or it was dead slow. HRV2 is designed to be performance by default. You only pay for what you do. If you don't modify the entities, there's no data upload. You don't need to use the static tags anymore. They still bring a tiny perf increase. If you are seeing a big difference with static tags, we need repro to analyze and fix the performance issue.

    Seeing 60% drop of performance by putting things in a DOTS sub-scene is not expected. We have always been seeing big performance increases. There are some cases where HRV2 is still not great. For example if you have unique material/mesh on every object. That results in very poor DOTS chunk utilization and poor performance. Also if you use a lot of sub-meshes (materials per mesh) the DOTS conversion is forced to replicate the entity. We are going to solve these issue in the next iteration of hybrid renderer (prototype already exists).

    LOD performance issues are not caused by the renderer. Unity treats each LOD as fully separate object, and they are converted to DOTS as separate entities. DOTS transform system needs to transform these deep LOD parenting hierarchies and it adds a lot of cost. We have seen the transform system taking half of the frame time in worst case. DOTS team has plans to do big refactoring to the transform system. Also our team has plans to add LOD combine as post process pass. This will detect whether LOD hierarchies ONLY differ by mesh/material and in those cases combine LOD objects together as single object eliminating the transform hierarchy cost completely.

    All of this will be fully automated. We are aiming for "performance by default".

    Moving renderers around is not a problem at all for HRV2. That was a big bottleneck for HRV1. Our stress test scenes show 10x+ perf improvement there. If you are seeing perf issues with moving entities (except the LOD/submesh hierarchy case described above), please file a bug report with a small repro project, so that we can fix it.

    And please post screenshots of the profiler. Those help a lot in knowing what is slow. Makes it much easier for us to give advice or identify the issue.
     
  7. SebastianAaltonen

    SebastianAaltonen

    Unity Technologies

    Joined:
    Feb 21, 2020
    Posts:
    112
    If you are seeing slow down in the editor, please ensure that Burst jobs are active. It takes a few seconds to compile them if you have changed something, so the first frames will be very slow.

    If you are performance profiling in editor, please disable collection safety checks and memory leak tracking. Those features add a significant cost. Best to do profiling in standalone builds, but editor with these features disabled is OK too.
     
    BigRookGames, Kmsxkuse and thelebaron like this.
  8. Endlesser

    Endlesser

    Joined:
    Nov 11, 2015
    Posts:
    89
    Yes, these will help me spot several potential opts.

    Yes, I will try it.
    Thank you for these useful info.

    Hybrid render is the last piece of DOTS for my proj, so far it runs pretty awesome with other DOTS parts(like with DOTS Anim), and "performance by default" sounds good always.
     
  9. Endlesser

    Endlesser

    Joined:
    Nov 11, 2015
    Posts:
    89
    It's been a while since struggle with `Converting a URP scene into a Hybrid scene` progress, the FPS is reclaimed 80% more or less in last improvement, considering I'm not using any Hybrid OC, FPS's going to be better when it's ready to perform.

    Btw, it turns out `StaticOptimizeEntity` pull the trigger and restore my FPS from 39~45 to 80~85,

    Btw again, the original URP scene renders at 108~111 FPS.(500X500 terrain and 15k+ props)

    ZM URP Scene profiler.png

    ZM Hybrid Scene profiler.png

    I have to say profiler is not my thing and really would like it makes sense to me, are these profiler cuts correct?(1 is URP scene and 2 is Hybrid scene)

    Not much further to add at the present stage, if there's potential todo, let me know, hope all our scenes can be rendered as performent and splendid as what Megacity does~
     
    Last edited: May 26, 2021
  10. SebastianAaltonen

    SebastianAaltonen

    Unity Technologies

    Joined:
    Feb 21, 2020
    Posts:
    112
    Seems that companion game object transform update is taking a lot of time. Are you using a lot of hybrid components, such as lights? And moving them every frame? Do you have a query modifying positions or LocalToWorld every frame? Any query that goes over a component and that component is not set as read-only in the query is considered modifying that component.
     
  11. SebastianAaltonen

    SebastianAaltonen

    Unity Technologies

    Joined:
    Feb 21, 2020
    Posts:
    112
    > Btw, it turns out `StaticOptimizeEntity` pull the trigger and restore my FPS from 39~45 to 80~85,

    I would guess that you are doing some queries incorrectly if this happens. I would guess you are accidentally marking all positions or LocalToWorld matrices as modified and paying the full cost of uploading them to the GPU every frame. Check your queries to make sure they are using read-only access to all components you don't modify.
     
  12. Endlesser

    Endlesser

    Joined:
    Nov 11, 2015
    Posts:
    89
    Yes, you gave me the perfect direction of it. I checked all hybrid components and found these `companion` related tags:

    upload_2021-5-28_12-36-44.png

    And they are automatically created and attached to entity that with specific hybrid components when subscene import is completed, below are the types of what I learned:
    1. URP Post-processing Volume
    2. Light
    3. TextMesh
    4. Terrain
    5. ParticleSystem
    6. LightProbeGroup
    7. ReflectionProbe

    After these fellows are dragged out of subscene and stay as game objects, the FPS rise from 80~85 to 95~98, and no more `companion...state` tags.

    But here comes another question, are these components supposed to have `companion...state` tags? I mean they are all static and don't need to change transform all the time. Or is it a way to have them converted without those tags attached?

    There're total 2 scripts in proj, one is a converter which
    Code (CSharp):
    1. var terrain = gameObject.GetComponent<Terrain>();
    2. conversionSystem.AddHybridComponent(terrain);
    , one is a SystemBase and do have query for hybrid component `Terrain`
    Code (CSharp):
    1. query = GetEntityQuery(ComponentType.ReadOnly<Terrain>());
    , but both 2 scripts are running for once, and it doesn't make any difference when removed from porj.
     
  13. Endlesser

    Endlesser

    Joined:
    Nov 11, 2015
    Posts:
    89
    ----------------------A year after----------------------

    OK, back to work of optimizing with hybrid renderer(v0.11), plus Entities(0.17) and Unity(2020.3.36).

    Fixed this companion updating overhead issue.

    Turns out the transform sync work in "CompanionGameObjectUpdateTransformSystem.cs" is setting all companions constantly without further identifying.

    It is appropriate for dynamic companion objects like followed `Camera` or moving `VFX`.

    But not for static companion objects like `Terrain` `Probe` `Volume`.. those I mentioned in previous post.

    So what I did is separating static companions into updating only once(by adding custom `IComponentData` as a tag), and keep dynamic companions running as always.

    Then all undergoing companions in the scene drops from 100+ to 2(one 3rd person camera and one 1st person camera), and `CompanionGameObjectUpdateTransformSystem` is performing from 0.54ms to 0.04ms.


    More references to solve this:

    https://forum.unity.com/threads/com...ry-slow-on-large-scenes.1016305/#post-6784961

    https://forum.unity.com/threads/com...ry-slow-on-large-scenes.1016305/#post-7397246