Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
e400a2f
#6318 Change compiler entry to LSL on Luau
marchcat Sep 15, 2026
41d9d0d
#3988 Add a toggle for sculpty area validation
akleshchev Sep 15, 2026
9e8cae3
#5856 Fix default state not restoring
akleshchev Sep 15, 2026
0e1d25f
#5806 enable reset environment after teleport only for new users
maxim-productengine Sep 16, 2026
56d7fbf
Voice wasn't automatically reconnecting after a voice server crash or…
roxanneskelly Sep 16, 2026
f258637
#6315 Separate voice queue from main queue
akleshchev Sep 16, 2026
c8e39fa
#6109 StopPlayout crash
akleshchev Sep 14, 2026
fcb9629
#5856 Update labels
akleshchev Sep 17, 2026
31b0748
#6334 Remove unnecessary popups when user doesn't have a payment met…
maxim-productengine Sep 17, 2026
9bc4280
Merge pull request #6335 from secondlife/roxie/fix-voice-reconnect
roxanneskelly Sep 17, 2026
f767219
Revert #5856 OS hibernation prevention (#6340)
marchcat Sep 17, 2026
89973b5
Revert "#3988 Don't render malformed sculpts"
akleshchev Sep 18, 2026
de2c84e
Merge branch 'release/26.4' of https://github.com/secondlife/viewer i…
RyeMutt Sep 19, 2026
3034b24
Fix syntax error in GHA script
RyeMutt Sep 19, 2026
79bf9b6
Disable vcpkg nuget cache temporarily
RyeMutt Sep 19, 2026
90000be
Bump alchemy-registry for arm64 cef-bin
RyeMutt Sep 19, 2026
0e3c20a
Bump alchemy-registry for more arm64 cef-bin fixes
RyeMutt Sep 19, 2026
a059e5e
Fix unused function warning under linux arm64
RyeMutt Sep 19, 2026
dc3dfac
Filter lens flare occlusion through a temporal state pass
taylnos Sep 3, 2026
b100439
Replace the flare occlusion settings with Size and Fade
taylnos Sep 3, 2026
e439242
Tighten the flare Size and Fade bounds
taylnos Sep 4, 2026
b88466f
Harden the lens flare state pass after review and a needle test
taylnos Sep 4, 2026
4042c6a
Fetch the flare tap colour with an explicit level
taylnos Sep 4, 2026
3dc5f51
Compare LLSD-typed settings by value in llsd_compare
taylnos Sep 3, 2026
d9ab948
Lightbox: spline tone curve baked to a LUT, and editable split-tone r…
taylnos Sep 3, 2026
91be5fa
Looks: apply defaults for whitelisted keys a Look file lacks
taylnos Sep 3, 2026
5607af4
Compare LLSD settings by value, with numbers as numbers
taylnos Sep 3, 2026
973cde3
Lightbox curves: fix edge adds, stored point caps and held split handles
taylnos Sep 3, 2026
6bac368
Looks: fence the reset of absent whitelisted keys
taylnos Sep 3, 2026
63be701
Bring the curve editor and grading docs in line with the final code
taylnos Sep 3, 2026
437c1c6
Add lens distortion and rebuild depth of field around it
taylnos Sep 1, 2026
c56cd4d
Add lens dirt and a cross-screen filter
taylnos Sep 1, 2026
338920d
A starburst frequency is not a spike count
taylnos Sep 1, 2026
67f8751
The cat's eye measures its field radius like everything else
taylnos Sep 1, 2026
82d75ba
Add lens aberrations to the bokeh
taylnos Sep 1, 2026
de89d66
Stop generating streaks nothing will draw
taylnos Sep 1, 2026
7c46c8d
Four lens dirt plates, and ones you can actually see
taylnos Sep 1, 2026
691b366
Bring the pipeline docs back in line with the pipeline
taylnos Sep 1, 2026
4f571dd
Sweep the branch before review
taylnos Sep 1, 2026
7de3a17
The dirt bake reports drift through its exit status
taylnos Sep 2, 2026
0aa2688
Draw the lens dirt instead of shipping it
taylnos Sep 2, 2026
f6e9282
The dirt check explains its failures instead of crashing on them
taylnos Sep 2, 2026
5a779e9
Depth of field borrows its scratch instead of owning it
taylnos Sep 7, 2026
d5c113c
The cross filter streaks into quadrants of a borrowed target
taylnos Sep 7, 2026
03850b3
The Lightbox's tabs share their strip and say what each one holds
taylnos Sep 13, 2026
2aa1556
The Lightbox's vector spinners scrub from their channel letters
taylnos Sep 13, 2026
68188f6
The Look tab counts the grading sections switched off for comparison
taylnos Sep 13, 2026
1643bee
The Lightbox hears its own shortcuts before the menu bar does
taylnos Sep 13, 2026
e31795b
The Lightbox finds its sections and settings once, before anything ca…
taylnos Sep 13, 2026
881cc27
The grade's undo steps carry names, and a step that changed nothing i…
taylnos Sep 13, 2026
d42e6e2
A white balance pick is one undo step
taylnos Sep 13, 2026
5b66d24
Ctrl+F finds a Lightbox setting or section by name and goes to it
taylnos Sep 13, 2026
dbeca79
The Lightbox's undo history can be read and gone back through
taylnos Sep 13, 2026
3c76068
A colour swatch can hand its picker to its owner
taylnos Sep 13, 2026
4e43159
The Lightbox's colour rows pick inline, and a pick is one undo step
taylnos Sep 13, 2026
81efc82
A Lightbox tab can come out into a window of its own
taylnos Sep 13, 2026
fc47a6e
Fit each Lightbox section to its rows
taylnos Sep 13, 2026
1232045
setting_row: one setting on one line
taylnos Sep 13, 2026
c60c085
A setting row can hand its reset to its owner
taylnos Sep 13, 2026
98a3e4b
Exposure & Tone's rows are setting rows
taylnos Sep 13, 2026
cc25e55
The rest of the Look tab's rows are setting rows
taylnos Sep 13, 2026
b88da7e
The Lens tab's rows are setting rows
taylnos Sep 13, 2026
e36559a
The Scene tab's rows are setting rows
taylnos Sep 13, 2026
68da5d5
The Sky tab's rows are setting rows
taylnos Sep 13, 2026
72d911a
The guide's row recipe is the setting row
taylnos Sep 13, 2026
32b1599
The Lightbox's colour popover opens with a ring worth aiming at, and …
taylnos Sep 13, 2026
e91d4c3
The Lightbox's buttons are split between the grade's bar and the tab …
taylnos Sep 13, 2026
fad9f55
Only the Lightbox's pop-out button sits on the tab strip.
taylnos Sep 13, 2026
ff49ab4
The Lightbox's top row is sized in XUI Studio, with 24px controls.
taylnos Sep 13, 2026
a452f02
The Lightbox's pop-out is 24px tall again, which looks level with the…
taylnos Sep 13, 2026
6b9ad78
The Lightbox shows Bloom (HDR) or Glow (Legacy), whichever the render…
taylnos Sep 13, 2026
de83f84
The Lens tab's tooltip lists bloom/glow as one effect.
taylnos Sep 13, 2026
9a2b708
Use fullopt preset in GHA
RyeMutt Sep 19, 2026
b330f9f
Strip the holder line's prefix without an empty regex match
RyeMutt Sep 19, 2026
e180d9f
Draw the checkerboard's own quad, so its sampler survives
RyeMutt Sep 16, 2026
58a3afe
Count the colour table's changes, keep its handles in one map, and le…
RyeMutt Sep 19, 2026
1ca6929
Canvas: pan, zoom about the pointer, rules, backdrops, a pixel grid a…
RyeMutt Sep 19, 2026
61b7130
Specimen list: cells as well as rows, a layout changed at will, sever…
RyeMutt Sep 19, 2026
66cab5b
Property grid: rows kept through new values, ranges and sliders, a re…
RyeMutt Sep 19, 2026
418a02e
A studio window's base, regions that fold and come out, an undo stack…
RyeMutt Sep 19, 2026
cd52457
XUI Studio on the studio base, with the canvas's own zoom, rules, pan…
RyeMutt Sep 19, 2026
4bf66e0
Keep XUI Studio's actions on the shared undo stack, and put a run of …
RyeMutt Sep 19, 2026
d1d2908
Merge remote-tracking branch 'internal/zanibar/lightbox-stack/4-xui-s…
RyeMutt Sep 19, 2026
1091553
Lens dirt draws on the world frame only, and the distortion fit is so…
RyeMutt Sep 19, 2026
a1924ed
The split-tone ramps and the tone curve LUT sit with their blocks in …
RyeMutt Sep 19, 2026
432971a
The setting row asks the slider for its label box, and the directory …
RyeMutt Sep 19, 2026
4e27259
A popover sends home the keys it does not take and remembers its size…
RyeMutt Sep 19, 2026
161b61e
Any region can come out into a window of its own; the studio's undo k…
RyeMutt Sep 19, 2026
75ce525
The Lightbox is a studio window: its find, history, undo keys, pop-ou…
RyeMutt Sep 19, 2026
7f3f9fc
Comments say what the code does rather than what it did, and the flar…
RyeMutt Sep 19, 2026
a718fbf
The dial and the pad stop dragging when the mouse is taken away
RyeMutt Sep 19, 2026
d6b3720
A kept property row is put right in every way it can change under an …
RyeMutt Sep 19, 2026
6682925
A cell drags what was pressed, a row's picture is the row's own, and …
RyeMutt Sep 19, 2026
919b772
A detached preview holds the studio by handle, and lets go of its zoo…
RyeMutt Sep 19, 2026
dbec107
The colour table test checks for its row before reading it
RyeMutt Sep 19, 2026
b6c9ad9
A peer connection re-initialised after a close gathers stats again
RyeMutt Sep 19, 2026
f5578ec
Add R2 vcpkg cache with read-only access for same-repository PRs
nopjmp Sep 20, 2026
91d92bc
Temporarily allow same-repository PRs to populate the R2 cache
nopjmp Sep 20, 2026
ab62b4c
Fix clang override warnings
RyeMutt Sep 20, 2026
8cad134
Bump alchemy registry with webrtc vcpkg repairs
RyeMutt Sep 20, 2026
bec2867
Fix merge defect in appviewersdl
RyeMutt Sep 20, 2026
b22aa2d
Fix unused function warning
RyeMutt Sep 20, 2026
27e5936
A walk over a multimap's run starts at its front, not wherever find l…
RyeMutt Sep 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 65 additions & 35 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,11 @@ jobs:
include:
# Linux on arm64: NEON is a first-class target, and this is the
# one row where GCC compiles the SIMD layer for it.
- runner: ubuntu-24.04-arm
- runner: ubuntu-26.04-arm
configuration: release
arch: arm64
build_variant: Viewer
- runner: ubuntu-24.04-arm
- runner: ubuntu-26.04-arm
configuration: release
arch: arm64
build_variant: Tests
Expand Down Expand Up @@ -209,7 +209,7 @@ jobs:
# Linux runner gets one from Mesa's llvmpipe through SDL's offscreen
# driver; the Windows runner has no GPU driver, and macOS is unproven,
# so they build those suites and register them disabled.
AL_ENABLE_GL_TESTS: ${{ runner.os == 'Linux' }}
AL_ENABLE_GL_TESTS: ${{ startsWith(matrix.runner, 'ubuntu-') }}
LIBGL_ALWAYS_SOFTWARE: 1
# Build Config
BUILD_ARCH: ${{ matrix.arch }}
Expand All @@ -232,8 +232,8 @@ jobs:
# vcpkg Setup
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
VCPKG_USERNAME: ${{ github.repository_owner }}
VCPKG_FEED_URL: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
VCPKG_BINARY_SOURCES: "clear;nuget,https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json,readwrite"
# VCPKG_FEED_URL: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
VCPKG_BINARY_SOURCES: "clear;default,readwrite"
steps:
- name: Linux Dependency Install and Disk Cleanup
if: runner.os == 'Linux'
Expand Down Expand Up @@ -303,33 +303,63 @@ jobs:
run: |
./vcpkg/bootstrap-vcpkg.sh

