HDR Rendering & Legacy Sky Adjustments - ApertureViewer/Aperture-Viewer GitHub Wiki

1. Introduction

Modern rendering pipelines, such as the one employed in the Second Life viewer featuring Physically Based Rendering (PBR) and Environmental Enhancement Project (EEP) capabilities, heavily utilize High Dynamic Range (HDR) rendering. HDR allows for a much wider range of brightness levels than traditional Standard Dynamic Range (SDR), resulting in more realistic lighting, richer colors, and the prevention of color banding artifacts.

However, Second Life has a long history and contains numerous user-created environment assets ("Windlights," specifically sky presets) that predate the introduction of PBR and HDR. These "legacy" assets were designed for an SDR pipeline. To bridge this gap and allow users to leverage HDR benefits even with older assets, a set of configuration settings exist to control HDR activation and automatically adjust legacy sky presets for better compatibility with the modern renderer.

This document details the function, usage, impact, and testing procedures for:

  • The primary HDR toggle (RenderHDREnabled).
  • The group of settings related to legacy sky auto-adjustment (RenderSkyAutoAdjustLegacy, RenderSkyAutoAdjust*Scale factors).
  • General lighting scale factors (Render*SunlightScale, RenderSkyAmbientScale).
  • The tonemapping mix control (RenderTonemapMix).
  • An analysis of potentially deprecated legacy settings (SkyAmbientScale, SkyNightColorShift).

These settings are primarily utilized within the LLSettingsVOSky::applySpecial function located in llcommon/llsettingsvo.cpp, which is responsible for translating sky asset data into shader uniforms.

Note

In Aperture Viewer, many of these underlying debug settings are managed or influenced by the Aperture Graphics Presets System and can be observed or fine-tuned via the APS - Environment (Evn) Tab and APS - Post-Processing (Post) Tab.

2. Core HDR Setting: RenderHDREnabled

  • Setting Name (Debug): RenderHDREnabled
  • Type: Boolean
  • Default Value: 1 (True) (as per typical XML configurations reflecting modern defaults)
  • Code Variable Reference: static LLCachedControl<bool> hdr(gSavedSettings, "RenderHDREnabled");

2.1. Function/Purpose

This setting acts as the master switch for enabling or disabling the High Dynamic Range (HDR) rendering pipeline. When enabled, the viewer renders scenes using a wider range of color and luminance values internally before typically tonemapping the result for display on standard monitors. This is fundamental for PBR materials and advanced lighting effects.

2.2. Code Usage Example (llsettingsvo.cpp)

The hdr() accessor (or its cached value) is checked within LLSettingsVOSky::applySpecial primarily to select the appropriate sunlight scaling factor for shaders:

// Selects between RenderHDRSkySunlightScale and RenderSkySunlightScale
shader->uniform1f(LLShaderMgr::SKY_SUNLIGHT_SCALE, hdr() ? sunlight_hdr_scale : sunlight_scale);

Its state also implicitly affects the entire rendering pipeline, determining whether HDR-capable framebuffers are used (e.g., GL_RGBA16F) and whether HDR post-processing stages like tonemapping are active (see LLPipeline::renderFinalize).

2.3. Performance Impact

  • Enabled (true): Significantly increases GPU load and VRAM usage. HDR rendering requires larger framebuffers (often using floating-point formats like FP16) and additional processing steps like tonemapping. This can lead to a noticeable decrease in Frames Per Second (FPS), especially on lower-end or older GPUs.
  • Disabled (false): Reverts to a simpler Standard Dynamic Range (SDR) rendering path, reducing GPU load and VRAM consumption, generally resulting in higher FPS.

2.4. Visual Impact

  • Enabled (true): Provides a significantly wider range of brightness, allowing for very bright highlights (like the sun or intense glows) alongside detailed shadows without harsh clipping. Colors generally appear richer and more nuanced. Prevents color banding in smooth gradients (e.g., skies). May introduce effects like bloom around bright objects. Overall scene lighting feels more realistic and immersive, and is essential for PBR materials to appear as intended.
  • Disabled (false): Limits the brightness range. Bright areas are prone to washing out (clipping to white), and dark areas can lose detail (crushing to black). Colors may appear less vibrant. Gradients might exhibit noticeable banding. The overall look is less dynamic compared to HDR.

