feat(paint): an inflated material whose shading follows the silhouette - #399
Merged
Merged
Conversation
The three presets from #357 compute their highlight on the node's **box** and then clip it. On a star cut out of a rectangle that gives one band of light across the box, not a relief per branch — the shape stays a flat varnished plane, which is what #385 measured against a reference. `inflated` derives the shading from the silhouette instead. The clipped path is rasterised and blurred, and the **gradient of that blurred mask is the surface normal**, lit by the scene's own `light` from #357. Each branch has its own edge, so each gets its own highlight and its own hollow. `bevel` sets how far in the rounding reaches, `softness` the profile from a hard chamfer to a cushion. The first version banded visibly: with a large `bevel` the mask's gradient is shallow, and sampling adjacent pixels quantises it into concentric steps on 8-bit alpha. The gradient stencil now widens with `bevel`, which is the same reason the artefact existed — measure a shallow slope over a longer baseline. Three tests. The decisive one counts separate bright runs along a row cutting two branches, and fails without the relief with `glossy=0, inflated=0`. The other two assert equality and pass both ways on purpose: nothing paints outside the silhouette, and `intensity: 0` is byte-identical to no material at all. Also here, because it obstructed this work four times: `dot_map_terminates_on_a_zero_dot_spacing` guards against a runaway loop with a 10-second wall-clock budget, and exceeded it under parallel build load while painting perfectly well. The budget is 120 seconds now. The guard answers "does this terminate", and 10 versus 120 seconds makes no difference to that question while making every difference to whether the suite is trustworthy during a chantier. Closes #385
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 #385. Refs #388.
The gap it closes
The three presets from #357 compute their highlight on the node's box, then clip it. On a five-branch star cut out of a rectangle, that is one band of light across the box — the shape reads as a flat varnished plane, not a volume.
inflatedderives the shading from the silhouette: the clipped path is rasterised and blurred, and the gradient of that blurred mask is the surface normal, lit by the scene's ownlight. Each branch has its own edge, so each gets its own highlight and hollow.Rendered side by side —
glossy,inflatedatbevel: 26, softness: 0.6,inflatedatbevel: 8, softness: 0.1— the first is one flat gradient across the bounding box and the other two have relief on every branch.An artefact I had to fix, not ship
The first version banded visibly: with a large
bevelthe mask's gradient is shallow, and sampling adjacent pixels quantises it into concentric steps on 8-bit alpha. The gradient stencil now widens withbevel— the same fact that caused the artefact is what fixes it: measure a shallow slope over a longer baseline.Verification
Three tests. The decisive one counts separate bright runs along a scanline cutting two branches:
The other two assert equality and pass both ways on purpose — nothing paints outside the silhouette, and
intensity: 0is byte-identical to declaring no material.Three things the rule file leads with
bevelmust stay small relative to the shape. It is both the blur width and the scale the slope is measured at, so a large bevel on a small shape drowns the silhouette before a normal can be taken from it. At most a quarter of the shape's smallest dimension.highlightandedge. No specular return at all — its light is entirely geometric. Next to aglossynode that is two lighting models in one frame, which may be intended but is not a tuning variant.Also in here
dot_map_terminates_on_a_zero_dot_spacingguards against a runaway loop with a 10-second wall-clock budget, and blew it four separate times today under parallel build load while painting perfectly well. It is 120 seconds now. The guard answers "does this terminate", and 10 versus 120 seconds makes no difference to that question while making every difference to whether the suite can be trusted during a chantier.Two
ffmpeg-dependent tests have the same shape of problem from a different cause; they are not touched here.cargo fmt --all --checkandcargo clippy --workspace --all-targets -- -D warningsclean.Written comment-free, per the codebase-wide rule from #345.