- name: Set up vcpkg nuget caching
shell: bash
run: |
if [[ "$RUNNER_OS" == "Windows" ]]
then
$(${VCPKG_ROOT}/vcpkg fetch nuget | tail -n 1) \
sources add \
-Source "${{ env.VCPKG_FEED_URL }}" \
-StorePasswordInClearText \
-Name GitHubPackages \
-UserName "${{ env.VCPKG_USERNAME }}" \
-Password "${{ secrets.GITHUB_TOKEN }}"
$(${VCPKG_ROOT}/vcpkg fetch nuget | tail -n 1) \
setapikey "${{ secrets.GITHUB_TOKEN }}" \
-Source "${{ env.VCPKG_FEED_URL }}"
else
mono $(${VCPKG_ROOT}/vcpkg fetch nuget | tail -n 1) \
sources add \
-Source "${{ env.VCPKG_FEED_URL }}" \
-StorePasswordInClearText \
-Name GitHubPackages \
-UserName "${{ env.VCPKG_USERNAME }}" \
-Password "${{ secrets.GITHUB_TOKEN }}"
mono $(${VCPKG_ROOT}/vcpkg fetch nuget | tail -n 1) \
setapikey "${{ secrets.GITHUB_TOKEN }}" \
-Source "${{ env.VCPKG_FEED_URL }}"
fi
- name: Install AWS CLI on macOS
if: >-
vars.VCPKG_R2_ENABLED == 'true' && runner.os == 'macOS' &&
((github.ref_protected && github.event_name != 'pull_request') ||
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository))
run: brew install awscli

