diff options
Diffstat (limited to 'docs/effects.md')
| -rw-r--r-- | docs/effects.md | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/docs/effects.md b/docs/effects.md index 08fd3d88..0e0ad51a 100644 --- a/docs/effects.md +++ b/docs/effects.md @@ -13,6 +13,19 @@ its text. A dim touches only the unfocused panes, with the same floor, and the focused pane's text is never at less contrast than theirs (tests in src/draw.zig). +**Density.** A pixel shell draws every size given in pixels in logical +pixels, `dp()` in gui.zig (SDL's window display scale, rounded, at least +one; `PARDES_TEST_SCALE` forces one in a harness, and a test window is 1x +otherwise): the rules (`rule_px`), the tag rule, the grip's ring and its +dirty gap and mode bars, the rail's gap to the text and its minimum, the +thumb's inset, the rim, a bar cursor's minimum width, underline and +strikethrough thickness, the rule-grab margin, and the Crt's scanline and +mask periods (`pardesScale`). Left as they are: what is measured in cells +or the tagline (the rail's width, `rail_px` scaled with the tagline; Lift's +blur and offsets; every motion, in cells), Shadertoy's iResolution, +fragCoord and iMouse (the display's pixels, as ghostty's), and the pet and +touch debug overlays. + Each effect of docs/render-pipeline.md §9 lands behind its own switch, off, and is kept only after a feel review (§8.4): a frame series on the virtual clock, a recording, and a verdict — keep, polish or drop — with one line of @@ -24,6 +37,13 @@ why. The verdict is the user's. | Ripple, Glitch | — | removed | live window | dropped by the user after a live look | | G1 lift | `Lift shadow\|rim\|auto` (off), `InactiveDim <percent>` | opt-in until the focus-lift default is decided | lift-shots-2 (off, shadow, rim, auto on acme, dusk, forge); frame series + mp4 per Motion flavour | shadow on acme: keep as is. Round 1 dropped glow and surface (surface lowered the focused text's contrast) and made rim a hairline just above the focused tag (light on a dark page, shade on a light one). auto on a dark page recedes the others (InactiveDim 30) | | G3 cursor | follows `Motion`; `CursorBlink on\|off` (on) | glide on by default through the default flavour (smooth); blink on (decision 6) | .scratch/render/cursor/cursor-flavours-grid.mp4 (and quarter speed), raw/<flavour>/<motion>/ | pending | +| G4 bloom, vignette, grain | `Bloom`, `Vignette`, `Grain` `0..3` (off) | bundled post passes; none touches a tag, grip, notice or the cursor (pardesSpare); each capped per theme (pardesCap) | .scratch/render/{bloom,vignette,grain}/ (levels 0-3 on forge, dusk, acme; crops; mp4 stepping through the levels) | pending | +| G5 lapis | `Theme lapis` (its `decor`) | a native theme with ornament: tag plaques with hard shadows inside their bands (the focused one striped), dots, rail checker, title shadow | .scratch/render/lapis/ (whole window at 1x and 2x, crops, a slide mp4) | pending | +| G6 smooth scroll | follows `Motion` (on through the default smooth; `Motion off` lands at once) | a mouse wheel's notch glides, a touchpad follows the finger | .scratch/render/scroll/ (glide-<flavour>.mp4, quarter speed, strips) | pending | +| G7 panel transitions | `PanelSlide`, `PanelZoom`, `PanelVertical`, `PanelDissolve` (off) with `Motion` | a moving pane casts a shadow; a retargeted move keeps its speed; the GUI's dissolve is a crossfade | .scratch/render/transitions/ (slide smooth, bouncy, retargeted; dissolve) | pending | +| G8 notice chips | follows `Motion` and `Lift` | a notice floats in tier 4 on a lift (shadow) while Lift is on, drops in easing out and dissolves easing in, quicker than it came (150 ms against 180) | .scratch/render/notices/ (acme, forge) | pending | +| G9 selection glow | `SelectionGlow on\|off` (off) | a soft halo of the selection's colour round each block of it in a body, fading in over 100 ms | .scratch/render/selection/ (forge, acme, lapis; lapis-glow-zoom.png) | pending | +| G10 theme crossfade | always (a theme change) | the chrome's colours fade through OKLab, easing in and out (out when retargeted) | .scratch/render/crossfade/ (forge, lapis, acme cut short by dusk) | pending | ## Motion flavours @@ -83,3 +103,107 @@ forge's text goes from 15.5:1 to 11.2:1 and dusk's from 6.4:1 to 4.8:1, plainly quieter and still easy reading; at 10 forge barely moves (14.1:1). On a light page the same percent bites far harder (acme: 7.0:1 at 10, the 4.5 floor at 30), which is why `auto` shades there instead of dimming. + +Notes on G4: the three are post passes, so each is a frame of cost only +when it is in the chain. None moves (grain is still, by choice: moving +grain would redraw every frame for a texture), so none asks for frames. +The focus rule is kept by construction: the shell hands every pass the +rectangles of the tags (with their grips), the column and workspace tags, +the notices and the cursor, and a bundled pass leaves them as they are; its +strength is capped per theme so the text on the page and the selection's +text keep min(their contrast, 4.5) (Post.capsOf, tested over the native +themes). Bloom takes only what is brighter than the page, so a light page +does not bloom at all; its glow is a dual Kawase blur in float textures at +half size and down (3 to 5 steps by level), within §8.2's 5%. The vignette +is round, starts halfway to a corner and reaches 10, 18 and 28%. Grain is +1.5, 3 and 5 of 255 on page-coloured pixels only, a logical pixel big. +Found on the way: SDL GPU binds at most 4 KiB of a uniform block, so every +Shadertoy colour after the palette (iBackgroundColor and on) read zero; the +block is now cut in three with ghostty's names and order kept. + +Notes on G5: lapis (src/themes/lapis.zig) is 0x4200.cafe's lapis.css in +pardes's chrome, drawn inside it (decision 1). The tags are the site's +trail and title bars: every tag a plaque in its own band, framed in gold +(2 px, the trail's border) with the trail's hard vermilion shadow (5 px) +down and right, the frame and the shadow both inside the band's rows and +columns, so no shadow reaches a body, a grip or the next pane; down, the +shadow gets what the band's slack under the text leaves (a pixel or three +at a tagline under the body's size, more at a larger one), to the right +its full offset. The focused pane's plaque is the code window's title bar, +gold and lapis stripes of 2 px, its words on plates of the focused ground +(the words' cells stay opaque, the blanks between let the stripes show), +so the focus indicator is plainer to see than any theme's tint, never +less; the unfocused ones are plain. Column and workspace tags take the +quieter object-label language: a 1 px frame and a 2 px shadow of vermilion +toward the page. The plaques are decor drawn under their cells (a group's +under range) with the cells blended premultiplied over them; blank tag +cells on the tag's ground are see-through there. They need an opaque +window: under WindowOpacity 100 the tags are plain. Also from the site: +the colours (lapis-deep page, vellum text, gold names and rules, +vermilion rubrics and tag rule, gold selection in lapis ink), the page's +gold dot grid (22 px, #e8c46a22) on page-coloured cells only, fixed to the +window; the dither frame's checker in the scroll track, anchored to its +rail (the thumb solid gold); the titles' vermilion offset shadow under a +file name's letters. Left out: Crimson Pro and Departure Mono, the +ornaments, a decor crossfade (it snaps while the colours fade). The tty +shows the colours alone: a tag row abuts its body and its neighbour, so +there is no cell for a shadow row or column. + +Notes on G6: a mouse wheel's notch (SDL's whole-number step) scrolls the +core by its lines at once, so keys and clicks act where the text is, and +the picture follows on the Motion flavour's spring at half again its pace, +critically damped whatever the flavour (text never passes its mark; §8.1), +from its current speed, so notches in a row carry on without a stall. How +far the rows moved is measured on the next frame against the last (a +wrapped line's rows, a terminal's output), within a couple of rows' slack +for the cursor's line and its number moving with the scroll; the rows that +left are kept and drawn in the gap the lag opens, and a lag is never more +than the body's height (a flick past that jumps). A touchpad's fractions +keep moving the picture under the finger, as before; there is no momentum +(SDL reports no finger lift on a wheel). The glide runs on the core's +continuous path (Pardes.shell_continuous), so the shell draws every loop +while it moves and a virtual clock moves with it; idle, it costs nothing. +A PDF page scrolls as before. The test feed takes wheel events +(ESC]777;mouse;wheel;<amount>;<x>;<y>BEL). + +Notes on G7: the geometry already followed the Motion flavour's spring +(sxrrwplk); a move retargeted mid-way now carries its speed on +(Track.launch, from the old move's speed along the new one's longest +side), so a second Newcol during a slide bends the motion instead of +stopping it dead. A pane that slides, zooms or rises stands off the page +while it moves: a soft shadow as Lift's, at sin(pi x progress) of its +strength (none as it sets out or lands), on the other panes' bodies and +rails alone and under the same contrast ceiling, moving with the pane. The +GUI's PanelDissolve is a crossfade: a changed cell's new form drawn whole, +its old one over it at 1 - progress; the blend is in sRGB, not linear +light (a two-colour mix in linear light needs both in one shader; open +point 3). The tty keeps its per-cell swap. GUI golden 18-mid-transition +changes (the slide's shadow at frame 6). + +Notes on G8: most of it was there: the drop eases out on the Motion +flavour's spring (sxrrwplk), the dissolve eases in, and a notice floats in +tier 4 with Lift's shadow at its fade while Lift is on, on the bodies +alone. What G8 changed: leaving was slower than arriving (a 300 ms +dissolve against a 180 ms fall); §8.1 wants leaving the quicker, in 100 to +160 ms, so MessageDissolve now defaults to 150 (a test holds both bands). + +Notes on G9: the halo is Lift's soft kind in the selection's own colour, +cast by each block of selected rows in a pane body (the rows that touch), +with the block as its caster, so the selection itself is never touched; +a cursor beside a block joins the caster, so it is never glowed over +either. It stays on bodies (never a tag or a grip), is at most 22% (§8.2: +coloured glows at most 25%) and less where the text round it would drop +below min(its contrast, 4.5); it comes up over 100 ms with an ease-out +(micro-feedback), on the core's continuous path, and is not drawn while +panes move. The blocks are read from the cells painted in the theme's +selection colour, a pixel shell's inference (§1.5, smell 4) until +selections are regions. + +Notes on G10: a theme change already faded the chrome (tags, rules, grips, +rails) over 10 frames (160 ms, in §8.1's 150 to 250 for a state change), +mixing sRGB bytes linearly in time. Now each colour goes through OKLab, so +a fade between two hues keeps its lightness instead of dipping dark and +muddy, on a smooth ease-in-out; a change made mid-fade sets off from where +it shows and eases out, so it moves at once instead of stalling. The page, +its text and the syntax colours still change at once with the theme, as +before: fading them would re-resolve every cell each frame. |