2.5. Default Value Rationale

The default of true reflects the adoption of HDR as the standard for modern visuals in Second Life and Aperture Viewer, assuming users have hardware capable of supporting it reasonably well.

2.6. Recommended Value

  • High-End Hardware / Max Fidelity: true. Essential for achieving the best visual quality and leveraging PBR/EEP features fully.
  • Low-End Hardware / Max Performance: false. Disabling HDR is a primary way to improve performance if FPS is too low, but at a significant cost to visual fidelity.

3. Legacy Sky Auto-Adjustment Settings

This group of settings controls whether and how the viewer attempts to modify "legacy" sky presets (those created before EEP/PBR, typically lacking a ReflectionProbeAmbiance value) to look more integrated with the HDR/PBR rendering pipeline.

3.1. RenderSkyAutoAdjustLegacy

  • Setting Name (Debug): RenderSkyAutoAdjustLegacy
  • Type: Boolean
  • Default Value: 0 (False) (as per XML and LLCachedControl fallback in code)
  • Code Variable Reference: static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", false);

3.1.1. Function/Purpose

This setting enables (true) or disables (false) the automatic adjustment mechanism for legacy sky presets.

  • If true, and the currently active sky preset is identified as "legacy" (internally, psky->canAutoAdjust() is true, which typically means it lacks a ReflectionProbeAmbiance value), the viewer will apply the various RenderSkyAutoAdjust*Scale factors (detailed below) to modify its appearance and will use a hardcoded default probe ambiance (sAutoAdjustProbeAmbiance).
  • If false (the default), legacy skies are rendered more closely to their original SDR intent, without these automatic HDR/PBR compatibility scaling factors. This is referred to as "Classic Mode" in the code (classic_mode = psky->canAutoAdjust() && !should_auto_adjust();).

3.1.2. Code Usage Example (llsettingsvo.cpp)

Determines the classic_mode flag and controls a conditional block in LLSettingsVOSky::applySpecial:

// sky is a "classic" sky following pre SL 7.0 shading
bool classic_mode = psky->canAutoAdjust() && !should_auto_adjust();
// ...
shader->uniform1i(LLShaderMgr::CLASSIC_MODE, classic_mode);
LLRender::sClassicMode = classic_mode; // Global flag
// ...
// Inside the main conditional logic:
else if (psky->canAutoAdjust() && should_auto_adjust()) // Note: should_auto_adjust() is the accessor for the LLCachedControl
{ 
    // auto-adjust legacy sky to take advantage of probe ambiance
    // Apply auto_adjust_* scales here...
    probe_ambiance = sAutoAdjustProbeAmbiance; // Uses a hardcoded default ambiance (e.g., 0.75f)
    shader->uniform1f(LLShaderMgr::REFLECTION_PROBE_AMBIANCE, probe_ambiance);
    // ...other adjustments...
}

3.1.3. Performance Impact

Negligible. It's a simple boolean check controlling which set of values are sent to the shader. The complexity of the sky shader itself doesn't significantly change based on this flag alone, though the resulting lighting can indirectly affect overall scene rendering cost.

3.1.4. Visual Impact

  • Enabled (true): Legacy skies will generally appear brighter, potentially with more saturated colors and stronger ambient lighting, attempting to mimic the look of modern EEP skies that have probe ambiance defined. The specific look is determined by the RenderSkyAutoAdjust*Scale values. This can make legacy environments feel more integrated with PBR objects but inherently alters the original artistic intent.
  • Disabled (false): Legacy skies retain a look closer to their original appearance in older, SDR viewers. Lighting might appear flatter, less intense, and less well-integrated with PBR materials compared to modern EEP skies or auto-adjusted legacy skies.

3.1.5. Default Value Rationale

The default of false is likely chosen as the "safer" option. It avoids altering the appearance of potentially cherished legacy environments without explicit user action, preserving the original creator's intent by default.

3.1.6. Recommended Value

User preference.

  • Set to true if you want legacy skies to attempt better integration with PBR/HDR lighting, even if it changes their original look.
  • Set to false if you prefer to see legacy skies as close to their original design as possible, even if they look less dynamic or integrated than modern EEP skies.

