Glow Effect Settings - ApertureViewer/Aperture-Viewer GitHub Wiki

Technical Deep Dive: Analysis and Configuration of Glow Effect Settings

1. Introduction to the Glow Effect

The Glow effect, often referred to as Bloom, is a common post-processing technique used in computer graphics to simulate the visual phenomenon where bright light sources or highlights appear to bleed light into their surrounding area, creating a soft halo or fringe. Within the Second Life viewer, the Glow effect significantly enhances the visual impact and perceived brightness of emissive objects (lights, signs, glowing prims), specular highlights, sky elements, and other luminous parts of the scene, contributing to overall visual richness and realism.

The implementation involves several stages executed on the GPU after the main scene rendering is complete but before the final image is presented:

  1. Extraction: Identifying and isolating pixels in the scene that exceed a certain brightness threshold. Crucially, as of recent changes (Ref: Commit b44ad50f757), this extraction step operates on the tonemapped/gamma-corrected image (mPostMap), not the raw linear scene colors.
  2. Downscaling: The extracted brightness information is rendered into lower-resolution buffers (mGlow buffers) to optimize the subsequent blurring steps.
  3. Blurring: A significant blur (typically a separable Gaussian blur achieved through multiple passes) is applied to the downscaled brightness map.
  4. Compositing: The final blurred glow map is blended (usually additively) back onto the tonemapped scene image before final presentation (potentially combined with other effects like FXAA).

The following settings provide control over various aspects of this process, allowing for artistic adjustment and performance scaling.

2. Analysis of Individual Glow Settings


Setting: RenderGlow

  • Type: Boolean
  • 1. Function/Purpose: Master control to enable or disable the entire Glow post-processing effect.
  • 2. Code Usage/Implementation: Checked at the beginning of the glow generation logic (e.g., LLPipeline::renderGlow). If false (!sRenderGlow), the extraction and blur passes are skipped, potentially just clearing an intermediate buffer (mGlow[1]) to avoid artifacts.
  • 3. Performance Impact:
    • Enabled (true): Adds significant GPU load due to the multiple render passes (extraction, blur iterations) and increases VRAM usage for the mGlow intermediate buffers. The cost scales with resolution (RenderGlowResolutionPow) and iterations (RenderGlowIterations).
    • Disabled (false): Eliminates the GPU and VRAM cost associated with the Glow effect, providing a noticeable performance improvement.
  • 4. Visual Impact:
    • Enabled (true): Adds the characteristic bloom/halo effect around bright areas of the scene.
    • Disabled (false): Renders the scene without bloom; bright areas appear sharper without the soft halo.
  • 5. Default Value: Typically true on medium-to-high graphics presets, false on low presets.
  • 6. Recommended Value:
    • Max Fidelity/Visuals: true.
    • Max Performance: false.

Setting: RenderGlowHDR

  • Type: Boolean
  • 1. Function/Purpose: Determines the color precision format of the intermediate mGlow buffers.
  • 2. Code Usage/Implementation: Checked during buffer allocation (LLPipeline::createGLBuffers). If true, buffers use a high dynamic range format (e.g., GL_RGBA16F - 16 bits per channel, floating-point). If false, uses a standard format (e.g., GL_RGBA - 8 bits per channel, integer). Requires buffer reallocation if changed.
  • 3. Performance Impact:
    • Enabled (true): Doubles the VRAM requirement for the glow buffers compared to 8-bit format. May have a minor impact on GPU bandwidth/processing speed during blur passes.
    • Disabled (false): Uses less VRAM for glow buffers.
  • 4. Visual Impact:
    • Enabled (true): Allows for a wider range of brightness values within the glow effect, reducing or eliminating visible banding artifacts in smooth glow gradients and potentially allowing for brighter, more intense bloom effects without premature clipping. Most beneficial when overall HDR rendering is active.
    • Disabled (false): Limits the brightness range, potentially causing clamping (loss of detail in very bright glows) and increasing the likelihood of visible banding artifacts, especially in smooth, broad glows.
  • 5. Default Value: Likely true for High/Ultra presets, potentially false otherwise.
  • 6. Recommended Value:
    • Max Fidelity: true.
    • Max Performance / VRAM Constrained: false. (Consider linking to quality presets internally).

