Repository navigation
Sky modernization 4: ALSky in place of the sky's objects and pools - #584
Merged
Merged
Conversation
The sky was two fake viewer objects (LLVOSky, LLVOWLSky) with pcodes, drawables and faces, pushed into every view's cull and drawn through two pools, one of them empty. Since the composite (Phase 3) only the stars still drew through a pool. ALSky (newview/alsky.h) now holds the sky's state, owned by LLPipeline as the water's surface is: - the sun and moon (LLHeavenBody, trimmed to its direction and turn as the sky sets them, its disk and its quad; their colour, the bloom's tint, and whether each is up are the current sky's, read where they are drawn) and their quads, taken at the start of the frame rather than in every view the pool ran in. Their half-extent per unit of disk radius, scale and distance is ALSkyLayers::BODY_FACTOR, the one bodyCorners builds them with, which the lens flare's probe (LLPipeline::generateLensFlareState) reads too; - the EEP textures, fetched from the ids the sky sets on the next update, at the priority they are drawn at; the bloom's only under the latched sun bloom. A rainbow or halo id the sky leaves null is LLSettingsSky's default, since every view that draws the dome samples both maps; - the star field, laid out on the General work queue (requestStars) and landed on the main thread (landStars), which keeps only the field that answers the last request: a RenderStarCount change, which takes effect without a restart, draws the last field until its own lands. The star buffer is made from the field when next drawn, and where it cannot be made it is not asked for again until a new field lands or the context changes. The cells, the brightness cull (none on the float attachment, where every star in view is drawn), and the meteors; - the per-frame uniforms (bindDome, bindComposite, useHDRISky); - the fog colour the tracker's beacons read, and for now the CPU-built legacy environment cube, moved as it was. It runs at three fixed points, the same in every view: the stars right after renderGeomDeferred's pool loop, the composite at the sky's pass, and the dome where the haze binds for water. Nothing after the opaque pools drew into the G-buffer (glow, alpha and water draw after the lighting), so the stars land where they did. ALSky::update takes the frame's sky at the start of display, before anything draws: the mirrors draw it, and the previews and impostor bakes read its environment cube. Right after LLEnvironment::update has moved the sky on, followEnvironment takes the bodies and the textures again for the main view; the mirrors, drawn before it, draw the sky as the frame began, as they take its environment. Each view takes what it draws of the sky once, at its G-buffer's clear. LLPipeline::beginSkyView has ALSky::beginView take the view's layers (ALSkyLayers::layersFor) from the kind of view, the current sky and the latched inputs, none where drawsSky says the view draws no sky, and clears the stars' attachment only where they have the stars. The stars' draw, the meteors' tick and the composite read the same layers (viewLayers). The composite's draw binds its program alone, not the G-buffer through bindDeferredShader: bindComposite binds the stars' attachment among its maps, only where the layers have them, records each map it binds, and unbindComposite lets go of those alone. It leaves the meteors out where none is on the screen. hazeOnWater asks drawsSky. gSky is folded in (D1): its callers move to gPipeline.mSky, and LLSky goes with the init and cleanup calls that existed only because the sky was an in-world object (llstartup, llworld, the agent's region hack). Its destroyGL/restoreGL are now the pipeline's releaseAllGLResources, restoreGL and cleanup. setWind, setCloudDensity and setMoonDirectionCFR fed nothing and go, and with setWind the region's average wind LLAppViewer::idle took for it; setSunDirectionCFR keeps its one effect, the sun bump maps are lit by. LLFace's moon ray and the sun and moon beacons take their directions from LLEnvironment. Deleted: LLVOSky, LLVOWLSky, LLDrawPoolSky, LLDrawPoolWLSky, POOL_SKY, POOL_WL_SKY, LL_VO_SKY, LL_VO_WL_SKY and their special cases, the cull pushes, the pool members and their lookups, the drawable's sky case, the pipeline's unread LLCullResult mSky, and the bump pool's uncalled bindCubeMap/unbindCubeMap. RENDER_TYPE_SKY and RENDER_TYPE_WL_SKY stay, beside RENDER_TYPE_CLOUDS outside the pool range; nothing persists pool or render-type numbers (the menu names its types by string). LLAtmospherics' constructor read two settings, SkyAmbientScale and SkyNightColorShift, into members nothing reads; ALSky constructs it with the pipeline, before settings load, so those reads go, and the two settings with them (settings.xml and their Portuguese comments). LLGLSLShader::bindTexture given a null texture or render target, and bindDepthTexture given a null target, bind nothing and return the unit all the same, let go of what an earlier bind left there, so the draw reads none of it; ALTextureSlot::bindFast given a null texture, or one with no GL image, lets its slot go likewise. llglslshader_gl_test binds each null over a unit holding a target and finds the unit let go, and the disable a reader pairs with the bind finding nothing to release under the debug checks. quadCoord, the CPU mirror of skyQuadCoord that only alskylayers_test calls, moves out of ALSkyLayers into it. alskydome_gl_test takes the sky tests' shared helpers (alskyraster_gl.h, which RAINBOW_SKY joins) in place of its own copies, and holds the haze on water against itself with its weight floor at zero: over a made-up scene whose dome weight runs from zero through the floor, the two are one picture where the weight is zero or at the floor and past it, and under the floor differ by no more than the floor allows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Where reflection probes are off (the low feature class, every Intel legacy session, RenderReflectionsEnabled off) the shiny and probe-less reflections read an environment cube. The CPU built it through LLAtmospherics a face a frame. Now ALSky bakes it from windlightDome whenever the sky changes, at most every quarter second as before, then mips it (D2): - ALSkyCube (alrender): each GL face's directions in the agent's frame the readers look it up in, and their turn into the dome's frame (toDome, ALFarPlane::skyFrame); the cube's storage (RGBA8, 64 a face as before, every level, LEVELS worked from SIZE), counted whole as an image's (LLImageGLMemory::OTHER_TEXTURE), every face and level mid grey as the readers take it (NEUTRAL) until its first bake; and the bake. The six faces draw side by side in one pass over a strip, then are copied into their faces and mipped (LLImageGL::generateMipmaps), so nothing is bound over the program's own texture units between them. - deferred/skyCubeF.glsl: windlightDome along each texel's direction, halved as the haze takes it, the scale the readers double (applyLegacyEnv). Built only without probes (ALShaderInputs). - ALRenderResourcePlan::Id::EnvironmentCube: a persistent texture of the pipeline's own, wanted only without probes. The reconcile makes and frees it; made neutral, it is bound from the frame it is made in, wherever the plan wants it, and where it is not the unit is let go. RenderWater no longer decides whether it exists. - The bake runs when windlightDome's inputs change: its Environment block terms, its loose uniforms, and the rainbow and halo maps as far as they have loaded. A term counts as changed only past ALSkyCube::TERM_TOLERANCE, 0.0005, of the larger of its two values (termsAlike), the comparison the CPU cube made of its atmospherics (approximatelyEqual): a sky that has drifted less differs from its bake by under a step of its eight bits. The fog colour the tracker's beacons read follows the same change, with probes on too, where it was never updated. - Both run from ALSky::followEnvironment, once LLEnvironment::update has packed the Environment block the main view takes, whether or not the sky is drawn: the cube lights the reflections, and the fog colour the beacons. A bake that cannot run, its program not built or its strip not made, leaves the sky untaken, and is tried again at the same interval until one does. LLAtmospherics keeps the fog colour alone: the sky texture's path, LLHaze and the atmospherics' comparisons go, and with them the members of AtmosphericsVars nothing reads (the haze below the clouds, the clouds' colours and density, the distance multiplier, the cloud shadow and the light transmittance). LLHeavenBody keeps its disk and its quad alone: the quads turn by the current sky's rotations, and nothing read its copies of the directions and turns. ALSkyDome, the dome's mesh, which nothing in the viewer draws, moves out of alrender into the sky tests' support (alskyraster_gl.h), for the raster sky they draw. alskycube_test pins each texel's direction against GL's face selection table, and holds termsAlike to the tolerance either side of it. alskycube_gl_test bakes with the viewer's program and samples every texel against windlightDome (0.56/255 at most, the rounding to eight bits), checks each face's last level against the mean of its first, checks that a cube never baked is complete and neutral at every level, read back and through the trilinear lookup the readers take, and that its storage is counted whole from its making to its deletion, and reports the bake against the old CPU cube, kept in the test. That cube differs on purpose. It held WindLight's colour along the opposite direction of each lookup (calcSkyColorInDir negates every axis), at a quarter saturation, and below -0.02 a dim fog-grey ground. Midday: above its horizon 14.6/255 on average (83 at most), below it 72.5/255 (115). Sunset: 17.9 (242, at the sun's glow) and 22.6 (139). Moonlit night: 2.2 (16) and 8.9 (19). Turning the mirror round changes little (15.7 for 14.6 at midday above the horizon), and full saturation with the haze in place of the ground leaves 13.4 above and 57.1 below: most of it is the old CPU model itself, which has no below-cloud blend, rainbow or halo, and dims the sun again by the haze's transmittance along the ray. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The sky is no longer a viewer object, a pool or a cull push: say what holds and draws it, beside the water's paragraph, and drop LLVOWLSky, POOL_WL_SKY and the sky pushes from the cutout's choke points. The paragraph says when ALSky takes the sky, at the start of display before the mirrors draw it and again once the environment update has moved it on, before the main view; that the environment cube is neutral grey until its first bake; that the star field is laid out on the General queue; and that each view takes what it draws of the sky once, at its G-buffer's clear, which clears the stars' attachment only where the view draws them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
LLAtmospherics worked out three things on each sky update: the fog colour the tracker's beacons fade into, a fog distance from the fog ratio, and a GL fog colour, the water's below its surface. Only the first has a reader. The fog distance went into a local, and nothing has asked for the GL fog colour or the ratio since before the sky moved to ALSky (develop's LLSky::getFogRatio and LLVOSky::getGLFogColor had no caller either). So the ratio goes (ALSky::setFogRatio/getFogRatio, its first-update read of RenderFogRatio and the setting's listener), and so do the GL fog colour and its underwater branch with the two settings only it read, WaterGLFogDepthScale and WaterGLFogDepthFloor. updateFog takes the direction to the light alone, and the file drops the includes only those paths needed. RenderFogRatio goes too, from settings.xml and its Portuguese comment, the three feature tables and the feature manager's skipped list. The test spinner floater's control spinner takes RenderDebugNormalScale in its place, a setting only the normals' debug display reads, its range 0 to 1 at two decimals. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The flare's state pass probes how much of the sun or the moon the world hides over the body's own angular radius. It worked that radius out by hand from what ALSkyLayers::bodyCorners builds the quad from: the factor, the disk radius, the sky's scale and the quad's growth toward the horizon, 1 + (1 - z) / 4, the mean of its 1.3 and 1.2. It now reads the quad the sky draws (LLHeavenBody::angularHalfSize, the mean of the corners' half-width and half-height over their distance), so retuning the disc moves the probe with it. The two agree wherever a body is up and its scale is at least 0.01, the floor the old sum held it to. They differ only while neither body is up, when the pass takes the moon and the old sum the direction the lighting falls back to, level, where the moon's quad lies lower and larger; and at a scale under 0.01, where the probe now shrinks with the quad. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ALStarField::pointDraws gives glMultiDrawArrays one run a cell in view, the prefix of it bright enough to show, so at dusk a view draws over a hundred short runs. Drawing every point of the cells in view instead, the runs that meet merged, and leaving the faint stars out in the vertex stage would make the runs few. alstarfield_gl_bench measures the two at the default count, 1920x1080 into R11G11B10F, through a level 60-degree view and a 100-degree one 60 degrees up, at faintest 0 (night) and 20, 40, 80 and 140 (dusk), on NVIDIA: - the CPU's time is the same either way, 1.2-1.4 us and 2.2-2.3 us: glMultiDrawArrays is one call whatever its runs; - at night the two draw the same runs, 5.2 against 5.1 us and 14.2 against 14.2 us of GPU; - at dusk the prefixes are cheaper on the GPU, the more so the fainter the stars left out: 3.5 against 3.7 us at faintest 20 and 0.8 against 1.4 us at 140 in the level view (121 runs against 13), 8.8 against 8.8 us and 1.8 against 3.5 us in the wide one (298 runs against 16). A vertex left out still runs, and a run costs less than the vertices. So pointDraws keeps its prefixes, and the benchmark stays as the reason. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The comments carried over from the raster clouds and aurora told how each fade came to be: what WindLight drew, a rate the aurora's fade once had, a hard edge a user once saw. They now say what each fade does and, for the clouds, why SL-10751's fade is not the one used. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A comma in a Catch2 test spec means "or", so a name with one cannot be run by its name alone. Seven of alwatersurface_gl_test's cases had one; they read the same without it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
LLGLSLShader::addConstant defined LL_SHADER_CONST_CLOUD_MOON_DEPTH and LL_SHADER_CONST_STAR_DEPTH into a program's permutations (SL-14113), and no shader reads either. The raster cloud and moon programs that took the first are gone, and the star program's second only added a dead key to its permutations. The enum, the two tables and addConstant go, with the star program's call and the GL tests' copies of it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gDeferredHighlightProgram (deferred/highlightF.glsl) was built and unloaded but never bound: the highlights draw through gHighlightProgram and its normal and specular twins, forward. It was the last program to flag a fragment in front of the far plane SKIP_ATMOS but one: class 1's material program (deferred/materialF.glsl), which writes a flat magenta into the albedo with no normal. The soften pass showed such a pixel through skyColor, the sky's old decode: with the emissive buffer it read the emissive, which that program leaves black, and scaled it by sky_hdr_scale. It now shows the albedo as it is, linear through the sRGB target's decode, and softenLightF neither declares sky_hdr_scale nor keeps skyColor. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
Important Review skippedToo many files! This PR contains 102 files, which is 2 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.
|
quadCoord left alskylayers.cpp for alskylayers_test.cpp on this branch, so its scale-free parallel test is carried to the test's copy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A meteor end on to the camera has its two ends apart on the screen by rounding alone. packMeteors left a streak out only where that came to exactly nothing, so whether it packed one hung on how the compiler fused the arithmetic: the sanitized Clang build packed four of the layers test's meteors where every other build packed five. A streak shorter than a hundredth of a pixel each way is now left out, as the CPU test's end on meteor already was. Such a streak covers no pixel's centre but by chance, and the old program's sliver for this one drew nothing. The CPU test adds an end on meteor whose head rounding has moved, which packMeteors packed before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Martin-Pitt
pushed a commit
to Martin-Pitt/Alchemy-Skooma
that referenced
this pull request
Oct 27, 2026
The Windows ARM Tests build stopped at the link of xui_translate_repair (AlchemyViewer#581, AlchemyViewer#584) and of llui_libtest (AlchemyViewer#578) with "The process cannot access the file because it is being used by another process." The half of the command that failed is the POST_BUILD "vcpkg z-applocal" that vcpkg's toolchain hangs on every executable declared while VCPKG_APPLOCAL_DEPS is on, and the three llui utilities, ready at the same moment, link together. The directory they share, sharedlibs/<config>, is not what fails. They import no port's DLL on Windows, where the spell checker is the system's, so z-applocal copies nothing. Eighty concurrent z-applocal runs, each into a directory of its own, fail the same way 3 times in 640, and eighty concurrent "vcpkg version" runs 6 times in 640: a start of vcpkg.exe beside another fails now and then, as d5095f9 found for the test binaries. So these are declared with the step off, as al_add_test_binary declares a test: the three utilities, http_texture_load (the other executable in sharedlibs/<config>) and llimage_libtest. Each exists only in a tests build and runs from the build tree; xui_overlay_check's ctest entry still runs with AL_TEST_ENVIRONMENT's PATH. Serializing them instead would leave them racing every other launch of vcpkg.exe in the build, and a Ninja job pool does nothing under MSBuild. With AL_USE_WINSPELLCHECK turned off, llui links Hunspell's DLL, which llui_libtest and xui_translate_repair no longer copy into sharedlibs/<config>; the llui tests, whose PATH names that directory, would then need vcpkg's bin directory on it. No CI row builds that way. Proof: a tests-on vs2026-os configure leaves z-applocal on five projects, alchemy-bin, dullahan_host, media_plugin_cef, media_plugin_libvlc and template_verifier, and on none of these; the three utilities build in Release and ctest -R xui_overlay_check passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 4 of the sky modernization (
doc/SKY_MODERNIZATION.md):ALSkyin place of the sky's viewer objects and pools. Stacked on #583 (rye/sky-p3-composite).What changes
ALSkyholds the sky's state (newview/alsky.h), owned byLLPipeline.LLVOSky,LLVOWLSky,LLDrawPoolSky,LLDrawPoolWLSky,POOL_SKY/POOL_WL_SKY,gSkyandLLSkyare deleted (D1).windlightDome(ALSkyCube, D2).OTHER_TEXTURE.LLAtmospherics;RenderFogRatioand other orphaned settings are deleted;ARCHITECTURE.mddescribes the sky asALSkydraws it.Look changes
Probes-off sessions (low class, Intel legacy, reflections off) reflect the GPU-baked dome in place of the old CPU cube. The old cube held WindLight's colour along the opposite of each lookup, at quarter saturation.
Verified
c32de66abf:ctest -LE manualpasses 557/557;Not verified
🤖 Generated with Claude Code