3.2. RenderSkyAutoAdjust*Scale Settings

These settings only take effect when RenderSkyAutoAdjustLegacy is true and a legacy sky is active. They provide multipliers to adjust specific components of the legacy sky's appearance during the auto-adjustment process.

  • RenderSkyAutoAdjustAmbientScale

    • Type: F32
    • Default: 0.75f (from LLCachedControl fallback; XML might differ but code default is key if missing)
    • Purpose: Multiplies the legacy sky's original ambient color. A value < 1.0 reduces ambient intensity, > 1.0 increases it. Default 0.75f suggests slightly reducing it.
    • Code Usage: shader->uniform3fv(LLShaderMgr::AMBIENT, (ambient * auto_adjust_ambient_scale).mV);
  • RenderSkyAutoAdjustHDRScale

    • Type: F32
    • Default: 2.0f (from LLCachedControl fallback; XML might be 1.0f - code default often takes precedence if XML is missing or for initial values).
    • Purpose: Sets the SKY_HDR_SCALE shader uniform specifically during legacy auto-adjustment. This scales the overall brightness/intensity influence of the sky for HDR calculations. A value of 2.0f suggests significantly boosting the perceived HDR intensity of legacy skies.
    • Code Usage: shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, auto_adjust_hdr_scale);
  • RenderSkyAutoAdjustBlueHorizonScale

    • Type: F32
    • Default: 1.0f
    • Purpose: Multiplies the legacy sky's blue horizon color component.
    • Code Usage: LLColor3 blue_horizon = getBlueHorizon() * auto_adjust_blue_horizon_scale; shader->uniform3fv(LLShaderMgr::BLUE_HORIZON, blue_horizon.mV);
  • RenderSkyAutoAdjustBlueDensityScale

    • Type: F32
    • Default: 1.0f
    • Purpose: Multiplies the legacy sky's blue density color component.
    • Code Usage: LLColor3 blue_density = getBlueDensity() * auto_adjust_blue_density_scale; shader->uniform3fv(LLShaderMgr::BLUE_DENSITY, blue_density.mV);
  • RenderSkyAutoAdjustSunColorScale

    • Type: F32
    • Default: 1.0f
    • Purpose: Multiplies the legacy sky's sun color.
    • Code Usage: sun_light_color = sun_light_color * auto_adjust_sun_color_scale; shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, sun_light_color.mV);

3.2.1. Performance Impact (Collective RenderSkyAutoAdjust*Scale settings)

Negligible. These are simple floating-point multiplications applied to values before they are sent as uniforms to the shader, only when auto-adjustment is active.

3.2.2. Visual Impact (Collective RenderSkyAutoAdjust*Scale settings)

These settings collectively fine-tune how a legacy sky is modified when RenderSkyAutoAdjustLegacy is enabled. They allow control over the intensity of ambient light, the overall HDR effect strength derived from the sky, specific sky coloration (blues), and the sun's color contribution during the automatic adjustment. The default values aim for a specific adjusted aesthetic (e.g., brighter HDR sky effect, slightly reduced base ambient, unchanged specific blue/sun colors unless overridden).

3.2.3. Default Value Rationale

The defaults (especially auto_adjust_hdr_scale = 2.0f and auto_adjust_ambient_scale = 0.75f) represent the viewer developers' chosen baseline for making legacy skies appear more compatible with the HDR/PBR pipeline, likely determined through internal visual testing.

3.2.4. Recommended Value

Generally, leave these at their defaults unless you have a specific artistic reason to tweak the auto-adjustment behavior. Modifying them requires enabling RenderSkyAutoAdjustLegacy and then experimenting with various legacy sky presets to achieve a desired altered look.

4. General Compatibility & Tuning Scales

These settings provide broader adjustments for sky lighting, often related to matching behavior with pre-PBR viewers or for general artistic tuning. They are not exclusively tied to the legacy auto-adjustment feature but can interact with it.

