perf(scene): extend viewport scissor to hatch / image / wipeout passes (Phase 1.4)

Wire pass already uses `WireModel.vp_scissor` to clip viewport-projected
geometry to its paper-space viewport rect; hatch / image / wipeout
passes drew across the whole canvas. When a future paper-space path
projects fills/images into a viewport, they would bleed past the
viewport frame.

Add `vp_scissor: Option<[f32; 4]>` to HatchModel and ImageModel
(mirroring WireModel), forward it through HatchGpu / ImageGpu, and add
per-pass `compute_*_scissors` / `set_scissor_rect` machinery. Factored
the wire-side scissor-projection math into a shared `project_scissor`
helper. Field defaults to None at every constructor site — no producer
sets it yet, so this is plumbing for the paper-viewport fill projection
that Phase 1.4 unblocks without changing current visual output.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-05-15 23:13:16 +03:00
commit fbbac423d4
8 changed files with 145 additions and 24 deletions

View file

@ -102,6 +102,10 @@ pub struct FamilyBatchData {
pub struct HatchGpu {
pub vertex_buffer: wgpu::Buffer,
pub bind_group: wgpu::BindGroup,
/// Mirrors `HatchModel.vp_scissor`. Forwarded to the pipeline so each
/// frame's `compute_hatch_scissors` can translate the world rect into
/// a pixel scissor.
pub vp_scissor: Option<[f32; 4]>,
_uniform_buf: wgpu::Buffer,
_boundary_buf: wgpu::Buffer,
_family_buf: wgpu::Buffer,
@ -268,6 +272,7 @@ impl HatchGpu {
Self {
vertex_buffer,
bind_group,
vp_scissor: model.vp_scissor,
_uniform_buf,
_boundary_buf,
_family_buf,