- name: Configure R2 binary cache for trusted builds
if: vars.VCPKG_R2_ENABLED == 'true' && github.ref_protected && github.event_name != 'pull_request'
env:
R2_CACHE_MODE: readwrite
R2_ENDPOINT_URL: ${{ vars.VCPKG_R2_ENDPOINT_URL }}
R2_BUCKET: ${{ vars.VCPKG_R2_BUCKET }}
R2_ACCESS_KEY_ID: ${{ secrets.VCPKG_R2_ACCESS_KEY_ID }}
R2_SECRET_ACCESS_KEY: ${{ secrets.VCPKG_R2_SECRET_ACCESS_KEY }}
run: python scripts/vcpkg/configure_r2_cache.py

- name: Configure R2 binary cache for same-repository PRs
if: >-
vars.VCPKG_R2_ENABLED == 'true' && github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name == github.repository
env:
# Temporary cache population test; restore read mode and reader secrets afterward.
R2_CACHE_MODE: readwrite
R2_ENDPOINT_URL: ${{ vars.VCPKG_R2_ENDPOINT_URL }}
R2_BUCKET: ${{ vars.VCPKG_R2_BUCKET }}
R2_ACCESS_KEY_ID: ${{ secrets.VCPKG_R2_ACCESS_KEY_ID }}
R2_SECRET_ACCESS_KEY: ${{ secrets.VCPKG_R2_SECRET_ACCESS_KEY }}
run: python scripts/vcpkg/configure_r2_cache.py

