A Unity ID allows you to buy and/or subscribe to Unity products and services, shop in the Asset Store and participate
in the Unity community.
Separate names with a comma.
Discussion in 'Graphics for ECS' started by joelv, Jan 26, 2022.
When it is used as an excuse, it's a problem.
Apologies for the slow reply, I was on vacation when this post was made.
BatchRendererGroup itself does not currently automatically provide correct lightmaps, light probes, or reflection probes to rendered instances. Instead, the responsibility is on the BRG user (such as the Entities Graphics package) and the active SRP to handle these in the following manner:
Lightmaps are expected to be provided manually in texture arrays. Normal Unity lightmaps are not texture arrays, and as such switching them requires breaking up draw calls. In addition, BatchRendererGroup does not currently have enough information available CPU side to figure out which instances are using which lightmaps. The Entities Graphics package, for example, manually packs lightmaps in arrays, so instances that are using several lightmaps can be rendered together in a single draw (other batching considerations permitting), and then sets up the unity_LightmapIndex property to contain the correct texture array index to use for each instance.
Light probes are expected to be provided by the BRG user (or handled automatically by the SRP, but as far as I know this would require a custom SRP). BRG does not currently always have the necessary instance position information available to interpolate light probes, and even if it did, it would not be able to efficiently cache the results. The Entities Graphics package evaluates interpolated light probe coefficients using LightProbes.CalculateInterpolatedLightAndOcclusionProbes and overrides the unity_SHCoefficients property to contain the interpolated values. This interpolation is only done when the positions change, so the results will be reused if the entities don't move.
Reflection probes currently rely completely on the SRP, which means that they will work in HDRP, or when using URP Forward+ (which evaluates reflection probes in screen space). Other URP modes do not currently support reflection probes when BRG is used.
BRG itself requires support for instanced rendering and shader integer operations, and it should work on GLES 3.0 and up. On GLES it will use UBOs instead of SSBOs, as SSBOs from vertex shaders are not universally supported on GLES. However, the GPU performance can greatly depend on the device, as many low end Android devices are not favorable towards instanced rendering in general, due to instance properties becoming "varying" values instead of "uniform" values.
The Entities Graphics package additionally requires compute shader support, but that is not a requirement for custom BRG usage.
Currently, Unity does not have a mechanism to configure how shaders are compiled, so there is no built in way to configure this. However, it is possible to use a locally modified package and comment out properties that you know you don't need. In addition, Shader Graphs provide a way to configure which properties are to be DOTS instanced on a per property basis, without requiring package modifications.
In general, customizing the package would also allow you to simplify or change how other pieces of the data are loaded. For these kinds of custom optimizations, you would be able to arrange things exactly according to what your game needs, and you would not be restricted by having to support a very wide variety of configurations.
If you are willing to write custom shaders, it should be possible to highly customize the data with the current BatchRendererGroup API in 2022.3. BatchRendererGroup itself does not really mandate a particular way of loading data, it just provides you a mechanism to efficiently issue instanced draws that have certain buffer bindings set up (the per batch SSBO, and the metadata UBOs with the metadata values for that batch). Unity shaders all use the documented convention how these are used to load instance properties, but a custom shader can do anything it wants with them (and could also use other globally bound textures or SSBOs).
Currently, you still need to split things by Mesh. Procedural support is something that we have been looking at, but is not available in the current version. However, on most platforms, switching Meshes should be relatively fast, cheaper than switching Materials.
Could we use this for rendering (possibly lit) sprites? If so, how?
Just wonder for the old BatchRendererGroup api in 2021.3, is it okay to run in opengles platform. Actually i just need a graphic.drawmeshpersist api,which was promised but latter cancled. And currently it seems only instancing shader can use BatchRendererGroup in 2021.3.
Anyone managed to get it to work properly on mobile, and/or has a sample project for that?
I'm getting weird results where only some instances are displayed - often at lower instance count, not even when pushing the thing to its limits.
Work perfectly fine on Desktop - it's only mobile that's whacky... but outside of setting GetConstantBufferOffsetAlignment/GetConstantBufferMaxWindowSize I'm not sure if there is any specific code that need to be added/tweak for phones.
Should work fine on mobile. Would recommend Vulkan over GL ES though. Also, mobile is more strict, there are weird shader tricks to make sure things function properly. Don't recall everything atm, make sure you are using all the build in unity macros and urp functions, don't try to get tricky with it at first. We have to do some weird tricks like referencing the metadata buffer and multiplying by 0.00001 even if we don't need it, etc. But definitely does work on mobile if setup properly.
I can get it to work. Mostly. The problem is that on some phones the little benchmark scene I made sometime just drop 3/4 of the models without raising any errors.
Also the performances are weird:
Graphics.DrawMeshInstanced is just as fast as BRG on mobile, despite being nearly twice slower on desktop.
Remade the same scene in another engine, and their local equivalent (MultiMeshInstance3D) is nearly twice as fast as BRG on mobile, despite being much, much slower in desktop.
Feels like BRG is doing something very wrong with its mobile implementation, it should be faster than anything else.
Vulkan isn't much of an option sadly since I'm targeting lower-end mobiles and a lot of them (including all the ones in my household) don't support it yet.
Many people are talking about mobile development with BRG in this thread. So I thought it might be good to give more visibility to the new "Advanced DOTS Instanced properties usage" section in the BatchRendererGroup manual https://docs.unity3d.com/Manual/dots-instancing-shaders.html
It's available with 2023.2+ and got backported to 2022 LTS. It's basically giving more control over the way material properties are loaded and can lead to significant performance improvements on low-end platforms when using stock shaders like URP/Lit.
Especially, if you do not use instanced material properties at all, I would recommand looking into the shader define UNITY_DOTS_INSTANCED_PROP_OVERRIDE_DISABLED_BY_DEFAULT. On Quest 2, I was able to get a 15% reduction of the total GPU frame time on some basic scenes by enabling it.
Note that ShaderGraph shaders are not impacted by this define. They are already fast in this regard and doing the right thing by default.
great - but maybe renaming the section adding "optimized" will help
i know this is not the right place but the entire documentation could need a revamp:
the first and most prominent item on each page is the nav to go back or forward - so to skip the page. how bad is this?
there is no toc (which would help in this case)
there are no info boxes, tips, warnings - all the stuff you know from almost any system be it confluence or notion.
hi there! Would you mind explaining further what you mean with this: UNITY_DOTS_INSTANCED_PROP_OVERRIDE_DISABLED_BY_DEFAULT
Do you have any plans to integrate these results with ParticleSystem?
Currently ParticleSystem requires a particle-specific instancing shader for mesh rendering (not a standard GPU instancing feature). Using a non-supported shader is not very practical due to the large number of vertex transformations performed on the CPU.
Although technically similar to DOTS instancing, the only standard shaders in URP that support particle-specific instancing are "Particles/Lit", "Particles/Simple Lit", and "Particles/Unlit", which also do not support shadow casting.
Many developers would be pleased if ParticleSystem would support DOTS instancing rendering, as it would allow the use of many standard URP shaders and shaders created with the shader graph.
How can I unambiguously check that the current environment where the game is running supports the BatchRendererGroup API? I've searched all the documentation, but I haven't found an answer to my question. There is a list of supported platforms in the documentation. It's fine, but it's completely useless. Today it is such a list and tomorrow it will be added and changed. You just need an api that will unambiguously return true/false. Something like SystemInfo.supportsBRG. Maybe I was not attentive enough and it already exists? If not, please ask the developers to add it.