Search Unity

Update LightProbe data with moving DrawMeshInstancedIndirect

Discussion in 'Global Illumination' started by alexr4, Dec 27, 2020.

  1. alexr4

    alexr4

    Joined:
    Nov 16, 2013
    Posts:
    1
    Hi everyone,

    Lately, I am working a lot with DMII with compute shader in order to have multiple moving object in my scene. Here is an example of some experiments I've made : https://www.instagram.com/p/CILdJNJoDsu/
    In order to upgrade my skill, I've decided to learn more about LightProbe and Global Illumination.

    As I want to keep consistency with the pipeline I use at work, I decided to work in legacy mode, so no URP, no VFX graph or ShaderGraph involved.

    I've understand how to bind LightProbe data to the DMII shader using a structured buffer and
    Code (CSharp):
    1. LightProbes.CalculateInterpolatedLightAndOcclusionProbes
    As my instances will move inside my scene I need to update this data.
    The quicker way I found is to retreive my positions from my compute shader and recompute the LightProbes data before udapting its structured buffer. It's working but as I retreiving data from the compute shader it can be really intensive as I have the following pipeline :
    1. GPU to CPU: retreives updated position data
    2. Compute LightProbes data (CPU side)
    3. Update structured buffer for LP data and bind to GPU
    Here is the result. It runs at 30FPS, 10K instances, 4K with Post-Process (AO, Bloom, Flare, ColorGrad...) (GTX 1060Ti + i7 2.6Ghz)


    I was wondering if there would be a quicker way to update this data?
    Maybe updating it directly inside a compute shader in order to keep all the data on GPU side avoiding reading it back on CPU side.

    Here is the code parts for updating the lightprobes data :

    Code (CSharp):
    1.  
    2. private void UpdateLightProbesData(){
    3.         meshPropertiesBuffer.GetData(properties); //Get data from Compute Shader
    4.         for(int i=0; i<numberOfInstance; i++){
    5.             MeshProperties props    = properties[i];//MeshProperties is a struct with various data (TRS and data per instance)
    6.             positions[i]            = props.transform.GetColumn(3); //Get the position from the Transform matrix. Positions array is set at start.
    7.         }
    8.  
    9.         LightProbes.CalculateInterpolatedLightAndOcclusionProbes(positions, lightprobes, occlusionprobes); //compute LP data for each positions
    10.         for(int i=0; i<numberOfInstance; i++){
    11.             LightProbesDatas probe = new LightProbesDatas();
    12.            //Get coefficient and bind to compute buffer
    13.             UnityEngine.Rendering.SphericalHarmonicsL2 sh = lightprobes[i];
    14.             probe.SHAr = new Vector4(sh[0, 3], sh[0, 1], sh[0, 2], sh[0, 0] - sh[0, 6]);
    15.             probe.SHAg = new Vector4(sh[1, 3], sh[1, 1], sh[1, 2], sh[1, 0] - sh[1, 6]);
    16.             probe.SHAb = new Vector4(sh[2, 3], sh[2, 1], sh[2, 2], sh[2, 0] - sh[2, 6]);
    17.             probe.SHBr = new Vector4(sh[0, 4], sh[0, 6], sh[0, 5], sh[0, 7]);
    18.             probe.SHBg = new Vector4(sh[1, 4], sh[1, 6], sh[1, 5], sh[1, 7]);
    19.             probe.SHBb = new Vector4(sh[2, 4], sh[2, 6], sh[2, 5], sh[2, 7]);
    20.             probe.SHC  = new Vector4(sh[0, 8], sh[2, 8], sh[1, 8], 1);
    21.             probes[i]  = probe;
    22.         }
    23.  
    24.         lightProbeBuffer.SetData(probes); //update structured buffer bound to GPU
    25.     }
     
    eggsamurai likes this.