Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question VSync making performance worse on build (even disabled)

Discussion in 'General Graphics' started by fomafomitch, Oct 16, 2023.

  1. fomafomitch

    fomafomitch

    Joined:
    Nov 22, 2020
    Posts:
    89
    Hello,
    I'm trying some optimisation on my game and encounter this on a build when I attach it to a profiler :

    upload_2023-10-16_19-46-7.png

    My FPS are lower on the build that on the editor. I never go higher than 15 fps in my build even with :

    1- VSync set to "Don't sync' in every quality of project settings
    upload_2023-10-16_19-47-34.png

    2- using the code :
    Code (CSharp):
    1.     private void Start()
    2.     {
    3.         QualitySettings.vSyncCount = 0;
    4.         Application.targetFrameRate = 50;
    5.     }
    3- Disabling Vsyinc on my NVidia Panel > Handle 3D Parameters > Vertical Synchronisation = Disabled + reboot.


    I'm using 2021.3.18f1 and have a GTX1070. I can have steady 30FPS on my editor but build is always 50% slower and 15FPS is kind of low. This "Vsync" doesn't appear at all on the profiler on editor but I read somewhere that it's not a good label and can reveal that a GPU is in a bottleneck. Any ideas ?
     
  2. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    688
    I'd take a GPU capture with RenderDoc (more for debugging but can do a little bit of profiling), NSight Graphics or PIX (DX12 only). If nothing shows up in NSight Graphics, you can also take a look at the entire system with NSight Systems.

    Maybe also log the value of QualitySettings.vSyncCount in regular intervals just in case that there is some other script that sets it later in time.

    By the way, a target frame rate of 50 is a bit of an odd choice. I would 60 on PC or 30 on mobile.
     
  3. fomafomitch

    fomafomitch

    Joined:
    Nov 22, 2020
    Posts:
    89
    Thanks for the advice.

    A capture with RenderDoc :
    upload_2023-10-17_10-45-2.png
    It made like 10 seconds to take the picture and the game was freezing.
    Is the "MainLightShadow" that from EID 265 to 7525 expensive ? And DrawOpaqueObjects from 7565-13350?
    Here a PIX capure :
    upload_2023-10-17_10-50-18.png


    In the first capture above you can see a huge "UniversalRenderPipeline.RenderSingleCamera:Camera_Fog_Gestion" and Camera_Fog_Gestion is a gameobject for my camera. I remove everything heavy for this gameobject (the fog), change my URP pipeline, and it's increasing the "VSync" performance so I'm still capped at 15-18fps

    upload_2023-10-17_10-40-26.png
     
  4. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    688
    Hit the timing button in RenderDoc to get draw call timings
    upload_2023-10-17_7-52-31.png

    Your PIX capture is missing timings too (EOP to EOP duration column). You many need to hit the "Start Analysis" button at the top right. After that click "Collect Timing Data" on the Overview tab.
    I'm surprised you managed to make a PIX capture for a DX11 game, though. That has never worked for me. But that's great, because PIX is a great tool for GPU debugging and profiling.
    upload_2023-10-17_8-5-37.png upload_2023-10-17_8-9-22.png
     
    fomafomitch likes this.
  5. fomafomitch

    fomafomitch

    Joined:
    Nov 22, 2020
    Posts:
    89
    Thanks again for your help. Didn't find the same button as you said but here we are with PIX :

    upload_2023-10-17_18-26-16.png

    There is HUGE budget on the URP :

    upload_2023-10-17_18-30-6.png

    Here an extracted file for RenderDoc (CaptureFrameUnity.txt)
     

    Attached Files:

  6. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    688
    I can't do the profiling for you. But, I'd start with draw call 12355, for example which takes a very long time.
    All the draw calls with 6912 indices add up as well
    By the way, even though RenderDoc can do some profiling, the timings are usually much higher than they would be in real-time. So you can't really tell if you are within 16 ms or not with RenderDoc.

    The PIX screenshot looks as if you didn't even start a capture. The present() information on the right is interesting, but doesn't really say what the issue is.
     
    Last edited: Oct 17, 2023
  7. fomafomitch

    fomafomitch

    Joined:
    Nov 22, 2020
    Posts:
    89
    Thank you for the insights; I can identify some resource-intensive elements now. However, I depend on specific weather effects that I haven't personally created, so optimizing them might be time-consuming. Even if I manage to optimize and possibly gain a 50% performance boost, I'm still perplexed about the significant FPS difference between the build and the editor. Ultimately, my goal is to achieve a consistent 60 FPS.

    It's worth noting that my GPU usage spikes to 100% when playing the game, yet it only renders at 15 FPS.

    upload_2023-10-18_14-32-45.png

    The following code doesn't seem to have any impact:
    Code (CSharp):
    1.         QualitySettings.vSyncCount = 0;
    2.         Application.targetFrameRate = 50;
    Interestingly, the FPS drop is predominantly associated with the game's main scene. I say this because I get about 300 FPS in the menu when it's built.

    What baffles me the most is how the editor runs at double the speed compared to the build. The Unity profiler doesn't offer much clarity either; most of the processes are lumped under the "Zsync" category.

    I've experimented with multiple builds, toggling Zsync on and off... Even when I strip down the scene completely, the FPS remains disappointingly low.

    Do you think upgrading to Unity 2022 might help? Or perhaps starting with a fresh scene and reimporting assets ? Is it common to have a worsen build that editor ?
     
  8. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    688
    Usually the editor runs worse than the build but are you using the same quality level in both?
     
  9. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,040
    Are you running the player as a full-screen application at native resolution?
     
  10. fomafomitch

    fomafomitch

    Joined:
    Nov 22, 2020
    Posts:
    89
    Yes, I only have 1 quality parameter for my project now "Low". In editor, 35FPS and in build no more than 15-18 event deleting everything. However, it's only on the "main scene" of my game with 3D scene, when I'm in the menu I have 300 FPS.

    Same resolution 1920x1080 tested for build and editor. In editor when I "Play Focused" or "Play Maximised" no difference.

    upload_2023-10-20_20-55-14.png

    upload_2023-10-20_20-57-5.png

    Today, I revisited the issue and tested two scenarios: one with FOG and another WITHOUT it. While the performance isn't as severely impacted as before, the FPS improvement from removing the fog is more pronounced in the editor than in the build.

    upload_2023-10-20_21-46-30.png

    BUT my GPU is still at 100% on the build...
    upload_2023-10-20_21-48-56.png
     

    Attached Files:

  11. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,040
    The screenshot says that you have scale set to 0.51in the Editor.
     
  12. fomafomitch

    fomafomitch

    Joined:
    Nov 22, 2020
    Posts:
    89
    having Scale 1f or 0.51f doesn't change performance in editor
    upload_2023-10-21_13-13-6.png
     
  13. fomafomitch

    fomafomitch

    Joined:
    Nov 22, 2020
    Posts:
    89
    I identify two problems.

    I have a frame that take up to 217,000 µs to be made (0.217 seconds => 5FPS).
    I have 133,000 from a pluggin to make a volumetric fog :
    Code (CSharp):
    1. 13942 | - DrawIndexed(6)                                                                                                    | 3476   | 133291.744
    2. 13943 | - OMSetRenderTargets({ Render Target View 6929 }, No Resource)                                                      |        |
    3. 13944 | - RSSetViewports({ { 0.00, 0.00, 5120.00, 2160.00 } })                                                              |        |
    4. 13945 | - ResolveSubresource(RenderTexture-2D-5120x2160, TempBuffer 59 5120x2160)                                           | 3477   | 405.504
    5. 13946 | - OMSetRenderTargets({ Render Target View 6929 }, No Resource)                                                      |        |
    6. 13947 | - RSSetViewports({ { 0.00, 0.00, 5120.00, 2160.00 } })                                                              |        |
    7. 13948 | - Map(Buffer-1-1048576, 0)                                                                                          |        |
    8. 13949 | - Map(Buffer-2-131072, 0)                                                                                           |        |
    9. 13950 | - Unmap(Buffer-1-1048576, 0, (68 bytes))                                                                            |        |
    10. 13951 | - Unmap(Buffer-2-131072, 0, (11 bytes))                                                                             |        |
    11. 13952 | - PSSetShaderResources(0, { RenderTexture-SRV-1515-color-5120x2160 })                                               |        |
    12. 13953 | - PSSetSamplers(0, { SamplerState-1-111-1 })                                                                        |        |
    13. 13954 | - PSSetShaderResources(1, { RenderTexture-SRV-1521-color-5120x2160 })                                               |        |
    14. 13955 | - PSSetShaderResources(2, { RenderTexture-SRV-1529-depth-5120x2160 })                                               |        |
    15. 13956 | - PSSetSamplers(2, { SamplerState-0-111-0 })                                                                        |        |
    16. 13957 | - OMSetBlendState(BlendState-2-1, {})                                                                               |        |
    17. 13958 | - IASetVertexBuffers(0, ID3D11Buffer *[8])                                                                          |        |
    18. 13959 | - IASetInputLayout(InputLayout-14)                                                                                  |        |
    19. 13960 | - IASetIndexBuffer(Buffer-2-131072)                                                                                 |        |
    20. 13961 | - VSSetShader(Unlit/FullVolumeCloudsURP LAYERS Fog of War)                                                          |        |
    21. 13962 | - PSSetShader(Unlit/FullVolumeCloudsURP LAYERS Fog of War)                                                          |        |
    22. 13963 | - Map(ConstantBuffer-171-656, 0)                                                                                    |        |
    23. 13964 | - Unmap(ConstantBuffer-171-656, 0, (656 bytes))                                                                     |        |
    24. 13965 | - VSSetConstantBuffers(1, { ConstantBuffer-171-656 })                                                               |        |

    I will see with the author of the asset for this part.

    And then I have this line that repeat 1,700 times, and if I add all times it takes up to 60,000µs :

    Code (CSharp):
    1. 8214  |   - DrawIndexedInstanced(6912, 1)                                                                                   | 2318   | 63.488
    2. 8215  |   - IASetVertexBuffers(0, ID3D11Buffer *[8])                                                                        |        |
    3. 8216  |   - IASetIndexBuffer(Hex_Mesh)                                                                                      |        |
    4. 8217  |   - VSSetConstantBuffers1(1, { Buffer 2154 })                                                                       |        |
    5. 8218  |   - PSSetConstantBuffers1(2, { Buffer 2154 })                                                                       |        |
    6. 8219  |   - DrawIndexedInstanced(6912, 1)                                                                                   | 2319   | 63.488
    7. 8220  |   - IASetVertexBuffers(0, ID3D11Buffer *[8])                                                                        |        |
    8. 8221  |   - IASetIndexBuffer(Hex_Mesh)                                                                                      |        |
    9. 8222  |   - VSSetConstantBuffers1(1, { Buffer 2154 })                                                                       |        |
    10. 8223  |   - PSSetConstantBuffers1(2, { Buffer 2154 })                                                                       |        |
    11. 8224  |   - DrawIndexedInstanced(6912, 1)                                                                                   | 2320   | 64.128
    12. 8225  |   - IASetVertexBuffers(0, ID3D11Buffer *[8])                                                                        |        |
    13. 8226  |   - IASetIndexBuffer(Hex_Mesh)                                                                                      |        |
    14. 8227  |   - VSSetConstantBuffers1(1, { Buffer 2154 })                                                                       |        |
    15. 8228  |   - PSSetConstantBuffers1(2, { Buffer 2154 })                                                                       |        |


    in my game here a HexChunk that contain :
    - HexMesh
    - A canvas
    - HexFeature that contain all feature in the grid
    - 64 HexCell gameobject

    upload_2023-10-22_10-58-7.png

    Here HexMesh with the "Hex_Mesh" mesh that repeat in my log :

    upload_2023-10-22_10-59-2.png

    I try to make it static and adding "Enable GPU Instancing" in the Hex_Map_Triplanar_Infinite material but performance don't change. Any idea ?
     
  14. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    688
    Check if instancing is actually working in RenderDoc and the frame debugger. If it isn't, the built-in frame debugger might tell you why not.
    You might need to remove SRP batcher compatibility to use instancing.
    https://docs.unity3d.com/Manual/SRPBatcher.html
     
    Last edited: Oct 22, 2023
  15. fomafomitch

    fomafomitch

    Joined:
    Nov 22, 2020
    Posts:
    89
    I believe instancing isn't functioning correctly in RenderDoc. This is based on the numerous "DrawIndexedInstanced(xxxx, 1)" lines observed, where the second argument is ALWAYS at 1.
    upload_2023-10-23_10-33-6.png


    Made a frame debugger on my project for HexMesh :

    upload_2023-10-23_9-42-32.png
    upload_2023-10-23_9-43-7.png

    SRP Why draw call can't be batched with the previous one (I list the errors I have):
    - First call from ScriptableRenderLoopJob
    - Objects either have different shadow caster shaders, or have different shader properties / keywords that affect the output of the shadow caster pass.
    - Nodes have different shaders


    So here my shader that is SRP compatible :
    upload_2023-10-23_9-46-50.png

    I tried to make the shader incompatible with SRP by following the instructions in the documentation. I copied the shader and pasted it into a new file named SRP_INCOMPATIBLE.shader. I then added only a material in the properties section
    Code (CSharp):
    1. Shader "Hex_Map_Triplanar_infinite_SRP_incompatible"
    2. {
    3.     Properties
    4.     {
    5.         _SRPuncompatible("SRP uncompatible", Float) = 1.0
    6.         _infinite_hex_size("infinite_hex_size", Float) = 0.84
    However, the shader still shows as "SRB Batcher: compatible," preventing me from testing GPU Instancing on this new shader.

    It's worth noting that the "Hex_Map_Triplanar_infinite" material is the same for all the Hex_Mesh chunks in my map. Each chunk has the exact same material without any instances. However, the meshes of these chunks vary due to differences in altitude or rotation. There is also a cookie light with moving cloud that go over the material.
     

    Attached Files:

  16. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    688
    Unfortunately, I don't know why it doesn't work. My experience with URP is limited. But I think, you are on the right track. You can try to make the renderer incompatible instead (see docs).

    Different transforms won't break instancing. Or do you mean you are actually using different meshes? You can only use instancing for objects that have identical mesh and materials - however, you can have different transforms and materialpropertyblocks.
     
  17. fomafomitch

    fomafomitch

    Joined:
    Nov 22, 2020
    Posts:
    89
    Yes thanks for the info I didn't know anthing about SRP batcher and GPU instancing I will dig it for the moment all infos !
     
  18. Whatever560

    Whatever560

    Joined:
    Jan 5, 2016
    Posts:
    538
    Did you get anything out of your search ? I recently had my vsync meter go through the roof as well. It was seemlingly ok like just some times ago.
     
  19. fomafomitch

    fomafomitch

    Joined:
    Nov 22, 2020
    Posts:
    89
    I greatly reduce triangle amount in mesh and it did the trick.
     
    Whatever560 likes this.
  20. Whatever560

    Whatever560

    Joined:
    Jan 5, 2016
    Posts:
    538
    Thanks. Yes after further research and profiling it appears that the CPU was simply waiting for the GPU (GPU profiling is turned off by default), so indeed culling/simplification/drawcall reduction todo, (and one fullscreen effect that was poorly optimized)