Search Unity

Feature Request Prefab Level Generation - Light Probe Support

Discussion in 'Global Illumination' started by Levitas, Nov 3, 2020.

  1. Levitas

    Levitas

    Joined:
    Mar 17, 2015
    Posts:
    7
    TLDR: We need LightProbes.positions to not be read only.

    We have a procedurally generated map (via rooms) and we want to take our game to the next level by baking lighting in those rooms. I figured out how to bake light maps and change them at runtime, but the only thing stopping us from moving forward is Light Probes. Light Probes can not be moved at run time, the code seems to be buried and hidden, directly from serialization. No way to change or recreate them.

    I have been searching for a solution to this problem for weeks and I am really hoping to draw a bit of attention here, because at this moment, there are no tools, no source code, no work arounds that I can find for this problem, and I'm seeing a lot of people stuck in the same situation as me.


    This presentation from The Elder Scrolls: Blades shows their solution to this exact problem. It is very nice, but from the looks of it they basically had to rewrite the lighting system. If I could, If I even knew where to begin, I would happily do the same. Are there any classes I can take? I feel the subject is too broad to be self-taught.

    Unless I can get help, my current and only course of action is to rewrite the light probe system, and I'm not sure if I can do it alone.

    Thank you for your time!
     
    Last edited: Nov 3, 2020
    Ruchir, Rich_A, NotaNaN and 1 other person like this.
  2. Extrys

    Extrys

    Joined:
    Oct 25, 2017
    Posts:
    345
    yes please
     
  3. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    727
    a good place to start learning is to just go to the Unity download archives and download the source code for the builtin shaders. just browse around, search for anything light probe related. skim through stuff like the ShadeSH9 macro.
     
  4. Extrys

    Extrys

    Joined:
    Oct 25, 2017
    Posts:
    345
    I meant, to add the light probes in a procedural way, so we can add new proves via code and change their positions and so
     
  5. thefranke

    thefranke

    Unity Technologies

    Joined:
    Jun 20, 2015
    Posts:
    153
    Hey Levitas,

    can you describe the way you procedurally generate your levels in a bit more detail? Are those spawned at regular positions? I.e. is this some kind of grid where you add rooms to other rooms at fixed positions?

    Cheers
     
  6. Doodel

    Doodel

    Joined:
    Sep 26, 2016
    Posts:
    17
    I just necroed a thread from 2012 in the general support forum (sorry for that) that asked the same question but is better placed here i guess.

    In the thread robert from Unity gives an answer to why Lightprobes.positions is read-only.:
    In Unity 2019.3 these missing functions were finally added: LightProbes.Tetrahedralize and LightProbes.TetrahedralizeAsync

    So now it seems there is a way to recalculate the lightprobe data in runtime but Lightprobes.positions is still read-only. Is this just an oversight or am I missing something here?
     
    NotaNaN and funkyCoty like this.
  7. Levitas

    Levitas

    Joined:
    Mar 17, 2015
    Posts:
    7
    As I understand it, I can load a set of light probes at run time and Tetrahedralize them, but I have to know where those light probes are going to be in world space beforehand.
    This won't work for us since we instantiate our room prefabs to create a random maze, so to speak.
    We need a way to save the light probes per prefab and convert from local to world space after level gen.
     
  8. thefranke

    thefranke

    Unity Technologies

    Joined:
    Jun 20, 2015
    Posts:
    153
    So, in relation to the geometry around them, probes are fixed in the prefabs and have fixed lighting, it's just that you want to instantiate those blocks of geometry to build the level, correct? I.e. each room is a kind of a closed lighting system?

    The probe system never allowed for modification after baking. I recently changed that so you one can at least additively load probes with the re-tetrahedralization feature, but I think we can loosen that restriction even further for prefabs. I got this noted in the probe backlog, but unfortunately I have no solution right now you could use.
     
  9. Levitas

    Levitas

    Joined:
    Mar 17, 2015
    Posts:
    7
    This is exactly what we need. Thank you very much for your time and effort here, it is greatly appreciated. We patiently wait for such an update.
     
  10. Extrys

    Extrys

    Joined:
    Oct 25, 2017
    Posts:
    345
    yeah, the exact thing available to do with additive scene loading would be amazing with prefabs.

    Anyways being able to change the positions so they are not readonly would make it easier to build our own procedural additive light probes
    and even creating a dots powered version for runtime baking

    Currently, if I want to do a transition between different backed light prove groups I'm restricted to change only the Spherical Harmonics and blend between them, but I can not do that with the positions nor creating my own randomizer for procedurally generated bake data

    Probably an option would be making the light probe data being stored inside the LightproveGroup component instead of the Scene, so switching between different backed light proveGroups components/prefabs could be a solution
     
  11. Daniel_Nagy

    Daniel_Nagy

    Joined:
    Feb 15, 2016
    Posts:
    4
    +1 for this, it would make workflow much easier!
     
    Extrys likes this.
  12. DGordon

    DGordon

    Joined:
    Dec 8, 2013
    Posts:
    649
    Anything to make GI + randomization not require lots of in depth knowledge or time trying to get it to work ... gets a huge +1 from me :).
     
    Extrys likes this.
  13. MicCode

    MicCode

    Joined:
    Nov 19, 2018
    Posts:
    59
    +1 to runtime modification of light probe
     
    Extrys likes this.
  14. l33t_P4j33t

    l33t_P4j33t

    Joined:
    Jul 29, 2019
    Posts:
    232
    if you are PROgrammer, you can do AssetBundle.LoadFromMemory(bytes[]) on a runtime generated asset bundle that has your desired light probe layout

     
  15. Aurigan

    Aurigan

    Joined:
    Jun 30, 2013
    Posts:
    291
    Another +1 for some way to use light probes in proc-gen layouts!
     
  16. apkdev

    apkdev

    Joined:
    Dec 12, 2015
    Posts:
    283
    My project needs this API too. Is there a technical reason why implementing this has been postponed for so long? Is the laughably scuffed Asset Bundle workaround really what I'll have to resort to?
     
  17. geonegames

    geonegames

    Joined:
    Sep 10, 2019
    Posts:
    4
    +1. Without the ability to change light probe positions at runtime, it's infeasible to use baked lighting in procedural games unless you're willing to effectively create your own implementation of light probes.

    Support for light probe groups in prefabs would be a magnificent addition.
     
  18. Extrys

    Extrys

    Joined:
    Oct 25, 2017
    Posts:
    345
    You actually can, you just need to copy the whole light probe data of the scene, modify the position of the copied data, and then re apply that data as the current light probe data
     
  19. apkdev

    apkdev

    Joined:
    Dec 12, 2015
    Posts:
    283
    upload_2022-1-24_13-39-5.png
     
  20. RPGia

    RPGia

    Joined:
    Jan 23, 2017
    Posts:
    44
    +1
     
  21. RPGia

    RPGia

    Joined:
    Jan 23, 2017
    Posts:
    44
  22. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    Any news on this?
     
  23. RPGia

    RPGia

    Joined:
    Jan 23, 2017
    Posts:
    44
  24. RPGia

    RPGia

    Joined:
    Jan 23, 2017
    Posts:
    44
  25. Pema-Malling

    Pema-Malling

    Unity Technologies

    Joined:
    Jul 3, 2020
    Posts:
    320
    Hey everyone, I’d like to point out a few release notes from the recent 2023.2.0a8 release, which should be useful to several of the users in this thread:

    > Graphics: Add API for modifying positions of LightProbes objects.
    > GI: Add API for accessing global light probe data used in rendering as well as for individual scenes.

    Essentially, we’ve added an API which allows moving light probes at runtime at the granularity of individual probe positions. Below is an example snippet from the documentation showing how to additively load a scene and move the probes associated with it. We’d like to expand a bit upon the API in the future, but it should cover most of the use cases we identified in its current state.

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. using UnityEngine.SceneManagement;
    4. public class MoveLightProbesExample : MonoBehaviour
    5. {
    6.     void Start()
    7.     {
    8.         StartCoroutine(LoadSceneAndMoveLightProbes());
    9.     }
    10.  
    11.     IEnumerator LoadSceneAndMoveLightProbes()
    12.     {
    13.         // Fully load a scene containing light probes additively.
    14.         Scene additiveScene = SceneManager.LoadScene("AdditiveScene", new LoadSceneParameters(LoadSceneMode.Additive));
    15.         yield return null;
    16.  
    17.         // Get the light probes for the scene.
    18.         LightProbes lightProbes = LightProbes.GetInstantiatedLightProbesForScene(additiveScene);
    19.  
    20.         // Move the light probes slightly.
    21.         Vector3[] positions = lightProbes.GetPositionsSelf();
    22.         for (int i = 0; i < positions.Length; i++)
    23.         {
    24.             positions[i] += Vector3.one;
    25.         }
    26.         lightProbes.SetPositionsSelf(positions, true);
    27.  
    28.         // Tetrahedralize to apply the changes to light probe positions.
    29.         LightProbes.TetrahedralizeAsync();
    30.     }
    31. }
    Looking forward to seeing how this will be used If you encounter issues, please use the bug reporter instead of posting here - it is much faster for us to notice and fix issues that way. I can answer questions about the API here, though.
     
    Shikoq, ilmario, saskenergy and 11 others like this.
  26. RPGia

    RPGia

    Joined:
    Jan 23, 2017
    Posts:
    44
    Hello, thank you for this update.

    What about the issue reported at:

    https://forum.unity.com/threads/lighting-data-asset-was-a-mistake.547591/#post-8936436
     
  27. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    265
    Would it be possible for there to be an additional API for resizing the positions array within the LightProbes object? I was very excited to see these APIs mentioned in the changelog but then found that I'm still not able to use light probes for runtime-generated scenes because I cannot resize the array :(

    The only workaround I know of is to pre-fill a blank "template" scene with a large number of dummy probes and then modify them at runtime, but that naturally comes with many limitations and can't cover multi-scene use cases.

    Other than this though, the APIs are great! It's a much-appreciated step forward for the lighting functionality available at runtime.
     
    RPGia likes this.
  28. Pema-Malling

    Pema-Malling

    Unity Technologies

    Joined:
    Jul 3, 2020
    Posts:
    320
    @TheZombieKiller Hey there. Thanks for the feedback, and for pointing out that your use case isn't sufficiently supported. I'll try to pick to my words carefully in this response, since I don't want to make any false promises. The use case you pointed it out is one of a few which we identified while working on the API, but decided not to support in the first iteration of it, instead focusing on the use case of piecing together pre-baked scenes at runtime. In other words, it is something we have tracked internally, but I can't give you an ETA, other than saying it is probably unlikely for 2023.1 or 2023.2.
     
    TheZombieKiller likes this.
  29. Pema-Malling

    Pema-Malling

    Unity Technologies

    Joined:
    Jul 3, 2020
    Posts:
    320
    To give a bit more context, the primary issue with this use case is that a LightProbes object currently stores data from an arbitrary amount of scenes, with an arbitrary amount of probe groups. This makes the meaning of resizing the data a bit ambiguous, and would invalidate some unexposed per-probe-group data, which we'd like to keep unexposed, since it's likely to change. That change would be breaking, though, and would affect our ability to be backwards compatible with existing light probe API, as well as the functionality of Enlighten RTGI.
     
    bdb400 and TheZombieKiller like this.
  30. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    265
    That makes much more sense and explains why the API is limited in the way it currently is, thanks! Just knowing that it's being tracked internally is good enough for me
     
    bdb400 likes this.
  31. RPGia

    RPGia

    Joined:
    Jan 23, 2017
    Posts:
    44
    So are you going with this solution? I'm interested in this. It sounds like you have to use lightmapped prefabs, and not lightmapped additive scenes with this method?
     
  32. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    265
    Right now what we do is use
    MaterialPropertyBlock.CopySHCoefficientArraysFrom
    to assign probe lighting via our own system, rather than using the built-in light probe system. It has lots of caveats though (an example being incompatibility with the SRP batcher) which is why it'd be preferable to use the built-in light probe system if possible, but the template scene workaround isn't good enough for our use cases.
     
    RPGia likes this.
  33. hungrybelome

    hungrybelome

    Joined:
    Dec 31, 2014
    Posts:
    336
    @TheZombieKiller I've heard that Unity is giving a zoom call tomorrow regarding getting access to Unity source code. Assuming this is for the c++ code and NOT the already publicly released c# wrappers, maybe we can find the light probe code and use it to reverse engineer the asset bundles to manually adjust light probes (and add new ones), like one guy did in his GDC talk. Any thoughts?
     
  34. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    265
    I'm not aware of any Zoom call announcements, can you elaborate?
     
  35. lanalana

    lanalana

    Joined:
    Dec 29, 2017
    Posts:
    5
    I'm looking forward to this features in an LTS version of Unity. Does anyone have recommendations with HDRP in the meantime?
     
  36. gshape

    gshape

    Joined:
    Aug 8, 2012
    Posts:
    104

    is there a way to access the connectivity of the tetrahedrons? for example
    1. int n = lightProbes.GetProbeIndicesNonAlloc(position, probeIndiceArray);
    2. int n = lightProbes.GetConnectedProbesNonAlloc(probeIndex, connectedProbeIndiceArray);
     
    ebaender likes this.
  37. Pema-Malling

    Pema-Malling

    Unity Technologies

    Joined:
    Jul 3, 2020
    Posts:
    320
    I don't believe we currently have any API that can give you that. If you need this, I suggest submitting an idea to our roadmap here https://portal.productboard.com/uni...s/c/561-didn-t-find-what-you-were-looking-for
     
    gshape and ebaender like this.
  38. Shikoq

    Shikoq

    Joined:
    Aug 5, 2023
    Posts:
    12
    Hey @Pema-Malling !
    Quick question – does this API cater exclusively to old Light Probes, or does it also support Probe Volumes? If it's not compatible with Probe Volumes, could you recommend any API that does? I'm particularly interested in any that allow real-time modifications. Thanks!
     
  39. Pema-Malling

    Pema-Malling

    Unity Technologies

    Joined:
    Jul 3, 2020
    Posts:
    320
    The API is only for the older tetrahedral light probe system. There is no equivalent API for adaptive probe volumes, and I don't believe there are any plans to make one. If you need something like that, you can always add feedback on our productboard portal https://portal.productboard.com/uni...s/c/561-didn-t-find-what-you-were-looking-for
     
  40. RPGia

    RPGia

    Joined:
    Jan 23, 2017
    Posts:
    44
    @Pema-Malling This post says:
    • Users can build modular scenes and instantiate them in a “hub” scene, the API enables light probes position to be updated at runtime
    https://portal.productboard.com/uni...ime?utm_medium=social&utm_source=portal_share


    This implies that we can use the new API to generate procedurally generated scenes composed of modular scenes that are additively loadd, and the dynamically changing light probe should just work.

    However, as per your discussion with @TheZombieKiller , it sounds like we can only change the positions of lightprobes from a fixed light probe count, so additively loading scenes at runtime would not work, since that light probe count would be changing.

    Am I understanding this correctly?

    Basically, I just want to be able to additively load multiple scenes and compose them at runtime like lego blocks to build a proc gen game level.
     
  41. ght1875

    ght1875

    Joined:
    Jul 29, 2016
    Posts:
    32
    Not sure why I get 0 light probes back from GetInstantiatedLightProbesForScene.
    I am on 2023.2.3f1. dx11,12 are broken for baking, using vulkan instead.
    Tried both baking mode single scene and baking sets. Both return 0 light probes.
    Rendering debugger shows up light probes correctly.
     
    Last edited: Jan 2, 2024
  42. Renardjojo

    Renardjojo

    Joined:
    May 15, 2019
    Posts:
    13
    I am in 2022. My solution to workaround this issue was to copy the property block of my renderer and set spherical harmonics manually to move my light probe

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Rendering;
    3.  
    4. [RequireComponent(typeof(Renderer))]
    5. public class LightProbObject : MonoBehaviour
    6. {
    7.     private Renderer m_Renderer;
    8.     void Start()
    9.     {
    10.         m_Renderer = GetComponent<Renderer>();
    11.         m_Renderer.lightProbeUsage = LightProbeUsage.CustomProvided;
    12.     }
    13.  
    14.     private void Update()
    15.     {
    16.         LightProbeGroup lightGroup = FindObjectOfType<LightProbeGroup>(false);
    17.  
    18.         if (lightGroup)
    19.         {
    20.             // Hack to move light probes at runtime. This feature was added in 2023
    21.             // https://forum.unity.com/threads/prefab-level-generation-light-probe-support.999266/#post-8914573
    22.             Vector3[] positions = new Vector3[1] {transform.position - lightGroup.transform.position};
    23.             SphericalHarmonicsL2[] lightProbes = new SphericalHarmonicsL2[1];
    24.             Vector4[] occlusionProbes = new Vector4[1];
    25.             LightProbes.CalculateInterpolatedLightAndOcclusionProbes(positions, lightProbes, occlusionProbes);
    26.  
    27.             for (int index = 0; index < m_Renderer.sharedMaterials.Length; index++)
    28.             {
    29.                 MaterialPropertyBlock property = new();
    30.                 m_Renderer.GetPropertyBlock(property, index);
    31.                 property.CopySHCoefficientArraysFrom(lightProbes);
    32.                 m_Renderer.SetPropertyBlock(property, index);
    33.             }
    34.         }
    35.     }
    36. }
     
  43. Pema-Malling

    Pema-Malling

    Unity Technologies

    Joined:
    Jul 3, 2020
    Posts:
    320
    Hmm, that's strange. I don't really have any other advice than to file a bug report.
     
  44. Pema-Malling

    Pema-Malling

    Unity Technologies

    Joined:
    Jul 3, 2020
    Posts:
    320
    You can additively load several scenes, each of which contain baked light probes. Then you call GetInstantiatedLightProbesForScene on each of those scenes. That gives you a LightProbes object for each scene. You can move probes contained within each object using SetPositionsSelf. The next time you call Tetrahedralize, the changes will be applied.

    The only thing the API doesn't allow for is adding or removing probes in a scene. To be able to move probes in a scene, the scene must already contain baked probes - you can't invent new ones at runtime. The mechanism for adding or removing probes is to (additively) load or unload scenes. Basically, SetPositionsSelf will only accept an array matching the current probe count in the given LightProbes object.
     
    RPGia likes this.
  45. ght1875

    ght1875

    Joined:
    Jul 29, 2016
    Posts:
    32
    It turns out even it is supposed to be a modular workflow, you still need to bake the modular scenes together with the hub scene(active scene), so the lighting data asset in the active scene has reference to the modular scenes.
     
  46. malikcgcs

    malikcgcs

    Joined:
    Jun 11, 2013
    Posts:
    9
  47. malikcgcs

    malikcgcs

    Joined:
    Jun 11, 2013
    Posts:
    9
    @Pema-Malling

    Can I use any of this to create an optimized lighting solution for dynamic scenes created at runtime from GLB models downloaded from APIs?
     
  48. Pema-Malling

    Pema-Malling

    Unity Technologies

    Joined:
    Jul 3, 2020
    Posts:
    320
    If your scenes are created entirely at runtime, I imagine you want to bake lighting for them at runtime? The API cannot be used for that. We don't support any kind of runtime baking
     
  49. gilley033

    gilley033

    Joined:
    Jul 10, 2012
    Posts:
    1,191
    This is not strictly true. Light probe data IS baked to a Lighting Data asset that is associated with the active scene at the time of baking, however when loading the modular scenes at runtime, you can leave your active scene set to the hub scene.

    To do this, you need to create a new scene for each bake (for different areas of your world), make them active before baking, then perform the bake.

    Of course, this isn't trivial without some sort of system for automation (shameless plug - I'll be adding this type of system in the next update of my product, S.A.M. - The Streamable Assets Manager).
     
    Last edited: Apr 2, 2024
  50. gilley033

    gilley033

    Joined:
    Jul 10, 2012
    Posts:
    1,191
    Are there any plans to backport this to older versions?

    Also, in the case of shifting all light probes by the same amount (to support a floating origin for example), would it be more efficient in Unity's internal code to use a different method than this?

    It just seems kind of burdensome to have to sift through all loaded scenes, create the position arrays, and shift all of the individual probe positions by the same amount. For example, there seems to be a lot of array allocations that could be eliminated if internally (assuming you have some sort of array storing the positions), you could just modify the positions in place via a method call like:
    Code (CSharp):
    1. public void ShiftAllProbes(Vector3 amount)
     
    Last edited: Mar 31, 2024