# - name: Set up vcpkg nuget caching
# shell: bash
# run: |
# if [[ "$RUNNER_OS" == "Windows" ]]
# then
# $(${VCPKG_ROOT}/vcpkg fetch nuget | tail -n 1) \
# sources add \
# -Source "${{ env.VCPKG_FEED_URL }}" \
# -StorePasswordInClearText \
# -Name GitHubPackages \
# -UserName "${{ env.VCPKG_USERNAME }}" \
# -Password "${{ secrets.GITHUB_TOKEN }}"
# $(${VCPKG_ROOT}/vcpkg fetch nuget | tail -n 1) \
# setapikey "${{ secrets.GITHUB_TOKEN }}" \
# -Source "${{ env.VCPKG_FEED_URL }}"
# else
# mono $(${VCPKG_ROOT}/vcpkg fetch nuget | tail -n 1) \
# sources add \
# -Source "${{ env.VCPKG_FEED_URL }}" \
# -StorePasswordInClearText \
# -Name GitHubPackages \
# -UserName "${{ env.VCPKG_USERNAME }}" \
# -Password "${{ secrets.GITHUB_TOKEN }}"
# mono $(${VCPKG_ROOT}/vcpkg fetch nuget | tail -n 1) \
# setapikey "${{ secrets.GITHUB_TOKEN }}" \
# -Source "${{ env.VCPKG_FEED_URL }}"
# fi

