feat(render): Flat/Gouraud shading, WithEdges overlay, paper-viewport mode

Faz 3 — FlatShaded vs GouraudShaded
- Uniforms.flat_shade (f32, 0/1) + mesh shader fragment derivative
  bazlı per-triangle face normal hesabı; GouraudShaded ise interpolate
  edilen vertex normalini kullanıyor.

Faz 4 — *WithEdges varyantları
- Pipeline::render.show_3d_edges parametresi:
  - FlatShaded / GouraudShaded → 3DFACE edge pass'i atlanıyor
  - *WithEdges varyantları → shaded fill'in üstüne mesh_wireframe
    pipeline ile triangle-edge overlay (LessEqual depth test ile)
  - face3d_edges pass'i show_3d_edges ile gate'lendi

Faz 5 — Paper-space viewport entity round-trip
- build_viewport_primitive / build_active_viewport_primitive artık
  render_mode parametresi almıyor; viewport entity'sinin kendi
  render_mode alanından okuyor. PaperViewportPane'dan render_mode
  field'i kaldırıldı. Model layout'taki tab.render_mode hala
  pick_list ile yönetiliyor.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-05-27 05:57:19 +03:00
commit 132efe6574
6 changed files with 141 additions and 56 deletions

View file

@ -14,6 +14,14 @@ pub struct Uniforms {
/// LWDISPLAY toggle (1.0 = show lineweights, 0.0 = force 1 px).
/// Read by the wire shader so the toggle does not require a retessellate.
pub lwdisplay_enable: f32,
/// 1.0 → mesh fragment shader replaces the interpolated vertex
/// normal with `normalize(cross(dpdx(pos), dpdy(pos)))` so each
/// triangle gets a uniform shade (FlatShaded mode); 0.0 → keeps the
/// per-vertex normal interpolation (GouraudShaded-style).
pub flat_shade: f32,
/// Pads the struct to 112 B (next multiple of 16) so wgpu's uniform
/// alignment rules are satisfied.
pub _pad: [f32; 3],
}
impl Uniforms {
@ -30,6 +38,8 @@ impl Uniforms {
viewport_size: [bounds.width, bounds.height],
world_per_pixel,
lwdisplay_enable: if lwdisplay_enable { 1.0 } else { 0.0 },
flat_shade: 0.0,
_pad: [0.0; 3],
}
}
}