Search Unity

Official New BatchRendererGroup API for 2022.1

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

  1. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,129
    I believe you are refer to putting MaterialProperty attribute at IComponentData. For this I have some feedbacks for u to improve.

    - Currently it's really hard to achieve semi transparent of 3D model at game object. I would like to see it become super simple at Hybrid Renderer. For my case I'm using URP but I think it's really nice to make work out of the box at HDRP too. I can just set MaterialProperty attribute with _BaseColor to change the alpha of the model. When changing alpha less than 1, it will auto switch surface to Transparent at background and it just works. I dun need to care about whether the shader of material is Lit, Simple Lit, Shader graph or custom shader. Hybrid Renderer will just take care of it. At current game object, it's not the case. I need clone another material, set surface to Transparent and then swap the material at runtime to achieve it. I need to write a lot of complex code to solve this problem. For material that using shader graph I need to mimic _BaseColo property since shader graph dun have such property that available at Lit / Simple Lit shader. There's one issue at Shader Graph I would like URP team to solve it that you when u set Surface to Opaque, some properties will be stripped out from the shader graph that not have the same behavior like Lit / Simple Lit which is really suck. Sometimes there's edge case that I need to clone shader graph and set surface to Transparent to solve the problem. I hope shader graph behave exactly like Lit / Simpe Lit that has _BaseColor property to set so I dun need to hack it to unify the _BaseColor property.

    - Another issue at game object is when working on merge multiple models and textures into single one at runtime, you need to tick Read/Write Enabled to make it work but it will consume double memory. Since Hybrid Renderer model is that all data is persistent on the GPU, will this no longer the issue anymore?
     
    Last edited: Jun 15, 2022
  2. Paulsams

    Paulsams

    Joined:
    Feb 14, 2020
    Posts:
    6
    Thank you very much. I got a better understanding of BRG and also tried the scene and script you suggested. And the problem with URP 2D shaders was not only that they did not have the DOTS_INSTANCING_ON keyword, but also that they were not compatible with SRP Batcher. I don't know if it was done on purpose that the properties for these shaders were not put in CBUFFER, but in general I fixed the problems I described by copying the code from Sprite Lit into my shader, fixed the problems above, and it already worked with BRG. So also Graphics.DrawInstanced also started working when the shader began to support SRP Batcher. But I also discovered RenderPass in RenderFeature, and it seemed very convenient to me - so I decided to leave it as a backup option if BRG is not supported on the device.

    In general, thank you very much for the tip on this script - it helped me a lot! But I still have a question: is there any way in ShaderGraph to make it so that it can take the basis from my shader? I just really would like to make it so that I can create shaders through the graph very easily, and not have to write shaders manually. After all, if you choose Sprite Lit as the basis in the shader graph, then it says that there is no DOTS_INSTANCING_ON keyword.

    UPD: I have a problem, both in BRG and with Graphics - how do I set Sorting Layer? And in the structures that I pass to ScriptableRenderContext.DrawRenderers, I did not find anything about SortingLayer (except for SortingLayerRange, which is not it)). I didn't find anything like that in BRG. Or maybe you can tell me how it happens in HybridRenderer with sprites?
     
    Last edited: Jun 20, 2022
  3. Kmsxkuse

    Kmsxkuse

    Joined:
    Feb 15, 2019
    Posts:
    306
    I just spent the last few days completely overhauling my custom 2D lighting system in URP (2021 because Entities) Render Feature to use
    cmd.DrawMeshInstancedProcedural()
    with buffers set by material property blocks.

    The main issue with this system is its integration with Entities. Entities of point and cone lights (currently the only light sources I've implemented) must first collect entity data into native arrays that are passed on the main thread to several compute buffers that are uploaded to the GPU every frame.

    I have plans on implementing a compute shader that will accept changes in light properties as an input and modify the GPU light properties arrays instead of invalidating and re-uploading all the data for every light source every frame.

    However, this collection of data (local to world TRS, color, light radius, cone direction, etc) must be done using a main-thread (although bursted)
    Entities.ForEach().Run()
    since setting compute shader data immediately after are not available job thread.

    My question is, will there be better integration with the Entities ecosystem and will BRG rendering allow for scheduling rendering calls with dependencies on Entities ForEach() job completion?
     
  4. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    The BRG callback is expected to return a Job handle that tells the engine when the draw commands are ready to be processed. It should be completely fine to have your job chain partially depend on jobs started elsewhere, for example something like the following:
    • callback schedules job A
    • some other code has scheduled job B earlier in the frame (e.g. from an Entities system)
    • callback schedules job C which depends on both jobs A and B
    • the handle for job C is returned from the callback, rendering will wait until that job chain is complete
     
    Kmsxkuse likes this.
  5. Kmsxkuse

    Kmsxkuse

    Joined:
    Feb 15, 2019
    Posts:
    306
    That is exactly what I'm looking for. Great to see.

    However, as my system utilizes multiple materials and variable passes, is there a way to set the render target texture of each batch? It seems to default render straight to camera color texture.
     
  6. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    The BRG does not deal with render targets or passes in any way. It integrates with the active SRP (e.g. URP), which is responsible for those. Draw commands are assigned to passes in the same way GameObjects are (DrawRenderers parameters together with the Material and filtering settings).
     
  7. Kmsxkuse

    Kmsxkuse

    Joined:
    Feb 15, 2019
    Posts:
    306
    Oh, that is a major pain point for converting my extremely heavy post processing 2D light rendering system.

    I know there's the way of setting the layer target of the BRG to one culled by the main camera and then another camera rendering to a RT to obtain the raw outputs of a BRG but adding additional cameras completely invalidates any improvements in performance of using this rendering API over a typical command buffer. Especially since I process between nearly 8 simultaneous render textures for lighting alone, let alone the rest of the project which is GPU driven.

    Which is a real shame. Still, this can possibly be used for direct custom sprite rendering. I know URP sprites right now are not SRP batch rendered due to sprite packing. This will allow for singular draw call rendering of sprites without having to go custom implement a DrawMeshInstancedProcedural() at least.
     
  8. nishikinohojo

    nishikinohojo

    Joined:
    Aug 31, 2014
    Posts:
    46
    I used BRG with burst. It runs very fast in many scenarios. I used ulong of MeshID(left 32bit) and MaterialID(right 32bit) as a key of DrawCommand, so that it makes fair amount of instancing whenever possible.

    But when I stressed out the system by making 15500 objects use difference meshes, it actually runs slower than MeshRenderer in a Render thread.
    (2022.2 b3 DX12, Graphics Job Enabled. Development Build with faster build mode of IL2CPP)
    It runs faster in main thread though. So my part of codes is not likely a bottleneck. It just does only culling and issuing of DrawCommands.
    Profiler indicates internal DrawBuffersBatchMode doesn't scale very well as multi-threaded workload for BRG. Which it does well for MeshRenderer. Even if I split rendering into mulitple BRGs, nothing has changed.

    2022y08m15d_131309682.png
    Figure 1: 15500 Mesh Renderer with different meshes.

    2022y08m15d_131128713.png
    Figure 2:15500 Mesh Renderer equivalent BRG. Split into 31 BRG.

    Is this expected result? Is there any ways to avoid this?
    This API is somehow complicated, I am not sure if I'm doing anything wrong or not.

    Thanks.

    Edit:
    This sounds not likely happen in real scenario but actually is, rather serious problem for me.
    I made custom solution for bone animation and skinning. Because for my scenario, built-in solution is not enough.
    It means I have many skinned Unity Meshes. Every single one of them is different. Normally I have to render them with MeshRenderer and MeshFilter. So I wanted to use BRG to make sure my system perform better. But I can not! because of the problem.

    I just wanted to point out this is real problem. Thanks.
     
    Last edited: Sep 30, 2022
  9. joelv

    joelv

    Unity Technologies

    Joined:
    Mar 20, 2015
    Posts:
    203
    Looks like you have hit some pathological case in job scheduling, where one job ends up doing all of the work. This is not expected. Can you share your scene in a bug report?
     
    nishikinohojo likes this.
  10. nishikinohojo

    nishikinohojo

    Joined:
    Aug 31, 2014
    Posts:
    46
    Thanks!
    I'll make a minimum project for that today or tomorrow. After sendind it, I will let you know!:)
     
    joelv likes this.
  11. nishikinohojo

    nishikinohojo

    Joined:
    Aug 31, 2014
    Posts:
    46
    @joelv

    I've sent a bug report with a minimum project. Something like this.
    2022y08m16d_231702937.png

    You can see the result in a development build only.
    Because to see multi-hreaded DrawBuffersBatchMode working, Graphics Job is needed.

    Sorry for the delay! Thanks!
    If this gets better, I wiil be so glad!!!
     
    MagiJedi and joelv like this.
  12. joelv

    joelv

    Unity Technologies

    Joined:
    Mar 20, 2015
    Posts:
    203
    Thank you. This is something we really want to see working well, and hopefully we can get time to look at it soon
     
    nishikinohojo likes this.
  13. YuriyPopov

    YuriyPopov

    Joined:
    Sep 5, 2017
    Posts:
    237
    Hey can you also share your code for learning purposes ?
     
  14. nishikinohojo

    nishikinohojo

    Joined:
    Aug 31, 2014
    Posts:
    46
    @joelv
    Sorry for bothering you too much, but after sending it, I realized there is a weird legacy comment in core logic.
    //TODO I do not know why but instanceSortingPositions is always needed even when I turn off depth-sorting. Find out why.
    If there is this in DrawCommandJobForSingleSplit.cs:140, it is a total lie.
    BTW I write comments in Japanese sometimes, so if it is incovinient, sorry. But I will try to answer as soon as possible when you have some questions.

    And in NatoriLevelMeshRenderer(This is the entry point of adding mesh. Used in MeshRendererToBRG.cs), you might notice LockBufferForWrite and UnlockBufferAfterWrite don't look like using the same valid count, but actually they do. This was a terrible writing mistake to look at, sorry.

    @YuriyPopov
    Well, sorry. I did not make UBER solution for this. Like my renderer does not support lightmap, because I do not need them. Also, I am not confident in some areas and there are still some work to be done like arbitrary property layout.

    Actually, unity's document is good for BRG 2022. They did not use Job/Burst for this but You should take a look at it.
    https://docs.unity3d.com/2022.2/Documentation/Manual/batch-renderer-group.html
     
    joelv likes this.
  15. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    Would WebGL be able to work with BRG or does it not have the feature set?
    What about WebGPU?
     
    Zarbuz likes this.
  16. joelv

    joelv

    Unity Technologies

    Joined:
    Mar 20, 2015
    Posts:
    203
    We currently do not support WebGL, but are looking into potentially supporting it in the future. The default URP shaders do not work as they are now, but some internal developers have had success in writing custom shaders with some workarounds that do work on WebGL.
     
    Arowx and Zarbuz like this.
  17. PalmGroveSoftware

    PalmGroveSoftware

    Joined:
    Mar 24, 2014
    Posts:
    17
    hard seconding this
     
    NotaNaN, Zarbuz and hippocoder like this.
  18. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    731
    Not sure what I am doing wrong but I can't get any of the BRG demos to work on my Android device. They just don't render anything.

    Tested on Vulkan and GL ES. I tried on 2022.2.5 and 2022.2.7 and didn't work in either.

    EDIT : Nvm, I didn't follow instructions. Had to turn off shader stripping.

    Performance seems....actually quite good. I think that may be the first time I have said that about Unity rendering. Is there a projected release month for 2022.2?
     
    Last edited: Sep 3, 2022
    JussiKnuuttila and mpa7ster like this.
  19. mpa7ster

    mpa7ster

    Joined:
    Jul 6, 2020
    Posts:
    5
    Any idea if this will be useful on Oculus Quest 2? Is it a question of SSBO read performance?
     
  20. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
  21. nishikinohojo

    nishikinohojo

    Joined:
    Aug 31, 2014
    Posts:
    46
    I just want to share my experience with BatchRendererGroup. I mean, how good this is!!!
    Thank you Unity!!!
    Only I hope now is the problem I reported is to be fixed in the near future:p
    https://issuetracker.unity3d.com/is...have-poor-thread-load-balancing-in-some-cases


    2022y10m09d_103429922.png 2022y10m09d_103456027.png
    These are pictures from a minimum project of the system.
    Here, 10000 penguins moving around pushing each other with weird animation, have the capability of playing two animations blended plus two additive animations blended. Internally PlayableGraph-ish API is running. Not like just massive amount of simple trash.
    BTW I'm not using DOTS. You can see Physx is doing things in the profiler.

    By using BatchRendererGroup;
    ・If the same characters happen to have the same posing in the same animation, it is instanced.
    ・Culling-based LOD of animation and skinning is achieved. (Like the top 500 nearest characters in the frustum of the main camera is to be calculated with full feature. Which means low-fov zooming is not a problem.)
    ・Not only TRS matrix, but also custom material properties can be controled in the burst job.

    With these optimization, only CPU does animation and skinning job in my system. Which means GPU can be used more productively to render beautiful things.

    Again, thanks!!! Seriously, this is the game changer!!
     
    Last edited: Oct 9, 2022
  22. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    838
  23. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    You're right, this parameter should be made actually optional. In the meantime, I would recommend passing IntPtr.Zero if you are not using it. Unity doesn't do anything else with this value except pass it back to your callback in case you want to use it to pass some extra information.
     
  24. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    To follow up on this, the upcoming 2022.2.0b15 should contain an improvement to this behavior, and hopefully the rendering work should be better balanced across different threads in that version.
     
    nishikinohojo and Anthiese like this.
  25. nishikinohojo

    nishikinohojo

    Joined:
    Aug 31, 2014
    Posts:
    46
    Hey, if I'm wrong I am sorry but maybe currently(2022.2b14) Shader Graph does not support custom properties for BRG?
    Materials with generated shader can use some basic properties like TRS matrices with BRG but custom properties cannot be used. HDRP/Lit is obviously BRG-ready with its properties like _BaseColor.

    I saw generated code briefly and it does not seem to contain required macro like UNITY_DOTS_INSTANCING_START for my properties.

    I do not want to manually write shader code just to use with BRG especially for HDRP:p
    Are there any future plans for supporting it or maybe am I missing something?

    Edit:
    "some basic properties" means I think these in ShaderVariables.hlsl.


    UNITY_DOTS_INSTANCING_START(BuiltinPropertyMetadata)
    UNITY_DOTS_INSTANCED_PROP(float3x4, unity_ObjectToWorld)
    UNITY_DOTS_INSTANCED_PROP(float3x4, unity_WorldToObject)
    UNITY_DOTS_INSTANCED_PROP(float4, unity_LightmapST)
    UNITY_DOTS_INSTANCED_PROP(float4, unity_LightmapIndex)
    UNITY_DOTS_INSTANCED_PROP(float4, unity_DynamicLightmapST)
    UNITY_DOTS_INSTANCED_PROP(float4, unity_ProbesOcclusion)
    UNITY_DOTS_INSTANCED_PROP(float3x4, unity_MatrixPreviousM)
    UNITY_DOTS_INSTANCED_PROP(float3x4, unity_MatrixPreviousMI)
    UNITY_DOTS_INSTANCED_PROP(SH, unity_SHCoefficients)
    UNITY_DOTS_INSTANCED_PROP(uint2, unity_EntityId)
    UNITY_DOTS_INSTANCING_END(BuiltinPropertyMetadata)


    I filled graphics buffer with unity_ObjectToWorld, unity_WorldToObject and unity_SHCoefficients and they worked for materials from Shader Graph.

    Edit2:
    This is what is happening.

    2022y11m11d_163041897.png 2022y11m11d_163048449.png
    HDRP/Lit (BRG particles receiving color from texture)

    2022y11m11d_163026763.png 2022y11m11d_163056861.png
    Shader Graph thing(They cannot change color even though color is an exposed property)
     
    Last edited: Nov 11, 2022
  26. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    Shader Graph DOTS instancing is supported. However, to be able to DOTS instance Shader Graph properties, it needs to be enabled separately for the property so Shader Graph knows to generate the DOTS instancing code.

    To enable DOTS instancing for a Shader Graph property, open the "Node settings" for the property by clicking the Property in the list of custom properties, and make sure that "Override Property Declaration" is set, and "Shader Declaration" is set to "Hybrid Per Instance".

    upload_2022-11-11_12-13-58.png
     
  27. nishikinohojo

    nishikinohojo

    Joined:
    Aug 31, 2014
    Posts:
    46
    Oh dear, it was that easy! I really sorry! And thanks!
    BTW I think you should put this information on https://docs.unity3d.com/2022.2/Documentation/Manual/dots-instancing-shaders.html
    as this page mentions Shader Graph.
    It would help somebody!
     
  28. unisip

    unisip

    Joined:
    Sep 15, 2010
    Posts:
    340
    that sounds very cool. Did you make any progress in exploring this idea ? I’m just getting started with SBG, but occlusion culling using HiZ is also something I have contemplated without ever getting down to actually implementing it (it sounds like a no brained but I guess if it didn’t make it to URP as a basic feature it probably has some drawbacks that I am not aware of)
     
  29. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,902
    using the "BRGSetup" from the github demos i can make the capsules being rendered in unity 2022.2. and HDRP 14 - but they do not cast shadows.
    using the entity example those can cast shadows.
    so i wonder if i do something wrong here?
     
  30. n3b

    n3b

    Joined:
    Nov 16, 2014
    Posts:
    56
    Hey guys, could you please confirm whether BatchDrawCommand.sortingPosition is an equivalent of Renderer Priority in HDRP or not? I might be missing something but it doesn't change rendering order neither with int positions nor with flag and instance sorting positions (HDRP).
     
  31. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    I don't think it works that way, but I haven't used Renderer Priority in HDRP. The BatchDrawCommand.sortingPosition is simply used for when objects need to be drawn back-to-front due to order-dependent transparency.
     
    n3b likes this.
  32. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    As was already posted, sortingPosition is used for depth sorting, and it's not the same as Renderer Priority, which is currently not supported. Support for Renderer Priority is on the roadmap, and should hopefully be coming in a future release.
     
    n3b and Opeth001 like this.
  33. unisip

    unisip

    Joined:
    Sep 15, 2010
    Posts:
    340
    Just a big "thumbs up" to the unity dev team for BRG ! This is really awesome tech !
    Been wishing to have something like that for years, it just feels like chrismas :)
     
    joelv and JussiKnuuttila like this.
  34. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    Is Unity planning to support OpenGL ?
     
  35. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    BatchRendererGroup should work with GLES3 and GLCore since 2022.2, although it is recommended to prefer other APIs whenever possible. The OpenGL backend is forced to use a less efficient uniform buffer based mechanism for GPU data, whereas every other API uses SSBOs which have fewer restrictions and less overhead.
     
    Opeth001 likes this.
  36. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,902
    @JussiKnuuttila any infos about 2022.2. and casting shadows? as i wrote: using the "BRGSetup" from the github demos i do not get any shdows from the capsules...
     
  37. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    Shadows are definitely supported, so this sounds like a bug of some kind.
     
  38. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,902
    i got the latest from: https://github.com/Unity-Technologi.../SampleScenes/BatchRenderGroupRaw/BRGSetup.cs
    shadow now work but there is no culling at all. neither within the regular passes nor the shadow caster passes which makes it a bit worthless...
    entities just make all this work right out of the box. so i wonder why the regular example does not...

    culling.PNG
     
  39. unisip

    unisip

    Joined:
    Sep 15, 2010
    Posts:
    340
    Is there any documentation about BatchDrawCommands splitVisibilityMask ?
    I suspect this is used to determine when the batch should contribute (main rendering, shadow map rendering, etc...), but is there anything more I should know about this when coding my OnPerformCulling jbo handle ? (I just don't like when I don't fully understand what's actually going on ;-)
     
  40. unisip

    unisip

    Joined:
    Sep 15, 2010
    Posts:
    340
    I have my BRG Renderer running properly now, with support for culling, LODs, per instance SH lighting and one directional light. I am now investigating point lights. Is this feasible, and is there some sample code somewhere ?

    (frame debugger seems to show that additional light data is properly passed to the shader in arrays but I can't see any additional lighting on my instances).
     
  41. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    Point lights should work with HDRP, and with URP if the Forward+ mode is enabled in the URP Renderer setting. The URP Deferred mode should also work for regular point lights, but URP Deferred does not support Reflection Probes with BatchRendererGroup.

    The URP default Forward mode does not support point lights with BatchRendererGroup, as it relies on per-instance light lists, which BatchRendererGroup is unable to set up.
     
  42. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    The official documentation is here: https://docs.unity3d.com/2022.2/Doc...ing.BatchDrawCommand-splitVisibilityMask.html

    It's used when rendering shadow maps that contain separate "splits", such as directional shadow cascades or point light shadow map cube faces, and bits in the mask tell Unity which of those splits the draw command should be rendered into.

    For example, if you have four directional shadow cascades, it's more efficient to compute culling for all of the cascades at once and then set the bitmask once, instead of invoking the entire culling process four times (which is what happened in 2021.3 and earlier).
     
  43. athert

    athert

    Joined:
    Dec 31, 2012
    Posts:
    36
    Can you please provide more detailed instructions how to use this new API?
    I know that its not really for novice users but CPU gain is just too good to be ignored.
    I managed to setup this API from your test projects but there is multiple issues that i dont understand.
    For example, how to setup reflection probes with this api? Or how can i add additional Compute Buffer (for example for occlusion after all Jobs from OnPerformCulling are done)? These informations are nowhere to be found so im struggling a lot.
    Also, i think its not working perfectly even from this test project. For example, this is how interior of my building looks like in editor
    upload_2022-12-23_20-2-35.png

    and this is how it looks like with your project
    upload_2022-12-23_20-3-7.png

    I know that its new API and that there will be more users later with more information, but please, can you show us one simple fully working project that we can analyze and make it working in our own projects too?
     
  44. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,902
    ambient lighting is missing here. you would have to grab sh lighting here per renderer or provide global sh values and sample them in your shader to get proper ambient diffuse lighting.
     
  45. athert

    athert

    Joined:
    Dec 31, 2012
    Posts:
    36
    I would love to do that but i simply dont know how :(
    In attached test project, they already use "unity_ProbesOcclusion" etc. but it doesnt work.
    From what i understand, i can override shader param per instance (for example, "unity_ObjectToWorld") so i think i can push lighting data per instance too but there are no information what or how i should do that. Only solution i found is for DrawMeshInstancedIndirect where i can use MaterialBlock but i cannot use that here.. :/
     
  46. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,902
    just out of my head:
    • use e.g. LightProbes.CalculateInterpolatedLightAndOcclusionProbes or LightProbes.GetInterpolatedProbe to grab the needed lighting information as sh
    • use MaterialPropertyBlock.CopySHCoefficientArraysFrom and read the result back (MaterialPropertyBlock
      .GetVector) or look into the sh code (not sure) from core or hdrp/urp to convert the sh data into the needed 7 Vector4 property arrays.
    • if you need per renderer data you would have to extend the graphicsbuffer and add 7 float4s next to the objecttoworld and worldtoobject matrices.
    reading that data in the shader i can only guess right now. having a look into hdrp code there is:
    #define unity_SHAr LoadDOTSInstancedData_SHAr()
    in the shadervariables.hlsl
    and:
    real4 LoadDOTSInstancedData_SHAr() { return unity_DOTS_Sampled_SHAr; }
    in unitydotsinstancing.hlsl
     
  47. athert

    athert

    Joined:
    Dec 31, 2012
    Posts:
    36
    Oh, i figured it out. There are 4 things that i needed to do.
    1) I should use LightProbes.CalculateInterpolatedLightAndOcclusionProbes to get data for every instance (as you suggested) and push it to MetadataValue. I will check later how it will works with LPPV.
    2) Its working only if there is at least one Light Probe Group with baked data. Otherwise i will get dark lighting. Why is this a thing, i dont know. I just know its working even with 1 light probe in whole level.
    3) It was my first time i needed to use "FlipWinding". There are multiple objects that are with negative scaling so i needed to set Batch with this flag for these specific objects.
    4) For some strange reason, when i had Far Clipping plane set to 10k, i got typical shadow flickering issue
    upload_2022-12-24_14-4-13.png
    when i set distance to 8k, it fix itself.
    upload_2022-12-24_14-5-34.png
    This only happen in game-mode where i draw everything with BRG. In editor mode, everything seems fine. I can live with 8k draw distance but maybe there is bug somewhere? Im not sure right now.

    Right now i think these bugs are fixed for me, still, there can be more. I really hope we will get information about what we need to setup so everything will work correctly. Im scared that there will be more issues later once i will start using more custom features in rendering just because i didnt setup something to BRG :/
     
  48. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,902
    hmm, the data you grab using LightProbes.CalculateInterpolatedLightAndOcclusionProbes is not in the format you send ambient to shaders?!
     
  49. athert

    athert

    Joined:
    Dec 31, 2012
    Posts:
    36
    Im not sure if i can push it straight to to metadata as it is.
    I was looking at ShaderVaraibles.hlsl and there are defines for unity_SHAr, unity_SHAg, unity_SHAb etc. per dots instanced prop. So i just push my values into this and it seems its working. Maybe its not optimal way of doing that so if anyone will know better, i will be glad for better solution :D
    Code (CSharp):
    1.  
    2.  
    3. LightProbes.CalculateInterpolatedLightAndOcclusionProbes(builderObjectPositionArray, lightProbeArray, occlusionProbeArray);
    4. for (int i = 0; i < lightProbeArray.Length; i++)
    5.         {
    6.             sHProperties = new SHProperties(lightProbeArray[i]);
    7.  
    8.             instanceProbeData_shar[i] = sHProperties.SHAr;
    9.             instanceProbeData_shag[i] = sHProperties.SHAg;
    10.             instanceProbeData_shab[i] = sHProperties.SHAb;
    11.             instanceProbeData_shbr[i] = sHProperties.SHBr;
    12.             instanceProbeData_shbg[i] = sHProperties.SHBg;
    13.             instanceProbeData_shbb[i] = sHProperties.SHBb;
    14.             instanceProbeData_shc[i] = sHProperties.SHC;
    15.  
    16.             instanceProbeDataOcclusion[i] = occlusionProbeArray[i];
    17.         }
    18.  
    19. ...
    20. ...
    21.         m_InstanceData.SetData(instanceProbeData_shar, 0, (int)(byteInstanceProbeDataSHAr / kSizeOfFloat4), instanceProbeData_shar.Length);
    22.         m_InstanceData.SetData(instanceProbeData_shag, 0, (int)(byteInstanceProbeDataSHAg / kSizeOfFloat4), instanceProbeData_shag.Length);
    23.         m_InstanceData.SetData(instanceProbeData_shab, 0, (int)(byteInstanceProbeDataSHAb / kSizeOfFloat4), instanceProbeData_shab.Length);
    24.         m_InstanceData.SetData(instanceProbeData_shbr, 0, (int)(byteInstanceProbeDataSHBr / kSizeOfFloat4), instanceProbeData_shbr.Length);
    25.         m_InstanceData.SetData(instanceProbeData_shbg, 0, (int)(byteInstanceProbeDataSHBg / kSizeOfFloat4), instanceProbeData_shbg.Length);
    26.         m_InstanceData.SetData(instanceProbeData_shbb, 0, (int)(byteInstanceProbeDataSHBb / kSizeOfFloat4), instanceProbeData_shbb.Length);
    27.         m_InstanceData.SetData(instanceProbeData_shc, 0, (int)(byteInstanceProbeDataSHC / kSizeOfFloat4), instanceProbeData_shc.Length);
    28.  
    29. ...
    30. ...
    31.  
    32.         metadata[2] = new MetadataValue { NameID = Shader.PropertyToID("unity_SHAr"), Value = 0x80000000 | byteInstanceProbeDataSHAr, };
    33.         metadata[3] = new MetadataValue { NameID = Shader.PropertyToID("unity_SHAg"), Value = 0x80000000 | byteInstanceProbeDataSHAg, };
    34.         metadata[4] = new MetadataValue { NameID = Shader.PropertyToID("unity_SHAb"), Value = 0x80000000 | byteInstanceProbeDataSHAb, };
    35.         metadata[5] = new MetadataValue { NameID = Shader.PropertyToID("unity_SHBr"), Value = 0x80000000 | byteInstanceProbeDataSHBr, };
    36.         metadata[6] = new MetadataValue { NameID = Shader.PropertyToID("unity_SHBg"), Value = 0x80000000 | byteInstanceProbeDataSHBg, };
    37.  
    38. ...
    39. ...
    40.  
     
  50. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,902
    well, you use "SHProperties" to convert the data :)
     
    Last edited: Dec 25, 2022