Setting: RenderGlowResolutionPow

  • Type: S32 (Integer)
  • 1. Function/Purpose: Controls the resolution of the intermediate mGlow buffers used for blurring. The actual resolution is calculated as 1 << RenderGlowResolutionPow, typically clamped (e.g., 1 to 512 or 1024). Lower values yield lower resolution buffers.
  • 2. Code Usage/Implementation: Read during buffer allocation (LLPipeline::createGLBuffers) to determine the size of mGlow textures. Also used in renderGlow logic to potentially adjust the blur delta (RenderGlowWidth scaling) to maintain a similar visual appearance across different resolutions. Requires buffer reallocation if changed.
  • 3. Performance Impact:
    • Higher Value: Significantly increases VRAM usage (quadratically with resolution). Increases GPU load during blur passes (more pixels to process). Major performance factor.
    • Lower Value: Decreases VRAM usage and GPU load for blur passes.
  • 4. Visual Impact:
    • Higher Value: Produces a smoother, potentially sharper, and higher-fidelity glow effect with fewer blocky artifacts.
    • Lower Value: Results in a more diffuse, softer glow that can appear blocky or less defined. Faster rendering. Often mapped to user-facing "Glow Quality" settings.
  • 5. Default Value: Varies by graphics preset. Common values might range from 7 (128px) to 9 (512px).
  • 6. Recommended Value:
    • Max Fidelity: Highest available value (e.g., 9).
    • Balanced: Mid-range value (e.g., 8).
    • Max Performance: Lower value (e.g., 7).

Setting: RenderGlowIterations

  • Type: S32 (Integer)
  • 1. Function/Purpose: Determines the number of blur passes applied to the downscaled glow map. The implementation likely performs RenderGlowIterations * 2 actual passes (one horizontal, one vertical per iteration) for a separable blur.
  • 2. Code Usage/Implementation: Used in renderGlow to control the loop limit for the blur passes applied to the mGlow buffers.
  • 3. Performance Impact:
    • Higher Value: Directly increases GPU load, roughly linearly with the number of iterations (passes). Significant performance factor.
    • Lower Value: Reduces GPU load proportionally.
  • 4. Visual Impact:
    • Higher Value: Creates a smoother, wider, more Gaussian-like blur.
    • Lower Value: Results in a less smooth blur (potentially showing stepping artifacts if too low) and a narrower glow spread for a given RenderGlowWidth.
  • 5. Default Value: Often relatively low, perhaps 2 or 3 (resulting in 4 or 6 passes).
  • 6. Recommended Value:
    • Max Fidelity/Smoothness: 3 or 4. Diminishing returns beyond this.
    • Max Performance: 1 or 2. (Consider linking to quality presets).

Setting: RenderGlowWidth

  • Type: F32 (Float)
  • 1. Function/Purpose: Controls the spatial extent or radius of the blur applied. Determines how far apart the samples are taken during each blur pass.
  • 2. Code Usage/Implementation: Used in renderGlow to calculate the delta offset passed as a uniform (GLOW_DELTA) to the blur shader (glowV.glsl). The vertex shader uses this delta to calculate offset texture coordinates for sampling. May be scaled internally based on RenderGlowResolutionPow.
  • 3. Performance Impact: Negligible. Changing the uniform value has minimal GPU cost.
  • 4. Visual Impact: Controls the visual "size" or "spread" of the glow halo.
    • Higher Value: Wider, softer, more diffuse glow.
    • Lower Value: Narrower, tighter glow (smoothness also depends on RenderGlowIterations). Major artistic control.
  • 5. Default Value: Typically around 1.0 to 2.0.
  • 6. Recommended Value: Subjective artistic choice. Adjust to achieve the desired look (e.g., 0.8 for tight halos, 2.5+ for wide haze).

Setting: RenderGlowStrength

  • Type: F32 (Float)
  • 1. Function/Purpose: Acts as a final intensity multiplier for the blurred glow map before it is composited back onto the main scene image.
  • 2. Code Usage/Implementation: Used in renderGlow (or potentially later in the glow combine stage). Passed as a uniform (GLOW_STRENGTH) to the blur shader or used in the final compositing step to scale the brightness of the added glow.
  • 3. Performance Impact: Negligible. Changing the multiplier value has minimal cost.
  • 4. Visual Impact: Directly controls the overall brightness or prominence of the glow effect. Higher values make the glow more intense and impactful; lower values make it subtler. Major artistic control.
  • 5. Default Value: Likely around 1.0 to 1.5.
  • 6. Recommended Value: Subjective artistic choice. Start near 1.0 and adjust to taste. Values 0.5-3.0+ are common depending on desired intensity.