- name: Cache Rust Dependencies
uses: actions/cache@v6
Expand Down Expand Up @@ -361,17 +391,17 @@ jobs:
SIGNING=()
case "$RUNNER_OS" in
Windows)
cmake_preset_name="vs2026$cmake_preset_postfix"
cmake_preset_name="vs2026${cmake_preset_postfix}-fullopt"
build_directory="build-Windows-$cmake_preset_name"
vcpkg_triplet="x64-windows-alchemy-avx2-release"
;;
macOS)
cmake_preset_name="ninja$cmake_preset_postfix-$BUILD_ARCH"
cmake_preset_name="ninja${cmake_preset_postfix}-fullopt-$BUILD_ARCH"
build_directory="build-Darwin-$cmake_preset_name"
vcpkg_triplet="$BUILD_ARCH-osx-alchemy-release"
;;
Linux)
cmake_preset_name="ninja$cmake_preset_postfix"
cmake_preset_name="ninja${cmake_preset_postfix}-fullopt"
build_directory="build-Linux-$cmake_preset_name"
if [[ "$BUILD_ARCH" == "arm64" ]]
then
Expand Down
27 changes: 17 additions & 10 deletions doc/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,10 @@ The deferred rendering pipeline is orchestrated by `LLPipeline` (`indra/newview/
2. **Shadows** (`renderGeomShadow()`) — 4 sun shadow cascades + 2 spot light shadow maps
3. **Deferred Lighting** (`renderDeferredLighting()`) — Sun, point lights (up to 16 batched), spot lights, with reflection probe influence
4. **Post-Deferred** (`renderGeomPostDeferred()`) — Alpha, water, atmospheric haze
5. **Post-Processing** — Luminance/exposure, bloom, DoF, tonemapping, color grading, AA, screen effects
6. **Finalize** (`renderFinalize()`) — Final blit with vignette, film grain, dithering, chromatic aberration
5. **Post-Processing** — Luminance/exposure, depth of field, bloom, then one pass doing tonemapping, color grading and the bloom composite together, then AA and CAS
6. **Finalize** (`renderFinalize()`) — Final blit with lens distortion, vignette, film grain, dithering, CVD compensation

Depth of field runs **before** bloom and before the tonemapper, on linear HDR. Gathering over display-space values gathers over already-compressed highlights, and bloom-after-defocus is the optical order, so a defocused highlight blooms as a soft disc rather than a sharp core on a blurred background.

**GBuffer layout** (MRT attachments on `deferredScreen`):
- frag_data[0]: Base color (GL_RGBA)
Expand All @@ -101,18 +103,23 @@ The deferred rendering pipeline is orchestrated by `LLPipeline` (`indra/newview/
- `mMainRT` — Full resolution for main scene
- `mAuxillaryRT` — 512×512 for reflection probes and dynamic texture bakes
- `mHeroProbeRT` — High-res hero probe rendering
- Additional targets: `mSceneMap` (SSR input), `mLuminanceMap`/`mExposureMap` (auto-exposure), `mPostPingMap`/`mPostPongMap` (post-process ping-pong), `mFXAAMap`, `mSMAABlendBuffer`, `mGlow[3]` (bloom pyramid), `mWaterDis` (refraction), `mSpotShadow[2]`, `mPbrBrdfLut`
- Additional targets: `mSceneMap` (SSR input), `mLuminanceMap`/`mExposureMap` (auto-exposure), `postPingMap`/`postPongMap` (post-process ping-pong), `mFXAAMap`, `mSMAABlendBuffer`, `bloomMip[BLOOM_MAX_MIPS]` (HDR bloom pyramid, up to 7 levels, live count in `bloomMipCount`), `mWaterDis` (refraction; also lends its quadrants to the cross-screen filter's two scratch buffers and accumulator, and its whole to depth of field's sharp copy, while it is idle after the water pass — `crossFilterReady`/`crossFilterWidth`/`crossFilterHeight` tell `colorCorrect` where the accumulator is), `mSpotShadow[2]`, `mPbrBrdfLut`
- `mGlow[3]` is the **legacy non-HDR glow chain**, not the bloom pyramid, and lives outside the pack. So does `mLensDirtMap`, the generated lens dirt plate — an `LLRenderTarget` allocated the first frame the effect is enabled and released when it is switched off.

**Post-processing chain:**
- **Auto-exposure:** Progressive histogram (`gLuminanceProgram`, `gExposureProgram`) with history fade
- **Bloom:** Bright-area extraction → 3-level glow pyramid (`mGlow[3]`) with warmth correction
- **Depth of Field:** Circle-of-confusion via `gDeferredCoFProgram`, combine via `gDeferredDoFCombineProgram`. Settings: `CameraFNumber`, `CameraFocalLength`, `CameraMaxCoF`
- **Lens flare sun state:** a 2x1 temporal pass (`gLensFlareStateProgram`, `lensFlareStateF.glsl`) run just before colour correction measures how much of the sun disc is unoccluded and its colour, and filters both under a rate limit; `computeLensFlare` in `postEffectUtilsF.glsl` reads one texel of it. The shader is the source of truth for the filter; `scripts/content_tools/check_lens_flare_state.py` mirrors it and is its regression test
- **Bloom:** Bright-area extraction → downsample/upsample pyramid over `bloomMip[]` with warmth correction and optional halation carried in alpha. The additive composite is **not** a pass of its own: it is folded into `colorCorrect`'s `BLOOM_COMPOSITE` permutation. `compositeBloomHDR` is a standalone equivalent that nothing currently calls
- **Cross-screen (star) filter:** `gCrossFilterProgram` streaks every thresholded highlight, seeded from `bloomMip[0]` and accumulated through three quadrants of `mWaterDis`, which the two shaders address through `uCrossRegion`/`uCrossClamp` so a tap at the quadrant's edge clamps exactly as it did at a dedicated target's edge. One strictly one-sided three-pass chain per arm, at strides that tile the reachable offsets exactly once — the tiling is load-bearing and the shader explains why. Composited in `colorCorrect` alongside the pyramid, so it inherits bloom strength
- **Lens dirt:** `gLensDirtGenProgram` draws the grime plate into `mLensDirtMap` — dust motes, wipe smudges, stray fibres, fine grit and optional scratches, built from hashes and distance fields rather than loaded from an image. Not a per-frame pass: it runs when a generation parameter moves or the window resizes, guarded by the cached parameter set in `mLensDirtParams`, which is also what makes a failed allocation stop retrying. Generated at the frame's own resolution, so nothing has to fit a square plate to a wide window. A rebuild is held off while `mLensDirtSliderHeld` is raised — the Lightbox raises it on a generation slider's mouse-down and lowers it on mouse-up, so a drag costs one plate on release rather than one per frame. Everything that is not a drag (typed values, resets, applying a Look, undo, window resizes) rebuilds immediately, which is what a settle timer would have delayed for no reason. `colorCorrect` multiplies the accumulated bloom and flare terms by it
- **Depth of Field:** three passes — circle of confusion (`gDeferredCoFProgram`, writing sharp linear colour plus signed CoF in alpha), a gather blur at `CameraDoFResScale`, and a combine (`gDeferredDoFCombineProgram`) back over `mRT->screen` under `setColorMask(true, false)` so the legacy prim-glow alpha tag survives. It owns no targets: the sharp copy borrows `mWaterDis`, which the water passes refill each frame and have finished with, and the blur borrows `bloomMip[0]` between the luminance read and the extract pass (`postPongMap` without HDR). The blur viewport is clamped to what mip 0 can hold when `RenderBloomResolutionScale` shrinks it, and the combine is told the fraction it actually covers via `res_scale` and where it sits via `dof_uv_scale`. The gather has four compile-time variants over two axes, `FRONT_BLUR` × `DOF_SHAPED`: `gDeferredPostProgram`, `gDeferredPostProgramNoNear`, `gDeferredPostProgramShaped`, `gDeferredPostProgramNoNearShaped`. Optics: `CameraFNumber`, `CameraFocalLength`, `CameraFieldOfView`, `CameraMaxCoF`, `CameraDoFResScale`
- **Bokeh shaping** (inside the `DOF_SHAPED` gather): polygonal aperture (`RenderBokehApertureBlades`, `Rotation`, `Curvature`), anamorphic squeeze, cat's-eye optical vignetting, defocus fringing, and the lens aberrations — spherical (`RenderBokehSphericalAberration`), field stretch for swirl and coma (`RenderBokehFieldStretch`, `FieldFalloff`) and comatic asymmetry. The CPU picks a shaped variant only when one of them is actually doing something
- **Screen Space Reflections:** Class 3+ feature, iterative ray marching
- **Tonemapping:** ACES, Reinhard, Filmic, AGX — selectable via `AlchemyRenderTonemapType`
- **Color Grading:** 3D LUT-based (`gDeferredPostGammaCorrectCGLutProgram`, `mCGLut`)
- **Color Grading:** 3D LUT-based (`gDeferredPostGammaCorrectCGLutProgram`, `mCGLut`), plus a CPU-baked 1D tone curve LUT (`mToneCurveLut`, baked from `ALToneCurveSet` on a dirty flag) and precomputed split-tone ramps; the helpers live in `colorGradeUtilF.glsl` under `shaders/class1/alchemy/`
- **Anti-aliasing:** FXAA (1-pass, `gFXAAProgram[4]`) or SMAA (3-pass edge detect → blend weights → neighborhood blend, `gSMAAEdgeDetectProgram[4]`/`gSMAABlendWeightsProgram[4]`/`gSMAANeighborhoodBlendProgram[4]`). CAS (Contrast Adaptive Sharpening) via `gCASProgram`
- **Final blit effects** (`blitWithEffectsF.glsl` in `shaders/class1/alchemy/`): Vignette (configurable shape/softness/color), film grain (luma/color/coarse/photon styles), TPDF dithering, CVD compensation/preview
- **Chromatic aberration** (`colorCorrectF.glsl` in `shaders/class1/alchemy/`): Per-channel offset with amount, falloff, angle, anisotropy controls
- **Final blit effects** (`blitWithEffectsF.glsl` in `shaders/class1/alchemy/`): geometric lens distortion (Brown-Conrady radial `k1`/`k2` and tangential `p1`/`p2`, anamorphic squeeze, decentring, with the auto-fit rescale solved on the CPU and out-of-frame samples masked to black), vignette (configurable shape/softness/color), film grain (luma/color/coarse/photon styles), TPDF dithering, CVD compensation/preview. Distortion warps the world view only — overlays drawn after the blit do not follow it
- **Effects inside `colorCorrectF.glsl`** (`shaders/class1/alchemy/`), which runs in every variant including the no-post ones and so gates them itself: chromatic aberration (per-channel offset with amount, falloff, angle, anisotropy), the five-component lens flare, the bloom and cross-filter composite, and lens dirt — the generated grime plate above, multiplied by the accumulated flare and bloom terms, so it only lights up where something already is

Post-processing settings are exposed in the Lightbox floater (`ALFloaterLightBox`); see `doc/LIGHTBOX.md` for how to add UI sections for new effects.

Expand All @@ -126,9 +133,9 @@ GLSL shaders live in `indra/newview/app_settings/shaders/` organized by quality
- **`class1/`** — Base shaders (all hardware)
- **`class2/`** — Mid-tier features
- **`class3/`** — Advanced features (SSR, high-quality lighting)
- Categories: `deferred/`, `objects/`, `environment/`, `alchemy/` (Alchemy post-processing), `windlight/`, `avatar/`, `interface/`
- Categories: `deferred/`, `objects/`, `environment/`, `alchemy/` (Alchemy post-processing), `effects/` (glow, the bloom pyramid, the cross-screen filter), `windlight/`, `avatar/`, `interface/`

Key shader groups: GBuffer write (`gDeferredDiffuseProgram`, `gDeferredPBROpaqueProgram`, `gDeferredBumpProgram`, `gDeferredMaterialProgram[]`, etc.), deferred lighting (`gDeferredSunProgram`, `gDeferredLightProgram`, `gDeferredMultiLightProgram[16]`, `gDeferredSpotLightProgram`), shadows (`gDeferredShadowProgram` and variants), environment (`gDeferredWLSkyProgram`, `gWaterProgram`, `gHazeProgram`), post-processing (tonemap, FXAA, SMAA, CAS, bloom, DoF programs).
Key shader groups: GBuffer write (`gDeferredDiffuseProgram`, `gDeferredPBROpaqueProgram`, `gDeferredBumpProgram`, `gDeferredMaterialProgram[]`, etc.), deferred lighting (`gDeferredSunProgram`, `gDeferredLightProgram`, `gDeferredMultiLightProgram[16]`, `gDeferredSpotLightProgram`), shadows (`gDeferredShadowProgram` and variants), environment (`gDeferredWLSkyProgram`, `gWaterProgram`, `gHazeProgram`), post-processing (tonemap, FXAA, SMAA, CAS, the bloom pyramid programs, `gCrossFilterProgram`, and the four-variant DoF gather set).

### Draw Pool & Spatial System

Expand Down
4 changes: 4 additions & 0 deletions doc/BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,10 @@ This creates a build tree at `build-<HostSystem>-<preset>/` next to the source

The first configure run downloads and builds every vcpkg dependency from source. Expect **30–60+ minutes** and several GB of disk; subsequent configures finish in seconds.

An optional [R2 binary cache](VCPKG-R2.md) can restore matching dependencies.
The setup guide covers pipeline environment variables, read-only developer
access, retention, and rollout checks.

#### Platform notes

- **macOS** — `xcode-os` and `ninja-os` (no arch suffix) pick the host architecture. Use the explicit `-arm64` / `-x64` preset to cross-build (e.g. an arm64 bundle from an Intel Mac).
Expand Down
Loading
Loading