Commit Graph
209 Commits
Author SHA1 Message Date
aiongg d57fed9fcc Merge #1837: Text: draw Faux Bold and synthetic bold (#1676) (@HEOJUNFO) 2026-10-23 21:26:20 +00:00
SBaksa c17f9eb959 Text Range Selector: Start, End and Offset show as counts with Units = Index (#1814)
With Units set to Index the selector already counts characters (words,
lines), but the timeline kept showing Start, End and Offset as
percentages ("3.0%"), so switching looked like it did nothing. They are
now shown without the % sign while Units is Index
(render::text::in_index_units).
2026-10-19 21:08:16 +11:00
heojunfoandClaude Opus 5.5 4bc40c7ac3 Text: grow Faux Bold per axis under a non-uniform scale (#1676)
Synthetic bold grows a glyph's outline in its own space, so a
non-uniform character Scale stretches it more along one axis. The patch
and layer bounds reserved it through mean_scale and could clip the
stretched side; they now reserve how far the bold reaches along x and y.

A run of solid fills grows its glyphs together in layer space by one
radius, which only matches when the bold stays round there: a bold glyph
whose matrix stretches or skews is no longer gathered into a run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 11:04:36 +09:00
heojunfoandClaude Opus 5.5 a5f096324d Text: draw Faux Bold and synthetic bold (#1676)
The layout marks a glyph synth_bold when Faux Bold is on, or when a bold
style is asked of a family without a bold face, but the renderer never
read it, so both drew as regular.

PlacedGlyph now carries the bold radius (0.03 em, which brings Inter
Regular's stems to Inter Bold's). A bold fill is the outline's coverage
merged with a round stroke twice that wide, and a bold glyph's stroke is
the band between the outline grown by radius ± half the stroke width, so
it follows the bolder shape. Runs of solid fills only merge glyphs of the
same bold radius, and the patch and layer bounds grow by it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 10:36:16 +09:00
Brandon Thomas a01f681551 Merge pull request #1704 2026-10-18 09:35:35 -04:00
Brandon Thomas 4d61409662 Merge pull request #1672 2026-10-18 09:35:34 -04:00
Brandon Thomas c44c51212c Merge pull request #1413 2026-10-18 09:35:33 -04:00
Brandon Thomas 53c84d7342 Merge pull request #1356 2026-10-18 09:35:33 -04:00
Brandon Thomas de7c8d6dd6 Merge pull request #1271 2026-10-18 09:35:33 -04:00
heojunfoandClaude Opus 5.5 ee5c9ac2dd Advanced 3D: Accepts Shadows Only draws just the shadow (#1691)
The Advanced 3D renderer folded Accepts Shadows (Off/On/Only) into a
bool, so a shadow catcher set to Only drew as an ordinary lit surface.
The material now carries shadows_only. Such a fragment draws black at
the strongest shadow a light casts on it, as Classic 3D does, and it
goes in the blended pass so what is behind it shows through. The CPU
shader and advanced3d.wgsl get the same branch.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-17 13:31:08 +09:00
Marco Arnulfo 9d56675da9 Text: drag a Range Selector's Start and End in the Composition viewer (#1011) 2026-10-16 18:45:11 +02:00
BFlat c6f6f9b373 Merge pull request #1511 from MatejKozlovsky/fallback-parallel
Export: render in parallel once the GPU stops for good
2026-10-16 19:01:38 +07:00
BFlat 23f1def7bc Merge pull request #1444 from wixar172/fix/stroke-miter-padding
Shapes: a stroke's buffer is padded by the miter limit only where it has miter joins
2026-10-16 19:00:41 +07:00
bflatastic f85f34c089 Merge remote-tracking branch 'origin/main' into pr-1379
# Conflicts:
#	crates/render/src/tests.rs
2026-10-16 18:14:14 +07:00
BFlat eac13d1cf1 Merge pull request #948 from Themolx/solo-outside-active-range
Solo: exclude other layers even when the soloed layer is outside its time range
2026-10-16 18:10:06 +07:00
Matej Kozlovský 2603a6f0e0 Export: render in parallel once the GPU stops for good 2026-10-15 01:30:54 +02:00
wixar172andClaude Opus 5.5 9846c7255d Shapes: a stroke's buffer is padded by the miter limit only where it has miter joins
draw_bounds padded every stroke by width × miter limit / 2 on each side, joins or
not. A straight 1080 px wide wipe used as a track matte became a 4326×6366 layer
buffer (~440 MB as RGBA f32), made anew every frame while its trim animates, then
cached on the CPU and uploaded to the GPU. With 12 frames exported in parallel a
16 GB Mac ran out of memory and froze.

Now the miter limit applies only to miter-joined paths with a join (two or more
segments, or closed); square caps reach √2 half widths, other strokes one; Taper
and Wave keep the widest padding. Rendered pixels are unchanged.

A full-res frame of the affected ad: 1.7 GB → 0.7 GB peak.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 17:20:02 +03:00
arnav-hiwarkar 68d928aff3 fix(render): preserve preceding effects in GPU Echo (#1120) 2026-10-14 13:42:59 +05:30
DWAA1660andClaude Opus 5.5 e0bb54e4c6 render: hash the comp scene of selected layers that read it into the owner's cache key (#1252)
A layer selected by another layer's effect (Displacement Map, Blend...) had
its structure, values, matrix and time hashed into the owner's key, but not
the comp camera/lights its own scene-reading effects (Caustics, CC Particle
World...) see. The owner's key included the scene only when the owner itself
ran such an effect, and a cached owner never runs the selected layer's
effects, so moving the camera or a light reused stale owner pixels.

Dependencies::layer now hashes comp_scene for every selected (or nested)
layer that reads it, with the same policy as owner keys.

Fixes #1252

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N9kwMcw2pYQ5fSjKa3ZPnh
2026-10-13 18:05:48 -06:00
ThemolxandClaude Opus 5.5 f62af4ca73 Guide layers: hidden in nested comps, and in the Timeline context menu, as in After Effects
Guide layers render only in their own comp's viewer: a nested renderer (precomp, collapsed
precomp in 2D, Classic 3D and Advanced 3D, comps read by effects, aux passes, the GPU walk's
resident precomps) now runs with guides off (Renderer::nested_opts), so a precomp's guide
layers no longer show in the parent comp's viewer or in a "Current Settings" render.

The Timeline layer and Composition viewer right-click menus (shared layer_menu) gain a
Guide Layer item (a plain toggle, no check mark) acting on the selection, and guide layers show a guide mark
before their name in the Timeline.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 20:44:40 +02:00
ThemolxandClaude Opus 5.5 03b7a958e5 Solo: exclude other layers even when the soloed layer is outside its time range
In After Effects solo is not time-dependent: while any AV layer is soloed,
non-soloed layers are excluded at every time. The renderer, nested/collapsed
3D paths, engine viewer helpers and viewer hit tests only counted solo layers
active at the current time, so outside the soloed layer's in-out range the
whole comp reappeared. Drop the time condition (audio already ignored it).

Update the #66 viewer regression test to the AE behaviour and add a render
test for it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 20:30:26 +02:00
Ian-ChegeandClaude Opus 5.5 5270eab095 Masks: Mask Expansion past a curve's radius grows a solid mask instead of a ring
Expansion was a fill plus a stroke 2·|expansion| wide, blended per pixel. Once the
expansion passed the shape's curvature radius the stroke's inner edge inverted: a
20 px circle expanded by 60 left a ring with the layer showing through the middle,
+600 cut only the original dot, and negative values left islands. The outline is
now offset with Offset Paths' geometry (round joins) and filled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 19:15:30 +03:00
Vikram Bhaskaran 48738093b5 Shapes: Merge Paths keeps paint that belongs to a group above it (#1174)
A Merge Paths item appended to a shape layer's Contents cleared every draw
collected so far, including fills and strokes inside groups above it, so
the layer's shapes vanished from the render. AE's rule is per group: only
paint items in the merge's own group above it are dropped. Draws now
record which contents level created them; the merge drops only its own
group's paint, and the group-bubbled draws keep rendering.

Adds a regression test (Merge Shapes and Add modes) that renders nothing
without the fix.
2026-10-14 00:02:12 +11:00
Brandon Thomas 9aabb5da4f Merge pull request #688 from MatejKozlovsky/gpu-resident-effects 2026-10-13 04:33:22 -04:00
Brandon Thomas 4574fb62bc Merge pull request #792 from vangel76/gap-object-matte
# Conflicts:
#	crates/ui-egui/src/i18n/ui.rs
#	docs/gaps.md
#	docs/target-app-parity.md
2026-10-13 04:30:49 -04:00
Brandon Thomas 5281171282 Merge pull request #1204 from marcoarnulfo/fix/adjustment-track-matte 2026-10-13 04:29:49 -04:00
Brandon Thomas 90621e2b04 Merge pull request #1111 from eliasx45/upstream/effect-fixes 2026-10-13 04:29:09 -04:00
Brandon Thomas 5249ff8bad Merge pull request #1090 from vangel76/fix-1081-orient-along-path-flip 2026-10-13 04:29:05 -04:00
Marco Arnulfo 3095217ce8 Track matte on an adjustment layer limits where its effects show (fixes #1201) 2026-10-13 08:42:14 +02:00
Kristian MyramandClaude Haiku 5.5 63e5068f7c #1169: blend the two samples around each time when a layer is stretched
Stretched layers copied the nearest source sample for each output sample, which adds error: at
48 kHz the worst error on a 440 Hz tone was 0.025, and 0.15 at 8 kHz. They now blend the two
source samples either side. Layers at 100% and 50% speed keep their exact samples.

The render tests cover a plain precomp, which mixes the same audio as its layers, and the stretch
error against the exact tone.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-13 02:36:16 +02:00
vangel76andClaude Sonnet 5.5 3840d227ff #1081: Orient Along Path keeps the last heading at and after the end of the path
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 20:44:44 +02:00
Elias c3fe609ee4 Effects: Time effects see the effects applied before them
Echo, Posterize Time and the other Time effects read the layer at other times with none of
its effects. After Effects renders them with the effects before them: SceneYard "Task
Preparation UI" applies Echo after CC Particle Systems II on black solids, and AE shows the
echoed fireworks over a white page where we echoed the black solids and blacked it out
(Posterize Time after Turbulent Displace, the usual stop-motion setup, depends on the same).
The host already bounds the count to the effects before the one rendering.

Mean abs error vs AE: Task Preparation UI 0.1855 -> 0.0071, Lightbulb Idea 0.0126 -> 0.0102;
the 15 other corpus projects with a Time effect after another effect are pixel-identical.

(cherry picked from commit 46870452db2656c72406f63245e8b1609ceb04d4)

(cherry picked from commit 334d102582e5a64db32e2f3e55836d55ac96bdaa)
(cherry picked from commit 734da3e35dc57c01b73823458bdd87611ac1bf99)

(cherry picked from commit 87a733e076)
2026-10-12 19:18:53 +01:00
vangel76andClaude Sonnet 5.5 4acea86d4f Merge upstream/main into gap-object-matte
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 19:03:42 +02:00
Matej Kozlovský f6497177b4 Merge main into gpu-resident-effects 2026-10-12 12:41:40 +02:00
Brandon Thomas cb59a959f4 Merge pull request #983 from MarekSpodBiedry/issue-974
Scale the timeline waveform by the layer's Audio Levels (#974)
2026-10-12 05:21:55 -04:00
Brandon ThomasandClaude Opus 5.5 61aaf83612 Fix tests and two behaviours after the community batch
- Renderer: no cover step for adjustment layers (#686); their buffer is the comp below.
  Restores a single CPU step in split adjustment stacks.
- Effect Controls rename (#953): focus the name field the frame it exists. Focusing an id
  not yet drawn left AccessKit with a focus outside its tree (a panic in the consumer).
  The tests double-click at 60 fps, within egui's double-click time.
- i18n: Russian, French and German entries for Copy Frame to Clipboard and the extrusion
  Front/Bevel/Side/Back Color submenus added by today's other PRs.
- Tests: "fr" is now a valid language; the marker dialog's comment is focused on open
  (#922), so Enter-is-OK is tested with the focus elsewhere; the toolbar gradient tests
  give the selected layer its paint kind, since the toolbar mirrors it (#732).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 05:08:58 -04:00
Brandon ThomasandClaude Opus 5.5 6baff9f5fe Integration fixes for the community batch
- Footage sources: the cancellable wrapper (#784) forwards frame_with (#752 float curves)
  and problem (#887); problem's default lives on the trait.
- Media: a called-off decode (#784) is not a footage problem (#887).
- Effect Controls rename (#953): Escape cancels (egui drops focus on Escape the same
  frame), the Rename item is translated; regression test.
- i18n (#873): drop the /out-i18n/ ignore rule and the note about an uncommitted script.
- Tests: text range selector caps (#926) re-borrow the layer; the RAM preview test (#793)
  sets the comp's own Resolution (#462).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 04:27:59 -04:00
Brandon Thomas 6b69881826 Merge pull request #686 from vbasky/fix/659-text-effect-bounds
Effects: text and shape layers run their stack over the whole layer region (#659, #658)
2026-10-12 04:21:15 -04:00
Brandon Thomas fa8a1376f9 Merge pull request #926 from MarekSpodBiedry/issue-908
Cap text animator range selector Start, End and Offset (#908)
2026-10-12 04:20:59 -04:00
Brandon Thomas a1c90b80f2 Merge pull request #906 from itrycodinganditsbad/fix-751
Shape layers: always rasterise at the on-screen scale (#751)
2026-10-12 04:20:50 -04:00
Brandon Thomas 2a7170de87 Merge pull request #899 from vangel76/fix-670-per-pane-views
#670: each pane of a 2- or 4-view layout chooses its own view
2026-10-12 04:20:48 -04:00
Brandon Thomas ab12890a9e Merge pull request #887 from vangel76/fix-886-unsupported-video-notice
#886: say why footage the decoders can't read shows no picture

# Conflicts:
#	crates/media/src/pool.rs
#	crates/media/tests/footage.rs
#	crates/render/src/lib.rs
2026-10-12 04:20:43 -04:00
Brandon Thomas 34ad8c7e9c Merge pull request #869 from vangel76/fix-864-track-matte-mode
Track Matte: picking a mode without a matte layer takes the layer above (#864)
2026-10-12 04:20:38 -04:00
Matej Kozlovský bc6a145203 GPU: a layer's effect stack runs resident on the GPU and is placed directly, instead of a readback and re-upload around every GPU effect run (#687) 2026-10-12 09:47:28 +02:00
Matej Kozlovský eec81bbe0e Render: an adjustment layer's footprint key ignores its effects, so a time-dependent effect (Noise) no longer re-keys it and the GPU re-uploads it every frame (#687) 2026-10-12 09:47:28 +02:00
Brandon Thomas 565fd4118d Merge pull request #784 from vangel76/fix-329-seek-latency
#329: scrubbing a long movie: superseded viewer frames call off their decodes

# Conflicts:
#	crates/media/tests/footage.rs
2026-10-12 03:22:50 -04:00
Brandon Thomas 261a5b125b Merge pull request #754 from vangel76/gap-surface-colors
#315: Front / Bevel / Side / Back Color for extruded shapes and text

# Conflicts:
#	docs/gaps.md
2026-10-12 03:20:01 -04:00
MarekSpodBiedry 25be439a0b Scale the timeline waveform by the layer's Audio Levels (#974) 2026-10-12 08:39:44 +02:00
MarekSpodBiedry 8927ae5781 Cap text animator range selector Start, End and Offset (#908) 2026-10-11 23:39:23 +02:00
Fabio LussiandClaude Opus 5.5 183d052c6a Shape layers: always rasterise at the on-screen scale
Shape layers are always continuously rasterised, as in After Effects and
as text layers already are here: the contents are drawn at the layer's
effective scale (own transform and parents) whether or not the
Continuously Rasterize switch is on, so scaled-up shapes stay sharp.

Fixes #751

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 20:38:17 +02:00