forked from 1b-agent/opencadstudio-upstream
fix(render): match model lineweight preview curve
This commit is contained in:
1 parent
76bdab1e5b
commit
2cd1d36661
7 files changed
+74
-16
No files matched your search
@@ -25,8 +25,9 @@ pub struct Uniforms {
|
||||
/// zooming inside MSPACE changes one scalar instead of re-tessellating and
|
||||
/// re-uploading every dashed wire.
|
||||
pub linetype_scale: f32,
|
||||
/// Multiplier for screen-space lineweights. Model space uses the user's
|
||||
/// preview scale; paper layouts derive it from the current paper zoom.
|
||||
/// Positive values scale paper-space lineweights directly. Negative values
|
||||
/// carry the model-space preview scale; lineweight shaders then apply the
|
||||
/// model preview curve before multiplying by its magnitude.
|
||||
pub lineweight_scale: f32,
|
||||
|
||||
// ── Relative-to-eye (double-single) additions ───────────────────────────
|
||||
|
||||
@@ -3848,7 +3848,7 @@ impl Scene {
|
||||
self.document.header.lineweight_display || display_plot_lineweights,
|
||||
);
|
||||
if self.current_layout == "Model" {
|
||||
uniforms.lineweight_scale = self.model_lineweight_scale;
|
||||
uniforms.lineweight_scale = -self.model_lineweight_scale;
|
||||
} else {
|
||||
let paper_per_pixel = 2.0 * self.camera.borrow().ortho_size() / canvas.1.max(1.0);
|
||||
let paper_units_per_mm = self.paper_space_unit_factor() as f32;
|
||||
|
||||
@@ -45,6 +45,8 @@ struct VertexIn {
|
||||
}
|
||||
|
||||
const DRAW_ORDER_BIAS: f32 = 0.001;
|
||||
const MODEL_LINEWEIGHT_BOOST: f32 = 2.0;
|
||||
const MODEL_LINEWEIGHT_MAX_PX: f32 = 10.0;
|
||||
|
||||
struct VertexOut {
|
||||
@builtin(position) clip_pos: vec4<f32>,
|
||||
@@ -67,7 +69,17 @@ fn resolve_hw(taper_ratio: f32, world_hw: f32, px_hw: f32) -> f32 {
|
||||
if world_hw > 0.0 {
|
||||
return max(world_hw / u.world_per_pixel, 0.5);
|
||||
}
|
||||
return select(0.5, max(px_hw * u.lineweight_scale, 0.5), u.lwdisplay_enable > 0.5);
|
||||
var display_hw = max(px_hw * u.lineweight_scale, 0.5);
|
||||
if u.lineweight_scale < 0.0 {
|
||||
let scale = -u.lineweight_scale;
|
||||
let base_hw = select(
|
||||
min(px_hw * MODEL_LINEWEIGHT_BOOST, MODEL_LINEWEIGHT_MAX_PX * 0.5),
|
||||
0.5,
|
||||
px_hw <= 0.5,
|
||||
);
|
||||
display_hw = max(base_hw * scale, 0.5);
|
||||
}
|
||||
return select(0.5, display_hw, u.lwdisplay_enable > 0.5);
|
||||
}
|
||||
|
||||
fn marker_relative(
|
||||
|
||||
+15
-5
@@ -50,6 +50,8 @@ struct HatchInstance {
|
||||
// Draw-order depth bias (see wire.wgsl). Higher draw_depth → smaller z →
|
||||
// drawn on top, ordering this fill against other entity types.
|
||||
const DRAW_ORDER_BIAS: f32 = 0.001;
|
||||
const MODEL_LINEWEIGHT_BOOST: f32 = 2.0;
|
||||
const MODEL_LINEWEIGHT_MAX_PX: f32 = 10.0;
|
||||
|
||||
struct LineFamily {
|
||||
cos_a: f32,
|
||||
@@ -133,6 +135,18 @@ struct VOut {
|
||||
// `ddx_xz`/`ddy_xz` are screen-space derivatives of `xz`, taken once in
|
||||
// fs_main: derivative builtins must run in uniform control flow, and the
|
||||
// per-family loop's early return makes later iterations non-uniform.
|
||||
fn display_lineweight(width: f32) -> f32 {
|
||||
if u.lineweight_scale < 0.0 {
|
||||
let base = select(
|
||||
min(width * MODEL_LINEWEIGHT_BOOST, MODEL_LINEWEIGHT_MAX_PX),
|
||||
1.0,
|
||||
width <= 1.0,
|
||||
);
|
||||
return max(base * -u.lineweight_scale, 1.0);
|
||||
}
|
||||
return max(width * u.lineweight_scale, 1.0);
|
||||
}
|
||||
|
||||
fn check_family(
|
||||
xz: vec2<f32>,
|
||||
ddx_xz: vec2<f32>,
|
||||
@@ -163,11 +177,7 @@ fn check_family(
|
||||
-ddx_xz.x * sin_a + ddx_xz.y * cos_a,
|
||||
-ddy_xz.x * sin_a + ddy_xz.y * cos_a,
|
||||
)) * 0.5;
|
||||
let width_px = select(
|
||||
1.0,
|
||||
max(fam.line_width * u.lineweight_scale, 1.0),
|
||||
u.lwdisplay_enable > 0.5,
|
||||
);
|
||||
let width_px = select(1.0, display_lineweight(fam.line_width), u.lwdisplay_enable > 0.5);
|
||||
let half_line = half_px * width_px;
|
||||
|
||||
// World units per screen pixel on each axis — used to light exactly the
|
||||
|
||||
@@ -23,6 +23,9 @@ struct Uniforms {
|
||||
}
|
||||
@group(0) @binding(0) var<uniform> u: Uniforms;
|
||||
|
||||
const MODEL_LINEWEIGHT_BOOST: f32 = 2.0;
|
||||
const MODEL_LINEWEIGHT_MAX_PX: f32 = 10.0;
|
||||
|
||||
// ── Group 1: per-hatch data ────────────────────────────────────────────────
|
||||
|
||||
struct HatchUniforms {
|
||||
@@ -117,6 +120,18 @@ struct VOut {
|
||||
// `ddx_xz`/`ddy_xz` are screen-space derivatives of `xz`, taken once in
|
||||
// fs_main: derivative builtins must run in uniform control flow, and the
|
||||
// per-family loop's early return makes later iterations non-uniform.
|
||||
fn display_lineweight(width: f32) -> f32 {
|
||||
if u.lineweight_scale < 0.0 {
|
||||
let base = select(
|
||||
min(width * MODEL_LINEWEIGHT_BOOST, MODEL_LINEWEIGHT_MAX_PX),
|
||||
1.0,
|
||||
width <= 1.0,
|
||||
);
|
||||
return max(base * -u.lineweight_scale, 1.0);
|
||||
}
|
||||
return max(width * u.lineweight_scale, 1.0);
|
||||
}
|
||||
|
||||
fn check_family(
|
||||
xz: vec2<f32>,
|
||||
ddx_xz: vec2<f32>,
|
||||
@@ -147,11 +162,7 @@ fn check_family(
|
||||
-ddx_xz.x * sin_a + ddx_xz.y * cos_a,
|
||||
-ddy_xz.x * sin_a + ddy_xz.y * cos_a,
|
||||
)) * 0.5;
|
||||
let width_px = select(
|
||||
1.0,
|
||||
max(fam.line_width * u.lineweight_scale, 1.0),
|
||||
u.lwdisplay_enable > 0.5,
|
||||
);
|
||||
let width_px = select(1.0, display_lineweight(fam.line_width), u.lwdisplay_enable > 0.5);
|
||||
let half_line = half_px * width_px;
|
||||
|
||||
let wpx = length(vec2<f32>(ddx_xz.x, ddy_xz.x));
|
||||
|
||||
+13
-1
@@ -72,6 +72,8 @@ struct InstanceIn {
|
||||
// draw_depth is signed (-1,1): front → positive → smaller z → drawn on top;
|
||||
// 0.0 = neutral (real depth). Depth32Float gives ample precision.
|
||||
const DRAW_ORDER_BIAS: f32 = 0.001;
|
||||
const MODEL_LINEWEIGHT_BOOST: f32 = 2.0;
|
||||
const MODEL_LINEWEIGHT_MAX_PX: f32 = 10.0;
|
||||
|
||||
struct VertexOut {
|
||||
@builtin(position) clip_pos: vec4<f32>,
|
||||
@@ -102,7 +104,17 @@ struct VertexOut {
|
||||
fn resolve_hw(taper: f32, world_hw: f32, px_hw: f32) -> f32 {
|
||||
if taper > 0.0 { return max(taper / u.world_per_pixel, 0.5); }
|
||||
if world_hw > 0.0 { return max(world_hw / u.world_per_pixel, 0.5); }
|
||||
return select(0.5, max(px_hw * u.lineweight_scale, 0.5), u.lwdisplay_enable > 0.5);
|
||||
var display_hw = max(px_hw * u.lineweight_scale, 0.5);
|
||||
if u.lineweight_scale < 0.0 {
|
||||
let scale = -u.lineweight_scale;
|
||||
let base_hw = select(
|
||||
min(px_hw * MODEL_LINEWEIGHT_BOOST, MODEL_LINEWEIGHT_MAX_PX * 0.5),
|
||||
0.5,
|
||||
px_hw <= 0.5,
|
||||
);
|
||||
display_hw = max(base_hw * scale, 0.5);
|
||||
}
|
||||
return select(0.5, display_hw, u.lwdisplay_enable > 0.5);
|
||||
}
|
||||
|
||||
fn marker_relative(position_high: vec3<f32>, position_low: vec3<f32>, instance: InstanceIn) -> vec3<f32> {
|
||||
|
||||
@@ -54,6 +54,8 @@ struct InstanceIn {
|
||||
}
|
||||
|
||||
const DRAW_ORDER_BIAS: f32 = 0.001;
|
||||
const MODEL_LINEWEIGHT_BOOST: f32 = 2.0;
|
||||
const MODEL_LINEWEIGHT_MAX_PX: f32 = 10.0;
|
||||
|
||||
struct VertexOut {
|
||||
@builtin(position) clip_pos: vec4<f32>,
|
||||
@@ -81,7 +83,17 @@ fn resolve_hw(taper_ratio: f32, world_hw: f32, px_hw: f32) -> f32 {
|
||||
return max((taper_ratio * world_hw) / u.world_per_pixel, 0.5);
|
||||
}
|
||||
if world_hw > 0.0 { return max(world_hw / u.world_per_pixel, 0.5); }
|
||||
return select(0.5, max(px_hw * u.lineweight_scale, 0.5), u.lwdisplay_enable > 0.5);
|
||||
var display_hw = max(px_hw * u.lineweight_scale, 0.5);
|
||||
if u.lineweight_scale < 0.0 {
|
||||
let scale = -u.lineweight_scale;
|
||||
let base_hw = select(
|
||||
min(px_hw * MODEL_LINEWEIGHT_BOOST, MODEL_LINEWEIGHT_MAX_PX * 0.5),
|
||||
0.5,
|
||||
px_hw <= 0.5,
|
||||
);
|
||||
display_hw = max(base_hw * scale, 0.5);
|
||||
}
|
||||
return select(0.5, display_hw, u.lwdisplay_enable > 0.5);
|
||||
}
|
||||
|
||||
fn marker_relative(position_high: vec3<f32>, position_low: vec3<f32>, c: WireConst) -> vec3<f32> {
|
||||
|
||||
Reference in new issue
Block a user