feat(antialias): AA geomètric a les línies amb edge attribute i smoothstep
Afegim antialias geomètric (sense MSAA) al pipeline de línies aprofitant que la línia ja es construeix com a quad extruït a CPU: - LineVertex: nou camp edge_dist (±1 als laterals del quad, 0 al centre). - pushLine: extrudeix 0.5px extra per banda (AA_PADDING) per allotjar el fade sense menjar gruix nominal. - line.vert: passa l'edge_dist al fragment com a varying. - line.frag: alpha *= 1 - smoothstep(0.7, 1.0, |edge_dist|) — fade Hermite C¹ als bords, sense banding. AA actiu per defecte. El toggle a runtime (F5) ve en el commit següent.
This commit is contained in:
+17
-4
@@ -1,12 +1,25 @@
|
||||
#version 450
|
||||
|
||||
// Fragment shader para líneas vectoriales.
|
||||
// Pinta el color interpolado per-vertex que viene del vertex shader.
|
||||
// (Postprocesado / bloom / glow son responsabilidad de la Fase 8.)
|
||||
// Fragment shader per a línies vectorials.
|
||||
//
|
||||
// Antialias geomètric: rebem `frag_edge_dist` interpolat (±1 als laterals del
|
||||
// quad, 0 a l'eix central). Apliquem un smoothstep d'1 píxel d'amplada perquè
|
||||
// el gruix nominal (els |edge_dist| < threshold) quedi totalment opac i només
|
||||
// el píxel extruit als laterals faci la transició suau.
|
||||
//
|
||||
// La línia ja ve extruïda amb thickness + 1px a CPU; el threshold equival a
|
||||
// (thickness)/(thickness+1), però no el coneixem aquí per vèrtex. En el cas
|
||||
// general (línies fines), fade lineal entre 0.0 i 1.0 dóna prou bon resultat
|
||||
// visualment sense necessitat d'un uniform per línia.
|
||||
|
||||
layout(location = 0) in vec4 frag_color;
|
||||
layout(location = 1) in float frag_edge_dist;
|
||||
layout(location = 0) out vec4 out_color;
|
||||
|
||||
void main() {
|
||||
out_color = frag_color;
|
||||
// |edge_dist|=0 → totalment opac; |edge_dist|=1 → totalment transparent.
|
||||
// smoothstep dóna un fade Hermite C¹ que evita banding.
|
||||
float d = abs(frag_edge_dist);
|
||||
float alpha = 1.0 - smoothstep(0.7, 1.0, d);
|
||||
out_color = vec4(frag_color.rgb, frag_color.a * alpha);
|
||||
}
|
||||
|
||||
@@ -14,10 +14,12 @@ layout(set = 1, binding = 0) uniform UBO {
|
||||
vec2 _padding; // alineamiento a 16 bytes
|
||||
} ubo;
|
||||
|
||||
layout(location = 0) in vec2 in_position; // píxeles lógicos
|
||||
layout(location = 1) in vec4 in_color; // RGBA 0..1
|
||||
layout(location = 0) in vec2 in_position; // píxeles lógicos
|
||||
layout(location = 1) in vec4 in_color; // RGBA 0..1
|
||||
layout(location = 2) in float in_edge_dist; // ±1 als laterals, 0 al centre
|
||||
|
||||
layout(location = 0) out vec4 frag_color;
|
||||
layout(location = 1) out float frag_edge_dist;
|
||||
|
||||
void main() {
|
||||
// Píxeles lógicos -> NDC (-1..+1)
|
||||
@@ -26,4 +28,5 @@ void main() {
|
||||
ndc.y = -ndc.y;
|
||||
gl_Position = vec4(ndc, 0.0, 1.0);
|
||||
frag_color = in_color;
|
||||
frag_edge_dist = in_edge_dist;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user