perf(scene): hatch LOD — solid-fill substitute + sub-pixel skip (Phase 3.3)
Hatch fills drew the full per-family pattern loop every frame regardless
of zoom. Two LOD tiers, neither of which existed:
* **Shader-side solid substitute.** When the densest line family's
spacing × scale projects to less than 2 px, individual lines blur
into a solid color and the per-fragment family loop is wasted ALU
(and produces moiré). Pass `world_per_pixel` through Uniforms; the
hatch fragment shader now returns `h.color` directly in that case.
* **CPU-side sub-pixel skip.** When the entire hatch AABB projects
to less than 2 px, drop the draw call. Adds `world_aabb` to
HatchGpu plus a per-frame `compute_hatch_lod` pass (mirrors the
existing scissor pass) and `hatch_skip_flags`. The render pass
skips flagged hatches.
Factored a shared `aabb_below_pixel` helper for future LOD callers.
The Uniforms layout is unchanged in size (96 B) — the trailing
`_pad: vec2<f32>` becomes `world_per_pixel: f32, _pad: f32`, so wgsl
modules that don't read the new field keep working with their old
`_pad: vec2<f32>` declarations.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
fbbac423d4
commit
e7675be0bc
5 changed files with 102 additions and 7 deletions
|
|
@ -7,16 +7,27 @@ pub struct Uniforms {
|
|||
pub view_proj: glam::Mat4,
|
||||
pub camera_pos: glam::Vec4,
|
||||
pub viewport_size: [f32; 2],
|
||||
pub _pad: [f32; 2],
|
||||
/// World units per screen pixel at the current zoom. Used by the
|
||||
/// hatch shader to substitute solid fill when pattern line spacing
|
||||
/// falls below ~2 px (Phase 3.3 LOD).
|
||||
pub world_per_pixel: f32,
|
||||
pub _pad: f32,
|
||||
}
|
||||
|
||||
impl Uniforms {
|
||||
pub fn new(camera: &Camera, bounds: Rectangle) -> Self {
|
||||
let half_h = camera.ortho_size();
|
||||
let world_per_pixel = if bounds.height > 0.0 {
|
||||
(2.0 * half_h) / bounds.height
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
Self {
|
||||
view_proj: camera.view_proj(bounds),
|
||||
camera_pos: camera.position_vec4(),
|
||||
viewport_size: [bounds.width, bounds.height],
|
||||
_pad: [0.0; 2],
|
||||
world_per_pixel,
|
||||
_pad: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue