refactor: remove the legacy full view_proj (CPU cull now relative-to-eye)
The GPU draws exclusively via the rotation-only `view_rot` + eye double- single; the full view-projection survived only to project AABBs in the CPU frustum-cull / scissor / LOD passes. Migrate those to the same relative-to-eye math (project `point - eye` through `view_rot`) — pixel- equivalent but precise at UTM scale — then drop the dead uniform: - pipeline cull/scissor/LOD helpers take (view_rot, eye) instead of the full view_proj; render.rs reconstructs eye from the uniform's eye_high/eye_low and passes the cropped view_rot. - Remove the `view_proj` field from the shared Uniforms struct and all six shader structs that only declared it for layout (none read it), and delete Camera::view_proj(). The struct shrinks by one mat4 on both sides, keeping the Rust / WGSL layouts in lock-step. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
5a8ec35f4f
commit
04c93df2c4
10 changed files with 57 additions and 80 deletions
|
|
@ -1041,11 +1041,11 @@ impl Pipeline {
|
||||||
|
|
||||||
/// Recompute pixel scissor rects for viewport-clipped wires from the current view_proj.
|
/// Recompute pixel scissor rects for viewport-clipped wires from the current view_proj.
|
||||||
/// Called every frame from prepare() because scissor pixels shift with pan/zoom.
|
/// Called every frame from prepare() because scissor pixels shift with pan/zoom.
|
||||||
pub fn compute_wire_scissors(&mut self, view_proj: glam::Mat4, clip_w: u32, clip_h: u32) {
|
pub fn compute_wire_scissors(&mut self, view_rot: glam::Mat4, eye: glam::DVec3, clip_w: u32, clip_h: u32) {
|
||||||
self.wire_pixel_scissors = self
|
self.wire_pixel_scissors = self
|
||||||
.gpu_wires
|
.gpu_wires
|
||||||
.iter()
|
.iter()
|
||||||
.map(|w| project_scissor(w.vp_scissor, view_proj, clip_w, clip_h))
|
.map(|w| project_scissor(w.vp_scissor, view_rot, eye, clip_w, clip_h))
|
||||||
.collect();
|
.collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1058,7 +1058,8 @@ impl Pipeline {
|
||||||
pub fn compute_hatch_lod(
|
pub fn compute_hatch_lod(
|
||||||
&mut self,
|
&mut self,
|
||||||
queue: &wgpu::Queue,
|
queue: &wgpu::Queue,
|
||||||
view_proj: glam::Mat4,
|
view_rot: glam::Mat4,
|
||||||
|
eye: glam::DVec3,
|
||||||
clip_w: u32,
|
clip_w: u32,
|
||||||
clip_h: u32,
|
clip_h: u32,
|
||||||
) {
|
) {
|
||||||
|
|
@ -1066,19 +1067,19 @@ impl Pipeline {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
for (i, aabb) in batch.instance_aabbs.iter().enumerate() {
|
for (i, aabb) in batch.instance_aabbs.iter().enumerate() {
|
||||||
let skip = aabb_below_pixel(*aabb, view_proj, clip_w, clip_h, 2.0)
|
let skip = aabb_below_pixel(*aabb, view_rot, eye, clip_w, clip_h, 2.0)
|
||||||
|| aabb_offscreen(*aabb, view_proj, clip_w, clip_h);
|
|| aabb_offscreen(*aabb, view_rot, eye, clip_w, clip_h);
|
||||||
batch.visibility[i] = if skip { 0 } else { 1 };
|
batch.visibility[i] = if skip { 0 } else { 1 };
|
||||||
}
|
}
|
||||||
batch.upload_visibility(queue);
|
batch.upload_visibility(queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recompute pixel scissor rects for viewport-clipped wipeouts.
|
/// Recompute pixel scissor rects for viewport-clipped wipeouts.
|
||||||
pub fn compute_wipeout_scissors(&mut self, view_proj: glam::Mat4, clip_w: u32, clip_h: u32) {
|
pub fn compute_wipeout_scissors(&mut self, view_rot: glam::Mat4, eye: glam::DVec3, clip_w: u32, clip_h: u32) {
|
||||||
self.wipeout_pixel_scissors = self
|
self.wipeout_pixel_scissors = self
|
||||||
.gpu_wipeouts
|
.gpu_wipeouts
|
||||||
.iter()
|
.iter()
|
||||||
.map(|h| project_scissor(h.vp_scissor, view_proj, clip_w, clip_h))
|
.map(|h| project_scissor(h.vp_scissor, view_rot, eye, clip_w, clip_h))
|
||||||
.collect();
|
.collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1086,20 +1087,20 @@ impl Pipeline {
|
||||||
/// `compute_hatch_lod`'s frustum branch. No sub-pixel skip:
|
/// `compute_hatch_lod`'s frustum branch. No sub-pixel skip:
|
||||||
/// wipeouts mask, so dropping a sub-pixel one wouldn't be wrong
|
/// wipeouts mask, so dropping a sub-pixel one wouldn't be wrong
|
||||||
/// but also wouldn't pay off — they're usually few.
|
/// but also wouldn't pay off — they're usually few.
|
||||||
pub fn compute_wipeout_lod(&mut self, view_proj: glam::Mat4, clip_w: u32, clip_h: u32) {
|
pub fn compute_wipeout_lod(&mut self, view_rot: glam::Mat4, eye: glam::DVec3, clip_w: u32, clip_h: u32) {
|
||||||
self.wipeout_skip_flags = self
|
self.wipeout_skip_flags = self
|
||||||
.gpu_wipeouts
|
.gpu_wipeouts
|
||||||
.iter()
|
.iter()
|
||||||
.map(|h| aabb_offscreen(h.world_aabb, view_proj, clip_w, clip_h))
|
.map(|h| aabb_offscreen(h.world_aabb, view_rot, eye, clip_w, clip_h))
|
||||||
.collect();
|
.collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recompute pixel scissor rects for viewport-clipped raster images.
|
/// Recompute pixel scissor rects for viewport-clipped raster images.
|
||||||
pub fn compute_image_scissors(&mut self, view_proj: glam::Mat4, clip_w: u32, clip_h: u32) {
|
pub fn compute_image_scissors(&mut self, view_rot: glam::Mat4, eye: glam::DVec3, clip_w: u32, clip_h: u32) {
|
||||||
self.image_pixel_scissors = self
|
self.image_pixel_scissors = self
|
||||||
.gpu_images
|
.gpu_images
|
||||||
.iter()
|
.iter()
|
||||||
.map(|i| project_scissor(i.vp_scissor, view_proj, clip_w, clip_h))
|
.map(|i| project_scissor(i.vp_scissor, view_rot, eye, clip_w, clip_h))
|
||||||
.collect();
|
.collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1175,11 +1176,11 @@ impl Pipeline {
|
||||||
/// projected pixel diagonal of each mesh's `world_aabb` (Phase 3.4
|
/// projected pixel diagonal of each mesh's `world_aabb` (Phase 3.4
|
||||||
/// ladder: >200 px → 0, 50–200 → 1, <50 → 2). Falls back to the
|
/// ladder: >200 px → 0, 50–200 → 1, <50 → 2). Falls back to the
|
||||||
/// nearest available lower slot when a level wasn't generated.
|
/// nearest available lower slot when a level wasn't generated.
|
||||||
pub fn compute_mesh_lod(&mut self, view_proj: glam::Mat4, clip_w: u32, clip_h: u32) {
|
pub fn compute_mesh_lod(&mut self, view_rot: glam::Mat4, eye: glam::DVec3, clip_w: u32, clip_h: u32) {
|
||||||
self.mesh_lod_levels = self
|
self.mesh_lod_levels = self
|
||||||
.gpu_meshes
|
.gpu_meshes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|m| pick_mesh_lod(m, view_proj, clip_w, clip_h))
|
.map(|m| pick_mesh_lod(m, view_rot, eye, clip_w, clip_h))
|
||||||
.collect();
|
.collect();
|
||||||
// Phase 2.2 — frustum-visibility flag per mesh. Cheap: same
|
// Phase 2.2 — frustum-visibility flag per mesh. Cheap: same
|
||||||
// 4-corner projection used for LOD selection, just answering a
|
// 4-corner projection used for LOD selection, just answering a
|
||||||
|
|
@ -1187,7 +1188,7 @@ impl Pipeline {
|
||||||
self.mesh_visible = self
|
self.mesh_visible = self
|
||||||
.gpu_meshes
|
.gpu_meshes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|m| !aabb_offscreen(m.world_aabb, view_proj, clip_w, clip_h))
|
.map(|m| !aabb_offscreen(m.world_aabb, view_rot, eye, clip_w, clip_h))
|
||||||
.collect();
|
.collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1847,11 +1848,12 @@ impl Pipeline {
|
||||||
/// to the next available coarser/finer level so the mesh always renders.
|
/// to the next available coarser/finer level so the mesh always renders.
|
||||||
fn pick_mesh_lod(
|
fn pick_mesh_lod(
|
||||||
mesh: &MeshLodGpu,
|
mesh: &MeshLodGpu,
|
||||||
view_proj: glam::Mat4,
|
view_rot: glam::Mat4,
|
||||||
|
eye: glam::DVec3,
|
||||||
clip_w: u32,
|
clip_w: u32,
|
||||||
clip_h: u32,
|
clip_h: u32,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
let diag_px = aabb_diagonal_pixels(mesh.world_aabb, view_proj, clip_w, clip_h);
|
let diag_px = aabb_diagonal_pixels(mesh.world_aabb, view_rot, eye, clip_w, clip_h);
|
||||||
let target = if diag_px > 200.0 {
|
let target = if diag_px > 200.0 {
|
||||||
0
|
0
|
||||||
} else if diag_px > 50.0 {
|
} else if diag_px > 50.0 {
|
||||||
|
|
@ -1870,7 +1872,8 @@ fn pick_mesh_lod(
|
||||||
|
|
||||||
fn aabb_diagonal_pixels(
|
fn aabb_diagonal_pixels(
|
||||||
aabb: [f32; 4],
|
aabb: [f32; 4],
|
||||||
view_proj: glam::Mat4,
|
view_rot: glam::Mat4,
|
||||||
|
eye: glam::DVec3,
|
||||||
clip_w: u32,
|
clip_w: u32,
|
||||||
clip_h: u32,
|
clip_h: u32,
|
||||||
) -> f32 {
|
) -> f32 {
|
||||||
|
|
@ -1881,10 +1884,10 @@ fn aabb_diagonal_pixels(
|
||||||
let w = clip_w as f32;
|
let w = clip_w as f32;
|
||||||
let h = clip_h as f32;
|
let h = clip_h as f32;
|
||||||
let corners = [
|
let corners = [
|
||||||
view_proj.project_point3(glam::Vec3::new(x0, y0, 0.0)),
|
view_rot.project_point3((glam::DVec3::new(x0 as f64, y0 as f64, 0.0) - eye).as_vec3()),
|
||||||
view_proj.project_point3(glam::Vec3::new(x1, y0, 0.0)),
|
view_rot.project_point3((glam::DVec3::new(x1 as f64, y0 as f64, 0.0) - eye).as_vec3()),
|
||||||
view_proj.project_point3(glam::Vec3::new(x0, y1, 0.0)),
|
view_rot.project_point3((glam::DVec3::new(x0 as f64, y1 as f64, 0.0) - eye).as_vec3()),
|
||||||
view_proj.project_point3(glam::Vec3::new(x1, y1, 0.0)),
|
view_rot.project_point3((glam::DVec3::new(x1 as f64, y1 as f64, 0.0) - eye).as_vec3()),
|
||||||
];
|
];
|
||||||
let mut min_px = f32::INFINITY;
|
let mut min_px = f32::INFINITY;
|
||||||
let mut max_px = f32::NEG_INFINITY;
|
let mut max_px = f32::NEG_INFINITY;
|
||||||
|
|
@ -1916,7 +1919,8 @@ fn aabb_diagonal_pixels(
|
||||||
/// extents` for this reason; meshes already store an absolute rect.
|
/// extents` for this reason; meshes already store an absolute rect.
|
||||||
fn aabb_offscreen(
|
fn aabb_offscreen(
|
||||||
aabb: [f32; 4],
|
aabb: [f32; 4],
|
||||||
view_proj: glam::Mat4,
|
view_rot: glam::Mat4,
|
||||||
|
eye: glam::DVec3,
|
||||||
clip_w: u32,
|
clip_w: u32,
|
||||||
clip_h: u32,
|
clip_h: u32,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
|
@ -1927,10 +1931,10 @@ fn aabb_offscreen(
|
||||||
let w = clip_w as f32;
|
let w = clip_w as f32;
|
||||||
let h = clip_h as f32;
|
let h = clip_h as f32;
|
||||||
let corners = [
|
let corners = [
|
||||||
view_proj.project_point3(glam::Vec3::new(x0, y0, 0.0)),
|
view_rot.project_point3((glam::DVec3::new(x0 as f64, y0 as f64, 0.0) - eye).as_vec3()),
|
||||||
view_proj.project_point3(glam::Vec3::new(x1, y0, 0.0)),
|
view_rot.project_point3((glam::DVec3::new(x1 as f64, y0 as f64, 0.0) - eye).as_vec3()),
|
||||||
view_proj.project_point3(glam::Vec3::new(x0, y1, 0.0)),
|
view_rot.project_point3((glam::DVec3::new(x0 as f64, y1 as f64, 0.0) - eye).as_vec3()),
|
||||||
view_proj.project_point3(glam::Vec3::new(x1, y1, 0.0)),
|
view_rot.project_point3((glam::DVec3::new(x1 as f64, y1 as f64, 0.0) - eye).as_vec3()),
|
||||||
];
|
];
|
||||||
let mut min_px = f32::INFINITY;
|
let mut min_px = f32::INFINITY;
|
||||||
let mut max_px = f32::NEG_INFINITY;
|
let mut max_px = f32::NEG_INFINITY;
|
||||||
|
|
@ -1958,7 +1962,8 @@ fn aabb_offscreen(
|
||||||
/// draw calls that wouldn't contribute a visible pixel.
|
/// draw calls that wouldn't contribute a visible pixel.
|
||||||
fn aabb_below_pixel(
|
fn aabb_below_pixel(
|
||||||
aabb: [f32; 4],
|
aabb: [f32; 4],
|
||||||
view_proj: glam::Mat4,
|
view_rot: glam::Mat4,
|
||||||
|
eye: glam::DVec3,
|
||||||
clip_w: u32,
|
clip_w: u32,
|
||||||
clip_h: u32,
|
clip_h: u32,
|
||||||
threshold_px: f32,
|
threshold_px: f32,
|
||||||
|
|
@ -1970,10 +1975,10 @@ fn aabb_below_pixel(
|
||||||
let w = clip_w as f32;
|
let w = clip_w as f32;
|
||||||
let h = clip_h as f32;
|
let h = clip_h as f32;
|
||||||
let corners = [
|
let corners = [
|
||||||
view_proj.project_point3(glam::Vec3::new(x0, y0, 0.0)),
|
view_rot.project_point3((glam::DVec3::new(x0 as f64, y0 as f64, 0.0) - eye).as_vec3()),
|
||||||
view_proj.project_point3(glam::Vec3::new(x1, y0, 0.0)),
|
view_rot.project_point3((glam::DVec3::new(x1 as f64, y0 as f64, 0.0) - eye).as_vec3()),
|
||||||
view_proj.project_point3(glam::Vec3::new(x0, y1, 0.0)),
|
view_rot.project_point3((glam::DVec3::new(x0 as f64, y1 as f64, 0.0) - eye).as_vec3()),
|
||||||
view_proj.project_point3(glam::Vec3::new(x1, y1, 0.0)),
|
view_rot.project_point3((glam::DVec3::new(x1 as f64, y1 as f64, 0.0) - eye).as_vec3()),
|
||||||
];
|
];
|
||||||
let mut min_px = f32::INFINITY;
|
let mut min_px = f32::INFINITY;
|
||||||
let mut max_px = f32::NEG_INFINITY;
|
let mut max_px = f32::NEG_INFINITY;
|
||||||
|
|
@ -1996,7 +2001,8 @@ fn aabb_below_pixel(
|
||||||
/// the projection collapses (off-screen, behind camera).
|
/// the projection collapses (off-screen, behind camera).
|
||||||
fn project_scissor(
|
fn project_scissor(
|
||||||
rect: Option<[f32; 4]>,
|
rect: Option<[f32; 4]>,
|
||||||
view_proj: glam::Mat4,
|
view_rot: glam::Mat4,
|
||||||
|
eye: glam::DVec3,
|
||||||
clip_w: u32,
|
clip_w: u32,
|
||||||
clip_h: u32,
|
clip_h: u32,
|
||||||
) -> Option<[u32; 4]> {
|
) -> Option<[u32; 4]> {
|
||||||
|
|
@ -2004,10 +2010,10 @@ fn project_scissor(
|
||||||
let w = clip_w as f32;
|
let w = clip_w as f32;
|
||||||
let h = clip_h as f32;
|
let h = clip_h as f32;
|
||||||
let corners = [
|
let corners = [
|
||||||
view_proj.project_point3(glam::Vec3::new(x0, y0, 0.0)),
|
view_rot.project_point3((glam::DVec3::new(x0 as f64, y0 as f64, 0.0) - eye).as_vec3()),
|
||||||
view_proj.project_point3(glam::Vec3::new(x1, y0, 0.0)),
|
view_rot.project_point3((glam::DVec3::new(x1 as f64, y0 as f64, 0.0) - eye).as_vec3()),
|
||||||
view_proj.project_point3(glam::Vec3::new(x0, y1, 0.0)),
|
view_rot.project_point3((glam::DVec3::new(x0 as f64, y1 as f64, 0.0) - eye).as_vec3()),
|
||||||
view_proj.project_point3(glam::Vec3::new(x1, y1, 0.0)),
|
view_rot.project_point3((glam::DVec3::new(x1 as f64, y1 as f64, 0.0) - eye).as_vec3()),
|
||||||
];
|
];
|
||||||
let px: Vec<f32> = corners.iter().map(|c| (c.x + 1.0) * 0.5 * w).collect();
|
let px: Vec<f32> = corners.iter().map(|c| (c.x + 1.0) * 0.5 * w).collect();
|
||||||
let py: Vec<f32> = corners.iter().map(|c| (1.0 - c.y) * 0.5 * h).collect();
|
let py: Vec<f32> = corners.iter().map(|c| (1.0 - c.y) * 0.5 * h).collect();
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,6 @@ use iced::Rectangle;
|
||||||
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
|
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Uniforms {
|
pub struct Uniforms {
|
||||||
/// Full view-projection (with translation) — GPU rendering no longer uses
|
|
||||||
/// this; it remains for the CPU-side frustum-cull / scissor / LOD passes
|
|
||||||
/// that project offset-relative AABBs to screen. The GPU draws via the
|
|
||||||
/// relative-to-eye `view_rot` + `eye_high`/`eye_low` below.
|
|
||||||
pub view_proj: glam::Mat4,
|
|
||||||
pub viewport_size: [f32; 2],
|
pub viewport_size: [f32; 2],
|
||||||
/// World units per screen pixel at the current zoom. Used by the
|
/// World units per screen pixel at the current zoom. Used by the
|
||||||
/// hatch shader to substitute solid fill when pattern line spacing
|
/// hatch shader to substitute solid fill when pattern line spacing
|
||||||
|
|
@ -54,7 +49,6 @@ impl Uniforms {
|
||||||
};
|
};
|
||||||
let (eye_high, eye_low) = camera.eye_high_low();
|
let (eye_high, eye_low) = camera.eye_high_low();
|
||||||
Self {
|
Self {
|
||||||
view_proj: camera.view_proj(bounds),
|
|
||||||
viewport_size: [bounds.width, bounds.height],
|
viewport_size: [bounds.width, bounds.height],
|
||||||
world_per_pixel,
|
world_per_pixel,
|
||||||
lwdisplay_enable: if lwdisplay_enable { 1.0 } else { 0.0 },
|
lwdisplay_enable: if lwdisplay_enable { 1.0 } else { 0.0 },
|
||||||
|
|
|
||||||
|
|
@ -91,28 +91,6 @@ impl Camera {
|
||||||
|
|
||||||
// ── Projection matrices ────────────────────────────────────────────────
|
// ── Projection matrices ────────────────────────────────────────────────
|
||||||
|
|
||||||
pub fn view_proj(&self, bounds: Rectangle) -> Mat4 {
|
|
||||||
let aspect = bounds.width / bounds.height;
|
|
||||||
|
|
||||||
// Up vector: use the rotation to find which world direction is "up"
|
|
||||||
// in the current camera frame.
|
|
||||||
let up_dir = self.rotation * Vec3::Y;
|
|
||||||
|
|
||||||
let view = Mat4::look_at_rh(self.eye(), self.target.as_vec3(), up_dir);
|
|
||||||
let proj = match self.projection {
|
|
||||||
Projection::Perspective => {
|
|
||||||
Mat4::perspective_rh(self.fov_y, aspect, self.distance * 0.001, self.distance * 1000.0)
|
|
||||||
}
|
|
||||||
Projection::Orthographic => {
|
|
||||||
let h = self.ortho_size();
|
|
||||||
let w = h * aspect;
|
|
||||||
let (near, far) = self.ortho_depth_range();
|
|
||||||
Mat4::orthographic_rh(-w, w, -h, h, near, far)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
OPENGL_TO_WGPU * proj * view
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Orthographic near/far that CENTRE the target plane at ndc-z ≈ 0.5.
|
/// Orthographic near/far that CENTRE the target plane at ndc-z ≈ 0.5.
|
||||||
///
|
///
|
||||||
/// The draw-order depth bias shifts clip-z by ±`DRAW_ORDER_BIAS` (0.001).
|
/// The draw-order depth bias shifts clip-z by ±`DRAW_ORDER_BIAS` (0.001).
|
||||||
|
|
|
||||||
|
|
@ -305,13 +305,20 @@ impl shader::Primitive for Primitive {
|
||||||
// refreshed every frame it's present, so a drag never re-uploads
|
// refreshed every frame it's present, so a drag never re-uploads
|
||||||
// the resident base wire buffer.
|
// the resident base wire buffer.
|
||||||
inner.upload_preview_wires(device, &vp.preview_wires[..], &vp.draw_depths);
|
inner.upload_preview_wires(device, &vp.preview_wires[..], &vp.draw_depths);
|
||||||
let vproj = vp.uniforms.view_proj;
|
// Cull / scissor / LOD project AABBs relative-to-eye (matching the
|
||||||
inner.compute_wire_scissors(vproj, clip_size.width, clip_size.height);
|
// GPU's RTE path) so the math stays precise at UTM-scale coords.
|
||||||
inner.compute_wipeout_scissors(vproj, clip_size.width, clip_size.height);
|
let view_rot = vp.uniforms.view_rot;
|
||||||
inner.compute_image_scissors(vproj, clip_size.width, clip_size.height);
|
let eye = glam::DVec3::new(
|
||||||
inner.compute_hatch_lod(queue, vproj, clip_size.width, clip_size.height);
|
vp.uniforms.eye_high[0] as f64 + vp.uniforms.eye_low[0] as f64,
|
||||||
inner.compute_wipeout_lod(vproj, clip_size.width, clip_size.height);
|
vp.uniforms.eye_high[1] as f64 + vp.uniforms.eye_low[1] as f64,
|
||||||
inner.compute_mesh_lod(vproj, clip_size.width, clip_size.height);
|
vp.uniforms.eye_high[2] as f64 + vp.uniforms.eye_low[2] as f64,
|
||||||
|
);
|
||||||
|
inner.compute_wire_scissors(view_rot, eye, clip_size.width, clip_size.height);
|
||||||
|
inner.compute_wipeout_scissors(view_rot, eye, clip_size.width, clip_size.height);
|
||||||
|
inner.compute_image_scissors(view_rot, eye, clip_size.width, clip_size.height);
|
||||||
|
inner.compute_hatch_lod(queue, view_rot, eye, clip_size.width, clip_size.height);
|
||||||
|
inner.compute_wipeout_lod(view_rot, eye, clip_size.width, clip_size.height);
|
||||||
|
inner.compute_mesh_lod(view_rot, eye, clip_size.width, clip_size.height);
|
||||||
if vp.show_viewcube {
|
if vp.show_viewcube {
|
||||||
inner.viewcube.upload(
|
inner.viewcube.upload(
|
||||||
queue,
|
queue,
|
||||||
|
|
@ -743,9 +750,7 @@ impl Scene {
|
||||||
};
|
};
|
||||||
let mut uniforms =
|
let mut uniforms =
|
||||||
Uniforms::new(&inst.camera, full_bounds, self.document.header.lineweight_display);
|
Uniforms::new(&inst.camera, full_bounds, self.document.header.lineweight_display);
|
||||||
uniforms.view_proj = crop_view_proj(uniforms.view_proj, uo, vo, us, vs);
|
// Crop the rotation-only RTE view-projection to the visible sub-rect.
|
||||||
// The RTE matrix is a view-projection too, so the same clip-space crop
|
|
||||||
// applies — keep it in lock-step with view_proj for tiled / sub-rect panes.
|
|
||||||
uniforms.view_rot = crop_view_proj(uniforms.view_rot, uo, vo, us, vs);
|
uniforms.view_rot = crop_view_proj(uniforms.view_rot, uo, vo, us, vs);
|
||||||
uniforms.viewport_size = [visible_w, visible_h];
|
uniforms.viewport_size = [visible_w, visible_h];
|
||||||
uniforms.flat_shade = if flags.flat_shade { 1.0 } else { 0.0 };
|
uniforms.flat_shade = if flags.flat_shade { 1.0 } else { 0.0 };
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
// color [f32; 4] offset 12 16 B
|
// color [f32; 4] offset 12 16 B
|
||||||
|
|
||||||
struct Uniforms {
|
struct Uniforms {
|
||||||
view_proj: mat4x4<f32>,
|
|
||||||
viewport_size: vec2<f32>,
|
viewport_size: vec2<f32>,
|
||||||
world_per_pixel: f32,
|
world_per_pixel: f32,
|
||||||
lwdisplay_enable: f32,
|
lwdisplay_enable: f32,
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@
|
||||||
// ── Group 0: frame uniforms (shared) ──────────────────────────────────────
|
// ── Group 0: frame uniforms (shared) ──────────────────────────────────────
|
||||||
|
|
||||||
struct Uniforms {
|
struct Uniforms {
|
||||||
view_proj: mat4x4<f32>,
|
|
||||||
viewport_size: vec2<f32>,
|
viewport_size: vec2<f32>,
|
||||||
world_per_pixel: f32,
|
world_per_pixel: f32,
|
||||||
lwdisplay_enable: f32,
|
lwdisplay_enable: f32,
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@
|
||||||
// ── Group 0: shared frame uniforms (matches hatch.wgsl) ──────────────────
|
// ── Group 0: shared frame uniforms (matches hatch.wgsl) ──────────────────
|
||||||
|
|
||||||
struct Uniforms {
|
struct Uniforms {
|
||||||
view_proj: mat4x4<f32>,
|
|
||||||
viewport_size: vec2<f32>,
|
viewport_size: vec2<f32>,
|
||||||
world_per_pixel: f32,
|
world_per_pixel: f32,
|
||||||
lwdisplay_enable: f32,
|
lwdisplay_enable: f32,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
// ── Bind group 0: shared projection uniforms ─────────────────────────────────
|
// ── Bind group 0: shared projection uniforms ─────────────────────────────────
|
||||||
// Must match the shared `Uniforms` struct (scene::pipeline::uniforms, 112 B).
|
// Must match the shared `Uniforms` struct (scene::pipeline::uniforms, 112 B).
|
||||||
struct Uniforms {
|
struct Uniforms {
|
||||||
view_proj: mat4x4<f32>,
|
|
||||||
viewport_size: vec2<f32>,
|
viewport_size: vec2<f32>,
|
||||||
world_per_pixel: f32,
|
world_per_pixel: f32,
|
||||||
lwdisplay_enable: f32,
|
lwdisplay_enable: f32,
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@
|
||||||
// flat shade (FlatShaded).
|
// flat shade (FlatShaded).
|
||||||
|
|
||||||
struct Uniforms {
|
struct Uniforms {
|
||||||
view_proj: mat4x4<f32>,
|
|
||||||
viewport_size: vec2<f32>,
|
viewport_size: vec2<f32>,
|
||||||
world_per_pixel: f32,
|
world_per_pixel: f32,
|
||||||
lwdisplay_enable: f32,
|
lwdisplay_enable: f32,
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@
|
||||||
// • pat0/pat1 encode up to 8 elements: positive=dash, negative=gap.
|
// • pat0/pat1 encode up to 8 elements: positive=dash, negative=gap.
|
||||||
|
|
||||||
struct Uniforms {
|
struct Uniforms {
|
||||||
view_proj: mat4x4<f32>,
|
|
||||||
viewport_size: vec2<f32>,
|
viewport_size: vec2<f32>,
|
||||||
world_per_pixel: f32,
|
world_per_pixel: f32,
|
||||||
// LWDISPLAY toggle: 0.0 = force 1 px (half_width 0.5), 1.0 = use the
|
// LWDISPLAY toggle: 0.0 = force 1 px (half_width 0.5), 1.0 = use the
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue