mirror of
https://github.com/storytold/figcraft.git
synced 2026-11-07 19:12:41 +00:00
* M3: glass bends with the reference tool's thick-lens profile and splits its colours over 8 steps (#1885) The backdrop bends most a 1-unit bevel in from the edge, falls off as the 3.5th power of the way out of the curve to nothing `depth` further in, and moves a fifth as much on the bevel itself (it fell off as the square of the way in from the very edge). Dispersion samples each channel at 8 steps along the bend with a triangular window, red moving furthest and blue least (it was three samples, blue furthest), as far apart as the reference tool's: at 100% red and blue move 0.16 of the bend apart (`Glass::DISPERSION_SPREAD`). `Glass::max_bend` bounds red's furthest step, so the backdrop read around a pane covers every sample, and the field margin covers the bevel. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * M3: glass's bend stays within `max_bend`, checked on a single bright pixel too (#1885) Review follow-up: the bend reaches `depth` × `refraction` a bevel in from the edge, so `Glass::max_bend` drops its 0.999 and bounds it, as a test now checks for several refractions. A single white pixel on black pins the dispersion's triangular window, which a ramp and a flat backdrop can't tell from one centred sample. The parity assessment records the bend, the dispersion and how they were measured against the reference tool. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * M3: glass's light is a line on its bevel, and splay turns the bend towards the centre (#1885) The light is a line on the 1-unit bevel added to the backdrop, as the reference tool's: fully where the edge faces the light, none below 0.35 of facing it and 0.6 as much on the opposite side, with a faint gradient across the curve, 5% darker facing the light and lighter opposite. It was a glow mixed towards white, as deep as `splay` made it, so `light_reach` goes. `splay` turns the bend from along the edge's normal towards the way away from the layer's centre, and no longer widens the light: files with a splay above 0 look different. The direction to the centre is worked out in the shape's own frame (`own_frame`, shared with the field cache), so cut renders match the whole one byte for byte. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * M3: glass bends towards its core, and rounded rectangles work it out in closed form (#1885) The backdrop bends towards the glass's core, the shape shrunk by `depth` and the bevel, instead of along the smoothed edge normal: round a sharp corner the bend turns smoothly instead of meeting along the diagonal, and a part thinner than twice that (a capsule, a letter's stroke) bends across itself towards its own middle, pixels about as deep as any within 2 px. The fields keep a bend direction beside the normal (an exact feature transform from the core, box-blurred once), their key includes the core's depth, and their margin covers the core. Rectangles, frames, components, instances and sections whose corners aren't smoothed, under a rotation, flip and even scale, work their glass out in closed form (`AnalyticRect`): signed distance, the light's normal (corners rounded to at least the bevel) and the bend direction (corners rounded to the core) per pixel, in the layer's own frame, with nothing to rasterise, transform or keep. A zoom frame draws in 40 ms instead of 54 and a resize frame in 46 instead of 67 (`glass_render_timings`, release, 2×). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * M3: cut renders of glass match with splay turning a dispersed bend (#1885) Review follow-up: the cut-versus-whole test had splay only on looks without refraction, so no turned bend reached the dispersion. A look with splay 1 and the default bend and dispersion now renders the same however it is cut. The parity assessment records the light on the bevel and splay's new meaning. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * M8: a glass too big to keep bends along its normals, and the core's fields take less memory (#1885) Review follow-up: a shape that doesn't use the closed form and whose whole window at the zoom, with the core's margin, would pass `MAX_SHAPE_PX` (a large vector, text or smoothed rectangle, or a deep glass far zoomed in) bends along its edge normals instead of working out a core, with the plain margin. The choice depends on the shape and the zoom alone, so every band and patch of a render agrees, and no render works out a core over more pixels than a kept shape holds. The core's feature transform keeps `u32` indices (16 bytes a pixel) and drops its maxima and core before making the directions. The edge normals are box-blurred twice again and the bend directions once, as their docs say: the two were swapped. The parity assessment records the bend towards the core and the closed form. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * M3: glass's flat inside skips the bend's curve, and full dispersion stays within `max_bend` (#1885) Review follow-up: `bend_at` returns 0 straight away past `depth` + the bevel, where the curve and the bevel's easing are both 0, instead of working out a power of 0 for every pixel of a pane's flat inside. A test moves one white pixel along a row under every bend of the profile at full dispersion and checks that no channel ever reads it further out than `Glass::max_bend`, which sizes the backdrop read around a pane. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * M3: glass's light shows over a transparent backdrop, and its flat inside skips the light (#1885) Review follow-up: the light was added to the backdrop's colour and then clamped to the backdrop's alpha, so with nothing under the glass (an export of the pane alone) the line on the bevel vanished, where the old glow raised the alpha and showed. Now the alpha rises as far as the lit colour needs (`lit`), and stays the backdrop's wherever the light fits under it, so renders over an opaque backdrop don't change. Past `depth` + the bevel the rim light, the gradient and the bend are all 0, so those pixels take one sample of the backdrop and skip the light's direction, facing and splay work, as the old glow's `reach` early-out did. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * M8: a kept glass shape works out only its bend again when the depth changes, and a core gets a wider margin (#1885) Review follow-up. The field cache was keyed on the core's exact depth, so every step of the Depth slider missed it and worked the whole shape out again over a window twice as wide: coverage, distances, normals, the feature transform and the blur, every frame, for every shape that isn't a plain rounded rectangle. Only the bend directions depend on the depth. The kept fields (`EdgeFields`: coverage, distances, normals) are now keyed without it, and hold the bend directions for the last two depths asked for beside them, so a new depth works out only those (`EdgeFields::bends`). Two glass layers of one shape at different depths each keep theirs. The margin a core takes was `reach` + 2 px past the plain one, but the nearest core pixel can be √2 × `reach` away round a sharp corner, past what that covers once `reach` is over about 91 px. It is now 1.5 × `reach` + 2 px past the plain margin. The cut-through-the-pane test gets a 60-unit-deep look (a core 122 px in at 2×). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Glass: splay's doc says splay 0 bends towards the core Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Oleksii Sukholita <oleksii.sukholita@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>