Repository navigation
fix(smudge): drag instead of blur: pull by distance, crisp shape and grain, an even strength curve, pigment mixing - #96
Open
zednaked wants to merge 8 commits into
Conversation
…the stamp, so a dense brush drags as a spaced one does Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mp there, over the pixel as found, so the shape and grain show in the drag Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… all the way or not, its strength how much passes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r grain leaves out stays out at full strength Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…udge barely moves the paint Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…al.js, MIT), so blue dragged into yellow goes green, not grey Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the strength taking how much and how far at a gentle curve Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e pigment mix's inverse written without cancellation 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.
Problem
With dense brushes, like most imported Procreate smudges (spacing around 0.04), the smudge tool blurs in place instead of dragging paint. The result is a soft, even-coloured patch with no trace of the brush's shape or grain. Measured offscreen over thin colour stripes with a commercial "Gouache Flow" smudge: the stroke left one flat average colour, and broad colour bands showed only a few pixels of drag.
Three causes, each measured:
DEFAULT_PULL(0.93) at every stamp. A dense brush stamps many times per pixel, so it lets go of the paint within a fraction of its own size.mix(w, carried, shape·alpha·grain). Hundreds of overlapping stamps take every pixel to 100% whatever the grain, so the texture evens out to a flat colour.Changes
canvas.rs):pull^(distance / (0.1 · diameter)). Any spacing drags as far as a brush spaced at 10% of its size, the common case, which behaves as before.smudge.wgsl, theamountbuffer now always made): a pixel takes the newest carried colour at the strength of the strongest stamp that passed over it. That strength is a crisp cut of shape × grain, so each fibre drags all the way or not at all. The pixel as the stroke found it is kept inamount's second half.alpha^0.15. Measured over the slider, the effect now rises evenly from 10% to 100%: 0.40, 0.53, 0.68, 0.84, 1.03, 1.25, 1.52, 1.86, 2.30, 2.91. Before, almost nothing happened up to 50%, the effect jumped 10× between 50 and 70%, and it was flat above.1 + ks − √(ks² + 2ks)is written as1 / (1 + ks + √(ks² + 2ks)), so it doesn't lose precision in 32 bits.Checked
a_smudge_mixes_blue_into_yellow_as_paint_does: it fails on main (the greenest pixel is −3, an even grey) and passes here.cargo test -p procraft-gpu: 174 passed, 0 failed, includinga_smudge_goes_by_a_shape_at_its_own_sizeanda_stroke_reads_a_brush_file_s_grain_at_its_own_size. Both need the crisp cut's floor of 0.12, without which a zero in the shape or grain passed at half strength.Open questions
source_before) didn't make it finite in my test, and I couldn't explain why, so I left it out.🤖 Generated with Claude Code