Atlassian uses cookies to improve your browsing experience, perform analytics and research, and conduct advertising. Accept all cookies to indicate that you agree to our use of cookies on your device. Atlassian cookies and tracking notice, (opens new window)

Enlighten SDK 3.10 Documentation
Results will update as you type.
  • Welcome to Enlighten
  • How Enlighten works
  • Artist workflow
  • Install Enlighten
  • Libraries
  • Implementation guide
  • Technical reference
    • Output formats
    • Albedo handling
    • Lightmap lighting models
    • Light probe evaluation
    • Local IBL reflections
    • Light visibility data
    • Custom direct lights
    • Precompute pipeline
    • Low level precompute API
    • Debugging the precompute
    • The low level runtime
      • Low level runtime walkthrough
        • Preparing the runtime
        • Per-frame walkthrough
          • Providing input lighting
          • Solving for irradiance
          • Solving for directional irradiance
          • Solving for probe points
          • Probe interpolation
          • Resampling bounce
        • Multiple systems at runtime
        • Low level cubemap API
      • Input lighting
      • Debug the low level runtime
    • Baked lighting
    • Performance tuning
    • Technical troubleshooting
    • Terrain LOD
    • Probe LOD
    • Lightmap LOD
  • Advanced techniques
  • Tools
  • Enlighten Mobile
  • White papers
  • Third-party licences
  • Release notes
    Calendars

You‘re viewing this with anonymous access, so some content might be blocked.
/
Solving for irradiance

    This is the documentation for Enlighten.

    Solving for irradiance

    Nov 21, 2019


    Overview

    After you have computed and fixed all of the input lighting in the scene (or at the very least, all of the input for the systems that are dependencies of the one you want to solve), the next step is the main radiosity solve task. It consists of the following steps:

    1. Prepare structure

    First prepare the structure describing the task:

    RadIrradianceTask irradianceTask;
    irradianceTask.m_CoreSystem = radCore;
    

    2. Prepare list of input workspaces

    The solver expects to be passed a list of input lighting buffers, one for each of its dependencies, in the correct order. There is a helper function to prepare this list, as shown in the code sample below.

    The only input lighting buffer that you absolutely must pass is the one corresponding to the system you wish to solve. All the others are optional; however, no light will be transferred from missing systems.

    irradianceTask.m_InputLighting        = GEO_NEW_ARRAY(const InputLightingBuffer*, Enlighten::GetInputWorkspaceListLength(radCore));
    Enlighten::PrepareInputLightingList(radCore, const_cast<const InputLightingBuffer**>(&inputLightingBuffer), 1, irradinceTask.m_InputLighting);
    // prepare the ordered list of input lighting buffers
    
    irradianceTask.m_Environment                = emissiveEnvironment;
    // optional emissive environment
    
    irradianceTask.m_OutputFormat               = Enlighten::ENLIGHTEN_FORMAT_FP16;
    // output values as 16-bit floating point vectors
    
    irradianceTask.m_OutputScale                = 1.0f;
    // no extra scaling on output
    
    irradianceTask.m_OutputStride               = radCore->m_MetaData.m_OutputWidth;
    // lazily assuming stride = width, not always true!
    
    irradianceTask.m_IrradianceOutput           = irradianceOutput;
    // must be persistent if using temporal optimisation
    
    irradianceTask.m_PersistentData             = persistentData;
    // required for temporal coherence and other data that persists between frames.
    
    irradianceTask.m_TemporalCoherenceThreshold = 0.01f;
    // set to -1 to not use temporal optimisation
    

    This code sample requests irradiance output in 16-bit floating point format. However, it is possible to store irradiance data using half the memory with an almost undetectable difference in quality. The trade-off is that you need a few more instructions in the final shader to decode the values. For more information, see LRB Compressed Output Format for Irradiance.

    3. Solve for irradiance

    Now call the function to solve for irradiance, passing the task structure and the working scratchspace memory:

    Geo::u32 timeTakenInMicroseconds, numSolvedPixels;
    bool success = SolveIrradianceTask(&irradianceTask, irradianceWorking, timeTakenInMicroseconds, numSolvedPixels);
    

    If the temporal coherence optimisation is used, it requires that all systems are kept in sync so that no changes in lighting are missed. Nevertheless, some systems can be updated less frequently than others by using the Freeze functions in place of a solve. FreezeIrradianceTask performs the minimal housekeeping required to keep track of light changes for the temporal optimisation; no output textures are updated. The input parameters are exactly the same as for SolveIrradianceTask:

    Geo::u32 timeTakenInMicroseconds, numSolvedPixels;
    bool success = FreezeIrradianceTask(&irradianceTask, irradianceWorking, timeTakenInMicroseconds, numSolvedPixels);
    

    4. Place data in texture

    Finally, when the output data has been written, the application places the data in a texture that is visible by the GPU, so that it can be used for final on-screen rendering.

    , multiple selections available,
    {"serverDuration": 10, "requestCorrelationId": "1143b7266ea842dca344e3b079977741"}