Search Unity

Official New BatchRendererGroup API for 2022.1

Discussion in 'Graphics for ECS' started by joelv, Jan 26, 2022.

  1. unisip

    unisip

    Joined:
    Sep 15, 2010
    Posts:
    340
    I just upgraded a BRG test project from 2022.1.22f1 to 2022.2.f1.
    In 2022.1, the lightprobe data passed via metadata works fine, but it seems to be broken on the same project in 2022.2.
    I am using URP.
    Has something changed ? Does anyone have lightprobes working with BRG on 2022.2 ?
     
    Last edited: Jan 2, 2023
  2. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    Lightprobe data has been collected into a single struct between 2022.1 and 2022.2 to cut down on property access overhead, which was found to be unnecessarily high with the old approach. The way to set the data in 2022.2 is to use the unity_SHCoefficients property together with the "SHCoefficients" struct type.
     
  3. mpa7ster

    mpa7ster

    Joined:
    Jul 6, 2020
    Posts:
    4
    If I understand correctly, objects in a subscene will automatically use this API? Is depth sorting happening automatically too or would we need to implement that manually?
     
  4. joelv

    joelv

    Unity Technologies

    Joined:
    Mar 20, 2015
    Posts:
    203
    Objects in subscenes will use the Entities Graphics data path if that package is included in your package manifest. That package uses this API internally.
    However you can use this API without subscenes if you want to provide data to unity rendering in some custom way. With a lot more manual work but with more control
     
    Last edited: Jan 10, 2023
    mpa7ster likes this.
  5. unisip

    unisip

    Joined:
    Sep 15, 2010
    Posts:
    340
    Thanks for the tip. Works like a charm :)
     
    JussiKnuuttila likes this.
  6. IgorBoyko

    IgorBoyko

    Joined:
    Sep 28, 2020
    Posts:
    90
    Hello and thanks for the great new functionality!

    Is there any link to bugtracker to track the issue state? We are currently trying to move to BRG and are experiencing performance degradation on devices like Realme 8, whereas S20 works flawlessly. We're strongly confident we're hitting the exact issue but have no means to track its progress to plan our release schedule.

    Thanks again and have a nice day!
     
  7. Reedmand

    Reedmand

    Joined:
    Sep 29, 2016
    Posts:
    7
    Hello. I want to add some information to the previous commenter's post. On devices like Xiaomi Mi 5 it renders only 1 object from total number when using BRG. Does this problem also related to issue which you described about SSBO data loading path or it is related to another issue? Thanks in advance
     
  8. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    Sorry if i may missed this, will URP and HDRP have a built in BRG integration out of the box? like user doesn't have to create additional renderer? Since it was mention a couple pages back that Unity are working for GPU Driven HDRP with BRG?
     
  9. joelv

    joelv

    Unity Technologies

    Joined:
    Mar 20, 2015
    Posts:
    203
    The BRG is not a renderer in the sense that URP/HDRP is. It's just a way to pass additional data to render. You can see it as an equivalent to Graphics.DrawMeshInstanced but much more performant and powerful (and more complicated to use). Most HDRP and URP shaders are already BRG compatible, or will be made compatible in the future.

    That's all I can say for now. Hopefully there will be more to share on this front soon(ish).
     
  10. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    oh i see, so it's for instancing. . . .
     
  11. joelv

    joelv

    Unity Technologies

    Joined:
    Mar 20, 2015
    Posts:
    203
    Instancing, scriptable culling and a way to keep the instance data persistent on the GPU yes.
     
  12. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,406
    would this improve anything on a heavy scene where all meshes are basically unique?

    Either really huge combined meshes with hundreds of millions of polygons
    or that big mesh in smaller pieces? (maybe culling could be used for those then?)
     
  13. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    i assume this only work when used with DOTS ECS?
     
  14. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    The Entities Graphics package is implemented using BatchRendererGroup, but the API can be used directly as well. You can use the BatchRendererGroup API from your code without using ECS, but then it is up to you to implement the instance data uploading and visibility culling.
     
  15. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    So basically this would perform best for rendering high amount of object with the same meshes, i guess on heavy scene with unique mesh this doesn't improve perfomance then?
    Seems like a good addition to be added into terrain system
     
  16. joelv

    joelv

    Unity Technologies

    Joined:
    Mar 20, 2015
    Posts:
    203
    You can still potentially benefit from using the BRG in the unique mesh case, as you have the ability to keep some data completely on the GPU. This means less data preparation on the CPU and less data transfer to the GPU. It's highly content/device dependent though.
     
    mgear likes this.
  17. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    Hmm interesting, also Sebastian tweet make me even more curious. Did he ever share the project file for the Viking Village? would like to see how it work for that kind of case. Do you guys have a similar sample project that we can peek around for BRG?
     
  18. joelv

    joelv

    Unity Technologies

    Joined:
    Mar 20, 2015
    Posts:
    203
    Sebastians tweet I think is regarding the test project he made during an internal hackweek. Is that correct? If so this is what became RenderBRG.cs which exists here

    https://github.com/Unity-Technologi...es/com.unity.testing.brg/Scripts/RenderBRG.cs

    It's very incomplete though but can be seen as a prototype on how to convert a game object world to render using BRG. But as I said, I do hope to have more to share on this front soon
     
    Reanimate_L likes this.
  19. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    726
    This is because you are working on more rendering improvements currently, with a tentative release date soon? Or you hope to be working on this in the future, but are not currently?
     
  20. IgorBoyko

    IgorBoyko

    Joined:
    Sep 28, 2020
    Posts:
    90
    I am once again bumping this post. Where exactly can we track the issue? It is mentioned that it is currently being investigated, but there are no means to support this statement as of now. We are up for voting for the resolution yet we cannot do that.
     
    bnmguy likes this.
  21. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    Gotcha, alright i hope we can get official proper example for the BRG, i'll use the current script from git for testing then. Which unity version that is used? at least for the current master branch?

    Edit : @joelv i'm getting this error using script above, i'm on HDRP already
    RenderBRG.cs(751,12): error CS1029: #error: '"You need either HDRP or URP package to use this script"'
     
    Last edited: Apr 19, 2023
  22. Thomas-Mountainborn

    Thomas-Mountainborn

    Joined:
    Jun 11, 2015
    Posts:
    501
    Where are we on the procedural / indirect draw support for BRG currently?
     
  23. joelv

    joelv

    Unity Technologies

    Joined:
    Mar 20, 2015
    Posts:
    203
    Work has started on it again but I can't promise in what version it can land.
     
  24. burningmime

    burningmime

    Joined:
    Jan 25, 2014
    Posts:
    845
    I feel like this feature is being "advertised" wrong by Unity. My impression was that BRG had something to do with entities/ECS. I basically just dismissed it as an ECS-only thing. But I took another look at it today, and it solves some problems I was having.

    What BRG basically seems to be is an equivalent of a feature-limited CommandBuffer you fill up in a Burst job (plus the DOTS instancing and other stuff to support that). Which is HUGE. That's so cool for so many things that have nothing to do with entities, and are scoped to smaller features. My brain is already jumping around between vegetation systems, crowd simulations, shattered glass, scattered debris, and all sorts of other things. This has TONS of implications in a GameObject-based game or asset store product.

    I guess all I really have to say is it's a really neat and well-designed feature.
     
    IgorBoyko, DylanF, NotaNaN and 3 others like this.
  25. kite3h

    kite3h

    Joined:
    Aug 27, 2012
    Posts:
    196
    Originally, culling and sorting operations were performed in the low-level engine stage, not the script stage.
    It is not worthwhile to port the work to the script stage and make it possible to transform it according to the purpose of use.
    However, it is meaningless if the speed is reduced to achieve that purpose.
    So, in order for BRG to be used for its intended purpose and to increase performance, the ECS/DOTS situation is only suitable.

    I think that if only meshlet metadata generation is possible, nanite can also be created with BRG.
    But it doesn't seem to make much sense. BRG manages by attaching all mesh data. There is already a similar aspect in terms of attaching and managing only that each piece is not a meshlet.
    In terms of its flexibility, BRG may be more useful than nanite. However, there seem to be a few obstacles to overcome to use BRG well.
     
  26. YuriyPopov

    YuriyPopov

    Joined:
    Sep 5, 2017
    Posts:
    237
    I don't understand your criticism. My current implementation, unfinished and unoptimised as it is, performs much better than the standard mesh renderer path. If you do your culling in a bursted parallel job with BRG performance is much better
     
  27. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    726
    @joelv, texture streaming is not handled automatically by BRG, correct? I mean it is similar to Graphics.Draw.... in that texture streaming has to be handled manually, right?
     
  28. joelv

    joelv

    Unity Technologies

    Joined:
    Mar 20, 2015
    Posts:
    203
    Yes, texture streaming needs to be manually handled as the backend of unity does not know anything about where instances are when you use the BRG.
     
    joshuacwilde likes this.
  29. YuriyPopov

    YuriyPopov

    Joined:
    Sep 5, 2017
    Posts:
    237
    Do you mean mip maps dont work at all?
     
  30. joelv

    joelv

    Unity Technologies

    Joined:
    Mar 20, 2015
    Posts:
    203
    Mip maps works. The GPU will select the correct mip when sampling the texture using derivatives.
    What does not work out of the box is automatic mip streaming.
     
    nishikinohojo likes this.
  31. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,609
    Has the BRG GameObject/MeshRenderer path been implemented since the first post? If so, in which version of Unity was it implemented? If it has not been implemented, has it been added to an internal task list?
     
    JesOb, graskovi and Lymdun like this.
  32. nishikinohojo

    nishikinohojo

    Joined:
    Aug 31, 2014
    Posts:
    46
    If there is such a implementation that would be good I admit(I personally have my BRG implementation with custom SRP though), but even if there isn't, should they officially bring that in future?

    At this point they've provided good low level api which is nice. "Low level" is the entire of point of BRG. Responsibility is apparently on us. I feel like integrating BRG into specific workload is easy work which should not annoy competent Unity's graphics engeneers here. A bunch of idiots like us just can do that instead. Even if you cannot, you just be able to use MeshRenderer and GameObject like old days.

    IMO, Unity should keep moving responsibility on us by making low level API like they are doing it right now. Which may earn them time to bring more nice big feature to fight against Unreal Engine or everything.
     
    Last edited: Jun 1, 2023
    joshuacwilde likes this.
  33. joelv

    joelv

    Unity Technologies

    Joined:
    Mar 20, 2015
    Posts:
    203
    We are exploring different ways of making this easier for you.
    At the moment the easiest way of getting access to using the BRG is to use Entities Graphics. Put your static background geometry in a sub scene and let it be rendered using that path. Of course this is not optimal, but it's something that is there today at least.
     
  34. bnmguy

    bnmguy

    Joined:
    Oct 31, 2020
    Posts:
    137
    Did anyone ever answer this?
     
  35. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    726
    @joelv Does 2022.2 version of BRG (or any version for that matter) support lightmaps, light probes, or reflection probes? For example, I would expect the lightmap and reflection probe textures to be in texture arrays to be usable in a highly instanced environment like BRG. Or does that need to be added in by us manually to the BRG code? I saw some code to handle this in the shader hlsl files for DOTS_INSTANCING, but it wasn't clear to me looking at the BRG script if these are handled properly or not, also not sure if things have changed in any more modern versions.

    And does BRG support GL ES 3.2? GL ES (maybe Vulkan as well, not sure) doesn't have support for cubemap arrays on all devices, so that's why I have some of the above questions.

    Also, I've been looking through the generated Metal shader code. It's concerning how much buffer reads are going on. It could significantly reduced, as there is a lot of extra data that doesn't need to be there. Is there anyway to customize this? The CPU performance of BRG is great! But I don't want to have to send so much data to the shader. For example, I don't need most of the data in this struct (unnecessary is commented out) :

    Code (CSharp):
    1. struct UnityDOTSInstancing_BuiltinPropertyMetadata_Type
    2. {
    3.     uint unity_DOTSInstancingF48_Metadataunity_ObjectToWorld;
    4.     //uint unity_DOTSInstancingF48_Metadataunity_WorldToObject;
    5.     //uint unity_DOTSInstancingF16_Metadataunity_LODFade;
    6.     //uint unity_DOTSInstancingF16_Metadataunity_RenderingLayer;
    7.     //uint unity_DOTSInstancingF16_Metadataunity_SpecCube0_HDR;
    8.     uint unity_DOTSInstancingF16_Metadataunity_LightmapST;
    9.     uint unity_DOTSInstancingF16_Metadataunity_LightmapIndex;
    10.     //uint unity_DOTSInstancingF16_Metadataunity_DynamicLightmapST;
    11.     //uint unity_DOTSInstancingF48_Metadataunity_MatrixPreviousM;
    12.     //uint unity_DOTSInstancingF48_Metadataunity_MatrixPreviousMI;
    13.     uint unity_DOTSInstancingF128_Metadataunity_SHCoefficients;
    14.     //uint unity_DOTSInstancingU8_Metadataunity_EntityId;
    15. };
    16.  
    and here, I would be fine with just a single float3 for reflection probe color as it is only used on tiny objects. Also _SpecCube0_HDR can just be a global float if you know all your reflection probes are the same format.


    Code (CSharp):
    1. struct unity_DOTSInstanceGlobalValues_Type
    2. {
    3.     float4 unity_DOTS_ProbesOcclusion;
    4.     float4 unity_DOTS_SpecCube0_HDR;
    5.     float4 unity_DOTS_SpecCube1_HDR;
    6.     float4 unity_DOTS_SHAr;
    7.     float4 unity_DOTS_SHAg;
    8.     float4 unity_DOTS_SHAb;
    9.     float4 unity_DOTS_SHBr;
    10.     float4 unity_DOTS_SHBg;
    11.     float4 unity_DOTS_SHBb;
    12.     float4 unity_DOTS_SHC;
    13. };


    The main issue with all this is that it is going to hurt GPU performance a lot due to having to jump around a bunch in the memory, way more jumping around than if these arrays were a lot smaller and more tightly designed.

    There is a best of both worlds here, it's just disappointing it's not where it's at right now. Probably makes it unusable for us sadly. What would be nice is if there was just a really fast version of CommandBuffer.DrawMeshInstancedProcedural(), as right now it is super slow (unless something changed in URP with this?) so we could customize the data input as much as possible.

    Even better would be an even lower level version where we can just draw straight from GraphicBuffers, so we can combine multiple meshes into one giant buffer and just specify offsets when drawing to reduce time spent binding new buffers.
     
    Last edited: Jun 25, 2023
  36. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    726
    Another thing, it seems that I am unable to use Xcode GPU profiling in my test scene using BRG on my iPhone XS Max (works ok on iPad). When I start profiling, memory usage on device increases until the app crashes. When I disable BRG, I can profile properly. Anyone else had this issue?
     
    Last edited: Jun 25, 2023
  37. Epineurien

    Epineurien

    Joined:
    Mar 9, 2013
    Posts:
    45
    I might have missed it, but is there a "not simple" sample somewhere?
    I'm mostly curious about the optimal way to handle having multiple mesh&material.
    Right now I just make one BatchRendererGroup (and thus one DrawCommands) object for each combo, because that was the easiest way to scale up that "BRGSetup.cs" sample.
    Is it fine this way, would it be better to cram everything into a single BRG and juggle with BatchID/MaterialID/etc or something in-between depending on some specifics?
     
  38. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    726
    Seems like it's not as bad as it first seemed after doing some more research and improving my custom shader a bit. The shader generator could still use some work to remove the metadata properties and directly replace with constants instead (to avoid a cbuffer read for the metadata indices), but it's not bad. Looking like it could be usable actually.

    My questions still remain with the first two paragraphs about compatibility with GL ES and light probe / light map / reflection probe support. I see that it uses an SSBO to access the indices, so that wouldn't work on GL ES Mali drivers. Is there an alternative? Or just force Vulkan on those devices?

    @joelv
     
  39. IgorBoyko

    IgorBoyko

    Joined:
    Sep 28, 2020
    Posts:
    90
    Sadly, no. Guess we're out of luck trying to track this issue in any manner.
     
  40. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    726
    Regarding what I said about lightmap support in BRG, this is why I am wondering, because I found this in EntityLighting.hlsl

    It makes me think there is support for lightmap texture arrays. If there is, I'll use that, otherwise I will use my solution from Built-In RP just ported over.

    Code (CSharp):
    1. #if defined(UNITY_DOTS_INSTANCING_ENABLED)
    2. #define TEXTURE2D_LIGHTMAP_PARAM TEXTURE2D_ARRAY_PARAM
    3. #define TEXTURE2D_LIGHTMAP_ARGS TEXTURE2D_ARRAY_ARGS
    4. #define SAMPLE_TEXTURE2D_LIGHTMAP SAMPLE_TEXTURE2D_ARRAY
    5. #define LIGHTMAP_EXTRA_ARGS float2 uv, float slice
    6. #define LIGHTMAP_EXTRA_ARGS_USE uv, slice
    7. #else
    8. #define TEXTURE2D_LIGHTMAP_PARAM TEXTURE2D_PARAM
    9. #define TEXTURE2D_LIGHTMAP_ARGS TEXTURE2D_ARGS
    10. #define SAMPLE_TEXTURE2D_LIGHTMAP SAMPLE_TEXTURE2D
    11. #define LIGHTMAP_EXTRA_ARGS float2 uv
    12. #define LIGHTMAP_EXTRA_ARGS_USE uv
    13. #endif
     
  41. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    726
    There seems to be some bug where enabling a keyword using Shader.EnableGlobalKeyword() breaks the BRG material, and it no longer renders at all, this is fixed by disabling the keyword. Is this how it's supposed to be? This is a breaking feature because it means we can't currently enable any "global" keywords during gameplay.

    @JussiKnuuttila @VincentBreysse @Tim-C can any of you respond please? We are trying to get this fixed ASAP. It is blocking progress on our upgrade to URP.
     
    Last edited: Jul 6, 2023
  42. zizoshx13

    zizoshx13

    Joined:
    Jul 7, 2023
    Posts:
    1
    +1
     
  43. Jorgeonidas

    Jorgeonidas

    Joined:
    Nov 21, 2017
    Posts:
    1
    we really need a fix for this ASAP
     
  44. Kritankboy

    Kritankboy

    Joined:
    Aug 8, 2020
    Posts:
    15
    Yeah I am experiencing something similar. Any fix yet?
     
  45. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    726
    C'mon guys, I know you've been online some point within the last 2 weeks. I can look at your profile and tell. You spend all this time to develop these tools and API improvements, and then when there are very basic questions about usage, you can't even take a few minutes to answer?

    This is a major blocker for us, and I've been waiting for answers in this thread for over 2 weeks now. I at least need an answer regarding my most recent question about why BRG breaks from setting global keywords.
     
  46. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    726
  47. Jebtor

    Jebtor

    Unity Technologies

    Joined:
    Apr 18, 2018
    Posts:
    115
    Hi,

    We're in the period where a lot of folks take some vacation to enjoy some much deserved time off. Please be respectful of this. The most efficient way to resolve an issue is by reporting a bug. Do you have an incident number?
     
    Harry-Wells likes this.
  48. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    726
    For all those following, I figured out the issue.

    It has nothing to do with changing global keywords.

    For a reason I don't understand yet (need to dive deeper into URP BRG shader code), you must call
    Code (CSharp):
    1. VertexPositionInputs vertInputs = GetVertexPositionInputs(pos.xyz);
    and you have to use the posiitonCS field in that returned struct. Even if you just multiply it by some tiny tiny number and add it to some random variable you are using. Unity has a similar bug where this is required to get access to the directional lightmap (have to multiply by lightmap color in some special way, even if by a small amount iirc).

    I think there is some kind of buggy (or maybe just odd) shader code stripping or something going on where it doesn't think some uniform or something is being used.

    I don't directly use the output of GetVertexPositionInputs() since I get the objectToWorld matrix in a more optimized way to avoid accessing the metadata buffer. Problem is this new hack will force it to use the metadata buffer, so I need to find a way around that, but for now it works.
     
    Arnold_2013 likes this.
  49. bnmguy

    bnmguy

    Joined:
    Oct 31, 2020
    Posts:
    137
    While your second point is valid, you're first point is ridiculous. You aren't the first company to exist that has employees wishing to take time off. Unity's inability to properly manage it's employee workforce is NOT our problem. Is this a joke? Really? If management allows so many people to take time off at the same time, halting productivity, it's time to fire management. Thats the hard truth.

    For the record, this comes across as "we deserve a break so too bad". As if we all don't have jobs & work hard as well. So condescending.
     
    Last edited: Jul 13, 2023
    goncalo-vasconcelos likes this.
  50. Fribur

    Fribur

    Joined:
    Jan 5, 2019
    Posts:
    135
    Calm down. Not really anything new that most folks take a few days off during summer. And xyz % fewer people compared to other seasons leads to xyz % productivity drop. Not the end of the world.
     
    Spy-Master, Tigrian and zenbin3d like this.