Setting: RenderGlowMinLuminance (Restored Functionality - Operates Post-Tonemapping)

  • Type: F32 (Float)
  • 1. Function/Purpose: Defines the minimum brightness threshold a pixel in the tonemapped source image (mPostMap) must exceed to contribute to the initial glow extraction (before blurring). Controls what glows based on perceived brightness after tonemapping.
  • 2. Code Usage/Implementation:
    • The setting variable LLPipeline::RenderGlowMinLuminance must be declared, connected (connectRefreshCachedSettingsSafe), and read (refreshCachedSettings).
    • In the glow extraction phase within renderGlow (or equivalent), the hardcoded 9999 must be replaced with code passing this variable to the GLOW_MIN_LUMINANCE uniform for gGlowExtractProgram: gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, llmax(0.f, RenderGlowMinLuminance));.
    • The shader (glowExtractF.glsl) uses this value in smoothstep functions to determine the contribution based on calculated luminance/warmth of the tonemapped input pixel.
  • 3. Performance Impact: Negligible. Restoring the use of the setting variable instead of a hardcoded value has no significant performance cost.
  • 4. Visual Impact: Controls the selectivity of the glow effect based on post-tonemapping brightness.
    • Higher Value (e.g., 0.9, 0.95): Only the very brightest pixels (after tonemapping) will contribute, resulting in glow mainly on extreme highlights.
    • Lower Value (e.g., 0.7, 0.6): Moderately bright pixels (after tonemapping) will also contribute, leading to a more widespread glow.
    • Crucial: Values useful for the previous linear-space implementation (e.g., > 1.0) are likely too high now. The effective range is roughly 0.6 to 1.0.
  • 5. Default Value: Needs Adjustment! The original default value (likely intended for linear space) is inappropriate. A new default suitable for post-tonemapped input should be set in the settings XML file. A starting point of 0.80 or 0.85 is recommended, requiring testing and refinement.
  • 6. Recommended Value: Highly dependent on desired artistic effect. Users should experiment within the ~0.6 to 1.0 range.
    • Highlight Glow: 0.85 - 0.95.
    • Wider Hazy Glow: 0.6 - 0.8.

Setting: RenderGlowNoise

  • Type: Boolean
  • 1. Function/Purpose: Enables adding a small amount of noise (dithering) during the glow extraction phase.
  • 2. Code Usage/Implementation: If true, the glow extraction logic binds a noise texture (mTrueNoiseMap) and enables noise calculations (controlled by HAS_NOISE preprocessor flag) in the extraction shader (glowExtractF.glsl). Requires shader state change if toggled.
  • 3. Performance Impact: Very minor GPU cost (extra texture lookup and arithmetic in the extraction shader).
  • 4. Visual Impact:
    • Enabled (true): Reduces or eliminates visible banding artifacts in the glow, especially noticeable in smooth gradients when using lower precision buffers (RenderGlowHDR=false). Adds a very subtle noise pattern.
    • Disabled (false): May result in visible banding artifacts under certain conditions.
  • 5. Default Value: Likely true.
  • 6. Recommended Value:
    • Max Fidelity: true.
    • Max Performance: false. (Generally recommended to leave true unless profiling shows an unexpected impact). Consider linking to quality presets.

Setting: RenderGlowMaxExtractAlpha

  • Type: F32 (Float)
  • 1. Function/Purpose: Acts as a multiplier or ceiling applied to the calculated glow contribution before it's written to the extraction buffer (mGlow[2]).
  • 2. Code Usage/Implementation: Passed as GLOW_MAX_EXTRACT_ALPHA uniform to glowExtractF.glsl. Used in the shader: frag_color.a = max(col.a, mix(lum, warmth, warmthAmount) * maxExtractAlpha);. Scales the luminance/warmth derived value.
  • 3. Performance Impact: Negligible.
  • 4. Visual Impact: Limits the intensity extracted from any single pixel before blurring. Can tame excessively bright spikes at the source. Lower values dim the source; higher values allow brighter sources (up to buffer limits). Effect can be subtle compared to final RenderGlowStrength.
  • 5. Default Value: Likely 1.0.
  • 6. Recommended Value: Generally 1.0. Can be considered an advanced/fine-tuning setting. Not essential for most users. Could potentially be hidden from basic UI.

