Roof border shows the un-aged reference color - #140
Merged
Conversation
At 0.5 matte walls crossed the cutoff and bloomed alongside the lit windows, softening the whole facade. 1.0 is the point the tip already described as windows-only.
The border was the aged wall color offset darker, so it carried no information: a faded building had a faded border. It now shows the color the file would have if it were touched today (same extension hue at the freshest saturation/lightness), so the gap between the dim walls and the bright border reads as how much the file has aged. The roof icon area is untouched, and grime never reached the roof: it is wall-face only. The shader sits exactly at the WebGL2 16-attribute ceiling, so the reference color could not simply take a slot. iOrient and iDoorWidth are now one vec2 iDoor, which frees the slot and groups two door properties that were already always written together. Picked that pair over iModifiedAge/iKind because both are written only in cellMesh and read only in the vertex shader, leaving the picker and the per-frame scrub loops alone. Reference color comes from getBuildingColorForRecency(file, 1), the same curve the wall color comes off, so the two cannot drift apart. ROOF_BORDER_LIGHTNESS_DELTA and its uniform are removed: nothing derives the border from the wall anymore. Closes #118
Every declaration comment matches the trailing one-liner form its neighbours already use, instead of a block above the line.
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.
Closes #118
The roof border was the building's current (aged) wall color offset darker, so it carried no information: a faded building had a faded border. It now paints the color the file would have if it were touched today, so the gap between the dim walls and the bright border reads as how much the file has aged. Each building carries its own swatch of what its color should be.
Border strip only. The roof icon/glyph area renders exactly as before.
Reference color
getBuildingColorForRecency(file, 1)is the fresh end of the exact curve the wall color comes off (same extension hue, saturation/lightness at max), so the reference and the wall cannot drift apart. Written per-instance at rebuild; it does not vary with Timeline scrub, so the scrub loops were left alone.The issue also asked to exclude the border from the grime pass. That turned out to be unnecessary: grime only ever ran inside
renderWallFace, so the roof was never grimed.The attribute repack
The issue sketched passing the reference color as a second per-instance color attribute. That does not fit: the shader sits at exactly 16 vertex attributes, the WebGL2 guaranteed minimum. Custom
iCols, iFloors, iOrient, iDoorWidth, iFade, iIconUV, iModifiedAge, iKind(8) plus Three.js-injectedposition, normal, uv, instanceMatrix(mat4, 4 slots) andinstanceColor(8). That ceiling is whyiFadealready packs 3 values andiIconUVpacks 4. A 9th declared attribute breaks on conforming hardware.So
iOrient+iDoorWidthare now onevec2 iDoor, freeing the slot forvec3 iRefColor. Total stays at 16.That pair was chosen over
iModifiedAge/iKindbecause both are written only incellMeshand read only in the vertex shader, so the picker and the two per-frame scrub loops stay untouched. They are also semantically one thing (door orientation + door width) and were always written together.Removed
ROOF_BORDER_LIGHTNESS_DELTA, itsuRoofBorderLightnessDeltauniform, and its control-panel field. Nothing derives the border from the wall anymore, so the setting had nothing left to control. Note this is a settings field disappearing from the Buildings panel.Also on this branch
Bloom
THRESHOLDdefault0.5to1.0. At0.5matte walls crossed the cutoff and bloomed alongside the lit windows, softening the whole facade.1.0is the point the field's own tip already described as windows-only.Tests
GLSL cannot be compile-tested in vitest, so coverage targets what can drift silently:
building-shader.test.tsasserts exactly 8 declared attributes. Exceeding the ceiling is invisible to every unit test (no GPU) and only fails on real hardware.iDoor/iRefColor.Full gate green: 2819 tests, eslint, typecheck, prettier. Verified visually in the dev stack.
🤖 Generated with Claude Code