4.1. RenderSkySunlightScale & RenderHDRSkySunlightScale

  • Setting Names (Debug): RenderSkySunlightScale, RenderHDRSkySunlightScale
  • Type: F32
  • Default Value: 1.5f (from LLCachedControl fallback); XML might specify 1.0f. The code default (1.5f) is often influential if the XML value isn't explicitly set or for initial states.
  • Purpose: These act as overall multipliers ("fudge factors") for the calculated sunlight intensity passed to the shaders via the SKY_SUNLIGHT_SCALE uniform.
    • RenderSkySunlightScale: Used when HDR is disabled (RenderHDREnabled = false).
    • RenderHDRSkySunlightScale: Used when HDR is enabled (RenderHDREnabled = true). They likely exist to help tune the perceived brightness of the sun to better match legacy viewer behavior or allow artistic preference under both SDR and HDR rendering modes.
  • Code Usage (llsettingsvo.cpp):
    shader->uniform1f(LLShaderMgr::SKY_SUNLIGHT_SCALE, hdr() ? sunlight_hdr_scale : sunlight_scale);

4.2. RenderSkyAmbientScale

  • Setting Name (Debug): RenderSkyAmbientScale
  • Type: F32
  • Default Value: 1.5f (from LLCachedControl fallback); XML might specify 1.0f.
  • Purpose: A general multiplier for the ambient light contribution from the sky, passed to shaders via the SKY_AMBIENT_SCALE uniform. It applies regardless of whether legacy auto-adjustment is active, although the base ambient value it multiplies might have already been affected by the auto-adjustment scales if a legacy sky is active and auto-adjust is on.
  • Code Usage (llsettingsvo.cpp):
    shader->uniform1f(LLShaderMgr::SKY_AMBIENT_SCALE, ambient_scale);

4.3. RenderTonemapMix

  • Setting Name (Debug): RenderTonemapMix
  • UI Control (Aperture Viewer): APS Post Tab -> "Tone Mix" slider.
  • Type: F32
  • Default Value: 0.7f (from XML); LLCachedControl fallback might be 1.0f. The XML value is typically the operational default. In Aperture Viewer, the default for its Graphics Presets is often 0.0.
  • Purpose: Controls the interpolation between the raw, linear HDR color output (after exposure but before tonemapping) and the final tonemapped color.
    • 0.0: Shows the linear color (likely appears washed out or overly bright/dark on an SDR display without further adjustment).
    • 1.0: Shows the fully tonemapped color (dynamic range compressed, contrast/saturation adjusted for display).
    • Values in between blend these two states. This setting is applied unless classic_mode is active (i.e., it applies to modern EEP skies and auto-adjusted legacy skies, but not to non-adjusted legacy skies).
  • Code Usage (Conceptual - set in llsettingsvo.cpp, applied in postDeferredTonemap.glsl):
    // In llsettingsvo.cpp, when not in classic_mode:
    if (!classic_mode)
    {
        psky->setTonemapMix(tonemap_mix_setting); // Stores the value
    }
    The actual mixing happens in the postDeferredTonemap.glsl shader using the tonemap_mix uniform.

    [!NOTE] Aperture Viewer features an improved tonemap_mix logic that blends with the exposed linear input before final LDR clamping, preserving HDR detail better during the mix.

4.4. Performance Impact (General Scales: *SunlightScale, SkyAmbientScale, TonemapMix)

Negligible. These are simple multipliers or interpolation factors used within shader calculations, with minimal direct performance cost.

4.5. Visual Impact (General Scales)

  • Render*SunlightScale: Directly affect the perceived brightness/intensity of the sun/moon and the direct lighting derived from it. Values > 1.0 make the sun brighter; < 1.0 make it dimmer than the base sky calculation.
  • RenderSkyAmbientScale: Affects the intensity of global ambient light from the sky. Values > 1.0 increase ambient brightness (filling shadows more); < 1.0 decrease it.
  • RenderTonemapMix: Affects the final image's contrast, saturation, and overall "look" when HDR is enabled and not in classic mode. Values closer to 1.0 typically result in a punchier, more contrasted image suitable for SDR displays. Values closer to 0.0 result in a flatter, more linear look, preserving more raw HDR information but potentially appearing dull directly on an SDR display. The default of 0.7 (from XML) historically aimed for a strong but not complete application of the tonemapper. Aperture Viewer's graphics presets default Tone Mix to 0.0 to give users a neutral starting point for its advanced Post-Processing controls.