Setting: RenderGlowWarmthAmount

  • Type: F32 (Float)
  • 1. Function/Purpose: Blends between using standard luminance (lumWeights) and an alternative "warmth" metric (warmthWeights) when calculating the initial glow extraction contribution.
  • 2. Code Usage/Implementation: Passed as GLOW_WARMTH_AMOUNT uniform to glowExtractF.glsl. Used in mix(lum, warmth, warmthAmount).
  • 3. Performance Impact: Negligible.
  • 4. Visual Impact: If > 0, allows biasing the glow source towards colors emphasized by RenderGlowWarmthWeights. 0.0 uses standard luminance only; 1.0 uses warmth metric only. Can provide subtle color tinting at the source of the glow. Effect depends heavily on WarmthWeights and is considered niche.
  • 5. Default Value: Likely 0.0.
  • 6. Recommended Value: 0.0 for standard behavior. Experimentation needed for artistic effect. Could potentially be simplified or replaced by a more intuitive post-blur tint control.

Setting: RenderGlowWarmthWeights

  • Type: LLVector3 (Vector of 3 Floats)
  • 1. Function/Purpose: Defines the RGB weights used in the alternative "warmth" calculation, used only if RenderGlowWarmthAmount > 0.
  • 2. Code Usage/Implementation: Passed as GLOW_WARMTH_WEIGHTS uniform to glowExtractF.glsl. Used in max(col.r * warmthWeights.r, max(col.g * warmthWeights.g, col.b * warmthWeights.b)).
  • 3. Performance Impact: Negligible.
  • 4. Visual Impact: Influences which colors contribute to the "warmth" component if WarmthAmount > 0. Highly technical control for a niche effect.
  • 5. Default Value: Unknown, could be (1,1,1) or biased.
  • 6. Recommended Value: Keep at default unless specifically using WarmthAmount for artistic effect. Candidate for simplification/removal from user settings.

Setting: RenderGlowLumWeights

  • Type: LLVector3 (Vector of 3 Floats)
  • 1. Function/Purpose: Defines the RGB weights used to calculate standard perceived luminance during glow extraction.
  • 2. Code Usage/Implementation: Passed as GLOW_LUM_WEIGHTS uniform to glowExtractF.glsl. Used in dot(col.rgb, lumWeights).
  • 3. Performance Impact: Negligible.
  • 4. Visual Impact: Determines relative contribution of RGB to brightness for glow. Changing from standard perceptual weights yields non-standard results.
  • 5. Default Value: Standard perceptual luminance weights (e.g., close to Rec.709: (0.2126, 0.7152, 0.0722) or NTSC: (0.299, 0.587, 0.114)).
  • 6. Recommended Value: Should not be a user setting. This should be fixed internally to a standard perceptual value. Recommend removing this from debug settings/XML definitions intended for users.

3. Testing Procedures

3.1 User Testing

Objective: To visually assess the impact of Glow settings on appearance and perceive performance changes.

Prerequisites:

  • Second Life Viewer running with Advanced Lighting Model (ALM) enabled.
  • Access to the Graphics Preferences panel or Debug Settings.
  • FPS counter visible (Ctrl+Shift+1).

Location: Find a location with a mix of elements: bright lights, emissive objects, dark backgrounds, potentially smooth gradients.

