forked from 1b-agent/opencadstudio-upstream
View backgrounds: reference blend, image adjust, layouts, cleanup, style name
- Gradients: the middle colour sits (horizon - 0.5) viewport widths from the centre and blends over height viewport heights each side; two colours blend over a viewport height each side. - Image backgrounds: offset in device pixels (right, down), negative scale mirrors, fitted with aspect ratio covers the viewport; the dialog keeps an image's offset and scale. - Layouts: a model-space view restored on a sheet asks for the viewport, enters it and gives it the view's camera, background and visual style; inside a viewport the view goes there; a paper-space view's background is kept on the sheet viewport but not drawn; floating viewports draw their background. - Background objects no view or viewport uses any more are erased; a view without a background restored where the viewport already is leaves the viewport's background. - The viewport's named visual style (Realistic, ...) shows by name and the render-mode picker records its style on the viewport record. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
1cf13971dc
commit
9ef8f4bedf
12 files changed
+349
-70
No files matched your search
+27
-27
@@ -81,22 +81,25 @@ fn equirect_uv(ndc: vec2<f32>, rotation: f32) -> vec2<f32> {
|
||||
fn image_uv(source_uv: vec2<f32>) -> vec2<f32> {
|
||||
var uv = source_uv;
|
||||
if u.background_image_params.x < 0.5 {
|
||||
// Not fitted: the image at its own pixel size (times its scale),
|
||||
// centred on the viewport and moved by its offset.
|
||||
let pixel = (source_uv - vec2<f32>(0.5)) * max(u.viewport_size, vec2<f32>(1.0));
|
||||
uv = pixel / max(abs(u.background_image_transform.zw), vec2<f32>(1e-6))
|
||||
+ vec2<f32>(0.5) - u.background_image_transform.xy;
|
||||
// Not fitted: the image at its own pixel size times its scale (a
|
||||
// negative scale mirrors it), centred on the viewport and moved by
|
||||
// its offset in pixels, right and down.
|
||||
let pixel = (source_uv - vec2<f32>(0.5)) * max(u.viewport_size, vec2<f32>(1.0))
|
||||
- u.background_image_transform.xy;
|
||||
let size = u.background_image_transform.zw;
|
||||
let safe = select(size, vec2<f32>(1e-6), abs(size) < vec2<f32>(1e-6));
|
||||
uv = pixel / safe + vec2<f32>(0.5);
|
||||
return select(uv, fract(uv), u.background_image_params.z > 0.5);
|
||||
}
|
||||
// Fitted: the image fills the viewport; keeping its aspect ratio it
|
||||
// covers the viewport and the overflow is cut off evenly.
|
||||
if u.background_image_params.y > 0.5 {
|
||||
let image_aspect = max(u.background_image_params.w, 1e-6);
|
||||
let viewport_aspect = max(u.viewport_size.x / max(u.viewport_size.y, 1.0), 1e-6);
|
||||
if image_aspect > viewport_aspect {
|
||||
let scale = viewport_aspect / image_aspect;
|
||||
uv.y = (uv.y - 0.5) / scale + 0.5;
|
||||
uv.x = (uv.x - 0.5) * (viewport_aspect / image_aspect) + 0.5;
|
||||
} else {
|
||||
let scale = image_aspect / viewport_aspect;
|
||||
uv.x = (uv.x - 0.5) / scale + 0.5;
|
||||
uv.y = (uv.y - 0.5) * (image_aspect / viewport_aspect) + 0.5;
|
||||
}
|
||||
}
|
||||
if u.background_image_params.z > 0.5 {
|
||||
@@ -112,28 +115,25 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||
if mode == 1u {
|
||||
color = u.viewport_background.rgb;
|
||||
} else if mode == 2u {
|
||||
// Bottom to top across the viewport, the "up" direction turned
|
||||
// counter-clockwise by the rotation; in pixels, so the angle holds
|
||||
// whatever the viewport's shape, and spanning corner to corner.
|
||||
// Bottom to top along the "up" direction turned counter-clockwise by
|
||||
// the rotation, in pixels from the viewport centre. As the reference
|
||||
// draws it: the middle colour sits (horizon - 0.5) viewport widths
|
||||
// from the centre and blends linearly into the top and bottom colours
|
||||
// over height viewport heights on each side; two colours are one blend
|
||||
// over a viewport height on each side of the centre.
|
||||
let angle = u.background_params.w;
|
||||
let up = vec2<f32>(-sin(angle), cos(angle));
|
||||
let size = max(u.viewport_size, vec2<f32>(1.0));
|
||||
let pixel = (vec2<f32>(in.uv.x, 1.0 - in.uv.y) - vec2<f32>(0.5)) * size;
|
||||
let extent = max(abs(up.x) * size.x + abs(up.y) * size.y, 1.0);
|
||||
let coordinate = clamp(dot(pixel, up) / extent + 0.5, 0.0, 1.0);
|
||||
let horizon = clamp(u.background_params.y, 0.0, 1.0);
|
||||
let half_height = abs(u.background_params.z) * 0.5;
|
||||
if half_height <= 1e-6 {
|
||||
// Two colours: one blend from the bottom to the top, over twice
|
||||
// the viewport (the reference's two-colour gradient reaches the
|
||||
// end colours a viewport beyond the edges).
|
||||
color = mix(u.background_bottom.rgb, u.background_top.rgb, 0.25 + 0.5 * coordinate);
|
||||
} else {
|
||||
let lower = clamp((coordinate - (horizon - half_height)) / half_height, 0.0, 1.0);
|
||||
let upper = clamp((coordinate - horizon) / half_height, 0.0, 1.0);
|
||||
let low_color = mix(u.background_bottom.rgb, u.background_middle.rgb, lower);
|
||||
color = mix(low_color, u.background_top.rgb, upper);
|
||||
}
|
||||
let along = dot(pixel, up);
|
||||
let three = abs(u.background_params.z) > 1e-6;
|
||||
let middle_at = select(0.0, (u.background_params.y - 0.5) * size.x, three);
|
||||
let half_band = select(1.0, abs(u.background_params.z), three) * size.y;
|
||||
let middle = select(mix(u.background_bottom.rgb, u.background_top.rgb, 0.5),
|
||||
u.background_middle.rgb, three);
|
||||
let lower = clamp((along - middle_at + half_band) / half_band, 0.0, 1.0);
|
||||
let upper = clamp((along - middle_at) / half_band, 0.0, 1.0);
|
||||
color = mix(mix(u.background_bottom.rgb, middle, lower), u.background_top.rgb, upper);
|
||||
} else if mode == 3u {
|
||||
let direction = world_direction(in.ndc);
|
||||
if direction.z >= 0.0 {
|
||||
|
||||
Reference in new issue
Block a user