4.6. Default Value Rationale (General Scales)

  • The Render*SunlightScale and RenderSkyAmbientScale defaults of 1.5f (often from code fallbacks) suggest an intentional baseline boost to sun and ambient light compared to raw calculations, possibly for better visual parity with older viewer versions or simply for a brighter default aesthetic if not overridden by XML.
  • The RenderTonemapMix default of 0.7f (often from XML) likely represented a balance judged to give good results on typical displays before extensive per-user post-processing was common.

4.7. Recommended Value (General Scales)

  • Render*SunlightScale, RenderSkyAmbientScale: Start with defaults (which might be 1.0 if defined in settings.xml, or 1.5 if using code fallbacks). Adjust based on artistic preference for overall scene brightness and direct sun/moon intensity. These are effectively global brightness tuners for sky-derived light.
  • RenderTonemapMix (Aperture Viewer UI: "Tone Mix"):
    • Aperture Viewer graphics presets default this to 0.0 to provide a neutral base for its advanced Post-Processing Tab.
    • Users can increase towards 1.0 to see more of the selected tonemapper's effect (Khronos Neutral or ACES), or keep it low and use Aperture's detailed Post-Processing controls for tone shaping.

5. Interactions and Dependencies Summary

  • RenderHDREnabled is the master switch. If false, HDR-specific effects and scales (like RenderHDRSkySunlightScale and the advanced tonemapping path) are inactive.
  • RenderSkyAutoAdjustLegacy only has an effect if the loaded sky preset is identified as "legacy" (i.e., psky->canAutoAdjust() is true).
  • The various RenderSkyAutoAdjust*Scale settings only apply if RenderSkyAutoAdjustLegacy is true AND a legacy sky is active.
  • RenderSkySunlightScale is used only when RenderHDREnabled is false.
  • RenderHDRSkySunlightScale is used only when RenderHDREnabled is true.
  • RenderSkyAmbientScale applies generally to the sky's ambient contribution, but the base ambient value it multiplies might have already been adjusted by RenderSkyAutoAdjustAmbientScale if a legacy sky is active with auto-adjust enabled.
  • RenderTonemapMix applies when RenderHDREnabled is true AND classic_mode is false (i.e., for modern EEP skies or auto-adjusted legacy skies).

6. Analysis of Deprecated Legacy Settings: SkyAmbientScale and SkyNightColorShift

Within llcommon/lllegacyatmospherics.cpp, two settings, SkyAmbientScale and SkyNightColorShift, are read from gSavedSettings into member variables mAmbientScale and mNightColorShift respectively during LLAtmospherics object construction.

  • SkyAmbientScale (Default 0.3f): Intended to scale ambient light in the legacy system.
  • SkyNightColorShift (Default [0.67, 0.67, 1.0]): Intended to shift the color of night lighting in the legacy system.

Finding: A review of lllegacyatmospherics.cpp shows that while these member variables (mAmbientScale, mNightColorShift) are initialized, they are not subsequently used in any of the atmospheric or lighting calculations within that file or referenced by the modern sky rendering path controlled by LLSettingsVOSky.

Conclusion for SkyAmbientScale and SkyNightColorShift: These settings appear to be deprecated and non-functional in the context of the current EEP/PBR rendering pipeline. They are likely remnants of the older Windlight system that have not been removed from the settings files or the legacy atmospherics class but no longer influence the final rendered scene. Users can safely ignore these settings. Adjusting them will produce no observable visual change. The modern equivalents are RenderSkyAmbientScale (for general ambient tuning) and the direct MoonlightColor (and other related color) properties within EEP sky assets for night lighting color.

7. Testing Procedures

Key aspects to verify through testing:

  • The visual and performance impact of toggling RenderHDREnabled.
  • The visual changes when RenderSkyAutoAdjustLegacy is toggled for legacy skies, and how the RenderSkyAutoAdjust*Scale factors influence this.
  • The conditions under which classic_mode becomes true and its visual effect.
  • The impact of Render*SunlightScale and RenderSkyAmbientScale on overall lighting.
  • The visual effect of RenderTonemapMix (especially the Aperture default of 0.0 vs. values approaching 1.0).
  • Confirmation that SkyAmbientScale and SkyNightColorShift produce no visual changes under any modern rendering configuration.
⚠️ **GitHub.com Fallback** ⚠️