2D-Bögen analytisch: exakter Kreis-Shader statt Segment-Tessellierung

Bögen im nativen 2D-wgpu-Renderer werden nicht mehr zoomabhängig in Segmente
zerlegt, sondern per SDF-Fragment-Shader (ARC_WGSL) mathematisch exakt rund
gerendert — bei jeder Zoomstufe ein echter Kreis, kein Vieleck, ohne
Neu-Tessellierung.

- compile_scene sammelt je Bogen EINE analytische Instanz (ArcInstanceData,
  Bildschirm-Raum-Parameter + Dash in Modell-Metern), zoom-invariant.
- Eigene Arc-Pipeline (ein Frame-Uniform, Quad je Instanz aus vertex_index):
  radiale Kante, Butt-Cap-Winkelclamp (beide Sweep-Vorzeichen) und Dash
  (Bogenlänge modulo Muster) analytisch antialiased; Strichbreite mit derselben
  mm->px-Formel wie die Linien.
- tessellate_arc + Zoom-Retessellierungs-Cache (last_scene/arc_px_per_m/
  maybe_retessellate) entfernt; upload_scene ohne px_per_m.
- Tests auf die neue Semantik umgeschrieben (Winkel-Parität, Bounding-Box,
  Dash-Mapping), ARC_WGSL per naga validiert.
This commit is contained in:
2026-07-02 22:07:18 +02:00
parent 7b9f72e79f
commit 6eead6d493
8 changed files with 588 additions and 172 deletions
+2 -4
View File
@@ -14,7 +14,7 @@ use std::sync::Arc;
use render2d::gpu::Renderer;
use render2d::types::ViewBox;
use render2d::{demo_scene, initial_view_box, meet_scale, PX_PER_M};
use render2d::{demo_scene, initial_view_box};
use winit::application::ApplicationHandler;
use winit::event::{ElementState, MouseButton, MouseScrollDelta, WindowEvent};
@@ -74,9 +74,7 @@ impl GpuState {
surface.configure(&device, &config);
let mut renderer = Renderer::new(&device, format);
let view_box = initial_view_box();
let px_per_m = PX_PER_M * meet_scale(view_box, config.width as f32, config.height as f32);
renderer.upload_scene(&device, &demo_scene(), px_per_m);
renderer.upload_scene(&device, &demo_scene());
Self {
surface,