Steps:

  1. Baseline: Set graphics to High or Ultra. Note visuals and FPS. Ensure RenderGlow is true.
  2. Master Toggle (RenderGlow): Disable/Enable RenderGlow. Observe bloom disappearance/appearance and FPS change.
  3. Quality (RenderGlowResolutionPow): Test low (e.g., 7) vs. high (e.g., 9). Observe glow definition/smoothness/blockiness and FPS impact.
  4. Iterations (RenderGlowIterations): Test low (e.g., 1-2) vs. high (e.g., 4). Observe glow smoothness/spread and FPS impact.
  5. Artistic Controls (RenderGlowStrength, RenderGlowWidth): Adjust Strength (intensity) and Width (spread/size). Observe how they interact to control the glow's look.
  6. Threshold (RenderGlowMinLuminance):
    • Crucial: Test values primarily in the 0.6 to 1.0 range.
    • Set to a low value (e.g., 0.6). Observe which moderately bright areas start glowing.
    • Set to a high value (e.g., 0.95). Observe that only the very brightest highlights contribute to the glow. Find a value that feels like a good balance.
  7. Quality Artifacts (RenderGlowHDR, RenderGlowNoise): Find a large, smooth glow area. Toggle HDR – look for banding reduction/intensity changes. Toggle Noise – look for subtle dithering and banding reduction (especially with HDR off).
  8. (Optional) Niche Settings: If desired, test RenderGlowMaxExtractAlpha (try extreme values like 0.5, 5.0). Test WarmthAmount (set > 0) and see if changing WarmthWeights subtly tints the glow source.

3.2 Developer Testing

Objective: To measure performance impact, verify functionality (especially the restored MinLuminance), and inspect intermediate steps.

Prerequisites:

  • Development environment, Debug build.
  • GPU Profiling/Debugging Tools (RenderDoc, Nsight, RGP, etc.).
  • System VRAM monitoring.

Steps:

  1. Performance Profiling (GPU Time): Use a GPU profiler. Measure time spent in the renderGlow function (or relevant GPU zones) while varying:
    • RenderGlow (on/off).
    • RenderGlowResolutionPow (e.g., 7, 8, 9).
    • RenderGlowIterations (e.g., 1, 2, 4).
    • Verify other settings have negligible GPU time impact.
  2. VRAM Measurement: Track VRAM usage. Measure increase when RenderGlow is enabled. Verify changes with RenderGlowResolutionPow and RenderGlowHDR match expected buffer sizes (Res*Res*BytesPerPixel*NumBuffers).
  3. Shader/Buffer Inspection (Frame Debugging - e.g., RenderDoc):
    • Capture a frame.
    • Input Check: Verify the input to gGlowExtractProgram is mPostMap (tonemapped image).
    • MinLuminance Verification: Inspect the uniforms passed to gGlowExtractProgram. Confirm GLOW_MIN_LUMINANCE matches the value set via the RenderGlowMinLuminance debug setting (not 9999).
    • Extraction Output (mGlow[2]): Examine the content. Verify that changing RenderGlowMinLuminance (in the 0.6-1.0 range) correctly changes which areas appear bright in this buffer. Check for noise dithering if RenderGlowNoise is enabled.
    • Blur Passes (mGlow[0], mGlow[1]): Step through blur iterations. Verify visual blurring and check GLOW_DELTA, GLOW_STRENGTH uniforms.
    • Buffer Formats: Confirm mGlow texture formats match RenderGlowHDR.
  4. Functionality/Stability: Change all restored/modified settings via Debug Settings. Check for log errors or crashes. Ensure the effect updates visually. Step through C++ code (refreshCachedSettings, renderGlow) to confirm variable reading and uniform setting.

4. Summary and Recommendations

The Glow effect is a key component of the viewer's visual presentation. The available settings provide significant control over its performance and appearance.

  • Key Functional Controls: RenderGlow, RenderGlowResolutionPow, RenderGlowIterations, RenderGlowWidth, RenderGlowStrength are essential and generally function as expected.
  • Restored Threshold: RenderGlowMinLuminance functionality has been restored by linking the setting variable to the shader uniform, replacing the previous hardcoded disabling value (9999). Crucially, this threshold now operates on post-tonemapping values, requiring adjustment of the expected range (approx. 0.6-1.0) and the default value in settings XML.
  • Quality Enhancements: RenderGlowHDR and RenderGlowNoise are useful for reducing artifacts but could potentially be linked to overall quality presets for simplicity.
  • Simplification Candidates:
    • RenderGlowLumWeights should be removed as a user setting and hardcoded internally.
    • RenderGlowWarmthAmount/Weights provide niche artistic control and could be simplified or replaced by a more common post-blur tint option.
    • RenderGlowMaxExtractAlpha could be relegated to advanced/debug status.

With the restoration of a functional (post-tonemapping) RenderGlowMinLuminance threshold, users and developers regain vital control over what parts of the scene contribute to the glow, complementing the existing controls for how the glow looks and performs. Further simplification of niche settings could improve usability.