forked from 1b-agent/opencadstudio-upstream
Merge PR #1023: preserve minified text strokes
Keep adaptive sampling in both text shaders with compact sampling loops. Validate shader derivatives and existing text rendering, including GPU pipeline creation. Closes #964
This commit is contained in:
commit
bf4614856c
3 files changed
+64
-10
No files matched your search
@@ -49,9 +49,29 @@ fn vs_main(v: VertIn) -> VertOut {
|
||||
|
||||
@fragment
|
||||
fn fs_main(in: VertOut) -> @location(0) vec4<f32> {
|
||||
let sd = textureSample(atlas_tex, atlas_samp, in.uv).r;
|
||||
let aa = max(fwidth(sd), 1e-4);
|
||||
let alpha = smoothstep(0.5 - aa, 0.5 + aa, sd);
|
||||
let uv_dx = dpdx(in.uv);
|
||||
let uv_dy = dpdy(in.uv);
|
||||
let dims = vec2<f32>(textureDimensions(atlas_tex));
|
||||
let footprint = max(length(uv_dx * dims), length(uv_dy * dims));
|
||||
let sd_center = textureSampleLevel(atlas_tex, atlas_samp, in.uv, 0.0).r;
|
||||
let aa = max(fwidth(sd_center), 1e-4);
|
||||
var alpha = smoothstep(0.5 - aa, 0.5 + aa, sd_center);
|
||||
|
||||
if footprint > 1.0 {
|
||||
// Average coverage over the pixel footprint so thin strokes survive minification.
|
||||
let samples = select(4, 2, footprint <= 4.0);
|
||||
var sum = 0.0;
|
||||
for (var y = 0; y < samples; y += 1) {
|
||||
for (var x = 0; x < samples; x += 1) {
|
||||
let offset = (vec2<f32>(f32(x), f32(y)) + 0.5) / f32(samples) - 0.5;
|
||||
let sd = textureSampleLevel(
|
||||
atlas_tex, atlas_samp, in.uv + uv_dx * offset.x + uv_dy * offset.y, 0.0
|
||||
).r;
|
||||
sum += smoothstep(0.5 - aa, 0.5 + aa, sd);
|
||||
}
|
||||
}
|
||||
alpha = sum / f32(samples * samples);
|
||||
}
|
||||
if alpha <= 0.0 {
|
||||
discard;
|
||||
}
|
||||
|
||||
+25
-7
@@ -59,13 +59,31 @@ fn vs_main(in: VertIn) -> VertOut {
|
||||
// ── Fragment stage ────────────────────────────────────────────────────────────
|
||||
@fragment
|
||||
fn fs_main(in: VertOut) -> @location(0) vec4<f32> {
|
||||
// SDF value: 0.5 at the glyph edge, higher inside the ink.
|
||||
let sd = textureSample(atlas_tex, atlas_samp, in.uv).r;
|
||||
// Antialias over one screen-space texel of field change.
|
||||
let aa = max(fwidth(sd), 1e-4);
|
||||
let a = smoothstep(0.5 - aa, 0.5 + aa, sd);
|
||||
if (a <= 0.0) {
|
||||
let uv_dx = dpdx(in.uv);
|
||||
let uv_dy = dpdy(in.uv);
|
||||
let dims = vec2<f32>(textureDimensions(atlas_tex));
|
||||
let footprint = max(length(uv_dx * dims), length(uv_dy * dims));
|
||||
let sd_center = textureSampleLevel(atlas_tex, atlas_samp, in.uv, 0.0).r;
|
||||
let aa = max(fwidth(sd_center), 1e-4);
|
||||
var alpha = smoothstep(0.5 - aa, 0.5 + aa, sd_center);
|
||||
|
||||
if footprint > 1.0 {
|
||||
// Average coverage over the pixel footprint so thin strokes survive minification.
|
||||
let samples = select(4, 2, footprint <= 4.0);
|
||||
var sum = 0.0;
|
||||
for (var y = 0; y < samples; y += 1) {
|
||||
for (var x = 0; x < samples; x += 1) {
|
||||
let offset = (vec2<f32>(f32(x), f32(y)) + 0.5) / f32(samples) - 0.5;
|
||||
let sd = textureSampleLevel(
|
||||
atlas_tex, atlas_samp, in.uv + uv_dx * offset.x + uv_dy * offset.y, 0.0
|
||||
).r;
|
||||
sum += smoothstep(0.5 - aa, 0.5 + aa, sd);
|
||||
}
|
||||
}
|
||||
alpha = sum / f32(samples * samples);
|
||||
}
|
||||
if alpha <= 0.0 {
|
||||
discard;
|
||||
}
|
||||
return vec4<f32>(in.color.rgb, in.color.a * a);
|
||||
return vec4<f32>(in.color.rgb, in.color.a * alpha);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#[test]
|
||||
fn adaptive_text_sampling_passes_derivative_uniformity_validation() {
|
||||
for (name, source) in [
|
||||
("text", include_str!("../src/shaders/text.wgsl")),
|
||||
("block text", include_str!("../src/shaders/block_text.wgsl")),
|
||||
] {
|
||||
let module = naga::front::wgsl::parse_str(source)
|
||||
.unwrap_or_else(|error| panic!("{name}: {}", error.emit_to_string(source)));
|
||||
naga::valid::Validator::new(
|
||||
naga::valid::ValidationFlags::all(),
|
||||
naga::valid::Capabilities::empty(),
|
||||
)
|
||||
.validate(&module)
|
||||
.unwrap_or_else(|error| panic!("{name}: {error:?}"));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user