@jbrowse/render-core 5.0.0-beta.11 → 5.0.0-beta.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/OverlayCanvas.d.ts +3 -2
- package/esm/OverlayCanvas.js +4 -2
- package/esm/RenderCanvas.d.ts +4 -3
- package/esm/RenderCanvas.js +4 -2
- package/esm/ScrollLockedOverlay.d.ts +2 -2
- package/esm/ScrollLockedOverlay.js +3 -2
- package/esm/blockClipUtils.d.ts +5 -5
- package/esm/blockClipUtils.js +4 -3
- package/esm/canvas2dUtils.d.ts +15 -21
- package/esm/canvas2dUtils.js +25 -55
- package/esm/colorRampLut.d.ts +2 -2
- package/esm/colorRampLut.js +2 -2
- package/esm/coverageBand.d.ts +0 -1
- package/esm/coverageBand.js +0 -5
- package/esm/coverageBandBuffers.d.ts +8 -5
- package/esm/createRenderingBackend.d.ts +1 -1
- package/esm/displayPhase.d.ts +5 -9
- package/esm/displayPhase.js +2 -2
- package/esm/hal/mockHal.d.ts +3 -4
- package/esm/hal/mockHal.js +5 -4
- package/esm/hal/types.d.ts +5 -5
- package/esm/hal/webgl2Hal.d.ts +4 -1
- package/esm/hal/webgl2Hal.js +18 -6
- package/esm/hal/webgpuHal.js +2 -2
- package/esm/linkFeet.d.ts +4 -0
- package/esm/linkFeet.js +7 -0
- package/esm/marks/barMark.d.ts +1 -1
- package/esm/marks/barMark.js +4 -2
- package/esm/marks/colorFill.d.ts +4 -4
- package/esm/marks/colorFill.js +4 -4
- package/esm/marks/connectorMark.d.ts +48 -0
- package/esm/marks/connectorMark.js +285 -0
- package/esm/marks/drawAgainstHit.d.ts +1 -1
- package/esm/marks/drawAgainstHit.js +4 -4
- package/esm/marks/glyphPaint.d.ts +5 -4
- package/esm/marks/glyphPaint.js +17 -7
- package/esm/marks/index.d.ts +8 -5
- package/esm/marks/index.js +6 -4
- package/esm/marks/lineMark.d.ts +47 -7
- package/esm/marks/lineMark.js +53 -39
- package/esm/marks/linkMark.d.ts +43 -6
- package/esm/marks/linkMark.js +118 -21
- package/esm/marks/markBackend.d.ts +1 -1
- package/esm/marks/markBackend.js +1 -1
- package/esm/marks/markPlan.d.ts +4 -3
- package/esm/marks/markPlan.js +5 -4
- package/esm/marks/markRamp.d.ts +11 -11
- package/esm/marks/markRamp.js +9 -9
- package/esm/marks/pointMark.d.ts +11 -5
- package/esm/marks/pointMark.js +34 -9
- package/esm/marks/rowLane.d.ts +4 -2
- package/esm/marks/rowLane.js +7 -3
- package/esm/marks/rowTable.d.ts +5 -5
- package/esm/marks/rowTable.js +4 -4
- package/esm/marks/ruleMark.js +1 -0
- package/esm/marks/spanMark.d.ts +8 -7
- package/esm/marks/spanMark.js +3 -3
- package/esm/marks/types.d.ts +8 -5
- package/esm/marks/types.js +8 -1
- package/esm/perRegionRenderingBackend.d.ts +1 -1
- package/esm/perRegionRenderingBackend.js +1 -1
- package/esm/regionDataMap.d.ts +2 -2
- package/esm/regionDataMap.js +2 -2
- package/esm/shaders/barMark.glsl.generated.d.ts +1 -1
- package/esm/shaders/barMark.glsl.generated.js +1 -1
- package/esm/shaders/barMark.wgsl.generated.d.ts +1 -1
- package/esm/shaders/barMark.wgsl.generated.js +1 -1
- package/esm/shaders/capsule.js.generated.d.ts +1 -1
- package/esm/shaders/capsule.js.generated.js +2 -2
- package/esm/shaders/connectorMark.consts.generated.d.ts +11 -0
- package/esm/shaders/connectorMark.consts.generated.js +13 -0
- package/esm/shaders/{coverageIndicator.generated.d.ts → connectorMark.generated.d.ts} +2 -1
- package/esm/shaders/connectorMark.generated.js +8 -0
- package/esm/shaders/connectorMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/connectorMark.glsl.generated.js +4 -0
- package/esm/shaders/connectorMark.iface.generated.d.ts +88 -0
- package/esm/shaders/connectorMark.iface.generated.js +1194 -0
- package/esm/shaders/connectorMark.js.generated.d.ts +5 -0
- package/esm/shaders/connectorMark.js.generated.js +47 -0
- package/esm/shaders/connectorMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/connectorMark.wgsl.generated.js +3 -0
- package/esm/shaders/coverageInterbase.glsl.generated.d.ts +1 -1
- package/esm/shaders/coverageInterbase.glsl.generated.js +1 -1
- package/esm/shaders/coverageInterbase.wgsl.generated.d.ts +1 -1
- package/esm/shaders/coverageInterbase.wgsl.generated.js +1 -1
- package/esm/shaders/curveDistance.js.generated.d.ts +4 -0
- package/esm/shaders/curveDistance.js.generated.js +113 -0
- package/esm/shaders/insertionGlyph.generated.d.ts +6 -0
- package/esm/shaders/insertionGlyph.generated.js +8 -0
- package/esm/shaders/lineCenterMark.glsl.generated.d.ts +2 -2
- package/esm/shaders/lineCenterMark.glsl.generated.js +2 -2
- package/esm/shaders/lineCenterMark.iface.generated.d.ts +11 -9
- package/esm/shaders/lineCenterMark.iface.generated.js +20 -18
- package/esm/shaders/lineCenterMark.wgsl.generated.d.ts +1 -1
- package/esm/shaders/lineCenterMark.wgsl.generated.js +1 -1
- package/esm/shaders/lineCommon.js.generated.d.ts +1 -0
- package/esm/shaders/lineCommon.js.generated.js +20 -0
- package/esm/shaders/lineStepMark.glsl.generated.d.ts +2 -2
- package/esm/shaders/lineStepMark.glsl.generated.js +2 -2
- package/esm/shaders/lineStepMark.iface.generated.d.ts +11 -9
- package/esm/shaders/lineStepMark.iface.generated.js +20 -18
- package/esm/shaders/lineStepMark.wgsl.generated.d.ts +1 -1
- package/esm/shaders/lineStepMark.wgsl.generated.js +1 -1
- package/esm/shaders/linkMark.consts.generated.d.ts +1 -0
- package/esm/shaders/linkMark.consts.generated.js +1 -0
- package/esm/shaders/linkMark.glsl.generated.d.ts +2 -2
- package/esm/shaders/linkMark.glsl.generated.js +2 -2
- package/esm/shaders/linkMark.js.generated.d.ts +4 -2
- package/esm/shaders/linkMark.js.generated.js +33 -4
- package/esm/shaders/linkMark.wgsl.generated.d.ts +1 -1
- package/esm/shaders/linkMark.wgsl.generated.js +1 -1
- package/esm/shaders/pointMark.glsl.generated.d.ts +1 -1
- package/esm/shaders/pointMark.glsl.generated.js +1 -1
- package/esm/shaders/pointMark.iface.generated.d.ts +10 -8
- package/esm/shaders/pointMark.iface.generated.js +18 -16
- package/esm/shaders/pointMark.wgsl.generated.d.ts +1 -1
- package/esm/shaders/pointMark.wgsl.generated.js +1 -1
- package/esm/shaders/spanMark.glsl.generated.d.ts +1 -1
- package/esm/shaders/spanMark.glsl.generated.js +1 -1
- package/esm/shaders/spanMark.wgsl.generated.d.ts +1 -1
- package/esm/shaders/spanMark.wgsl.generated.js +1 -1
- package/esm/slangPass.d.ts +5 -3
- package/esm/slangPass.js +2 -2
- package/package.json +7 -4
- package/src/shaders/arcHull.test.ts +87 -0
- package/src/shaders/barMark.glsl.generated.ts +1 -1
- package/src/shaders/barMark.slang +2 -2
- package/src/shaders/barMark.wgsl.generated.ts +1 -1
- package/src/shaders/capsule.js.generated.ts +2 -2
- package/src/shaders/capsule.slang +69 -24
- package/src/shaders/clipStrip.slang +1 -1
- package/src/shaders/colorPack.slang +2 -2
- package/src/shaders/colorRampLut.slang +7 -7
- package/src/shaders/connectorMark.consts.generated.ts +24 -0
- package/src/shaders/connectorMark.generated.ts +12 -0
- package/src/shaders/connectorMark.glsl.generated.ts +6 -0
- package/src/shaders/connectorMark.iface.generated.ts +1270 -0
- package/src/shaders/connectorMark.js.generated.ts +52 -0
- package/src/shaders/connectorMark.slang +287 -0
- package/src/shaders/connectorMark.wgsl.generated.ts +4 -0
- package/src/shaders/coverageBand.slang +10 -12
- package/src/shaders/coverageInterbase.glsl.generated.ts +1 -1
- package/src/shaders/coverageInterbase.slang +24 -21
- package/src/shaders/coverageInterbase.wgsl.generated.ts +1 -1
- package/src/shaders/coverageSnp.slang +1 -1
- package/src/shaders/curveDistance.js.generated.ts +112 -0
- package/src/shaders/curveDistance.slang +104 -1
- package/src/shaders/farDome.test.ts +117 -0
- package/src/shaders/hpClampFloor.test.ts +0 -4
- package/src/shaders/insertionGlyph.generated.ts +14 -0
- package/src/shaders/insertionGlyph.slang +59 -0
- package/src/shaders/lineCenterMark.glsl.generated.ts +2 -2
- package/src/shaders/lineCenterMark.iface.generated.ts +21 -18
- package/src/shaders/lineCenterMark.slang +19 -23
- package/src/shaders/lineCenterMark.wgsl.generated.ts +1 -1
- package/src/shaders/lineCommon.js.generated.ts +20 -0
- package/src/shaders/lineCommon.slang +18 -8
- package/src/shaders/lineStepMark.glsl.generated.ts +2 -2
- package/src/shaders/lineStepMark.iface.generated.ts +21 -18
- package/src/shaders/lineStepMark.slang +10 -6
- package/src/shaders/lineStepMark.wgsl.generated.ts +1 -1
- package/src/shaders/linkMark.consts.generated.ts +2 -0
- package/src/shaders/linkMark.glsl.generated.ts +2 -2
- package/src/shaders/linkMark.js.generated.ts +30 -4
- package/src/shaders/linkMark.slang +67 -24
- package/src/shaders/linkMark.wgsl.generated.ts +1 -1
- package/src/shaders/markColor.slang +10 -10
- package/src/shaders/pointMark.glsl.generated.ts +1 -1
- package/src/shaders/pointMark.iface.generated.ts +19 -16
- package/src/shaders/pointMark.slang +12 -8
- package/src/shaders/pointMark.wgsl.generated.ts +1 -1
- package/src/shaders/rowRect.slang +3 -3
- package/src/shaders/rowTable.slang +12 -8
- package/src/shaders/scoreScale.slang +1 -1
- package/src/shaders/spanMark.glsl.generated.ts +1 -1
- package/src/shaders/spanMark.slang +5 -5
- package/src/shaders/spanMark.wgsl.generated.ts +1 -1
- package/src/shaders/viewRegion.slang +13 -0
- package/esm/shaders/coverageIndicator.generated.js +0 -7
- package/esm/shaders/coverageIndicator.glsl.generated.d.ts +0 -2
- package/esm/shaders/coverageIndicator.glsl.generated.js +0 -4
- package/esm/shaders/coverageIndicator.iface.generated.d.ts +0 -85
- package/esm/shaders/coverageIndicator.iface.generated.js +0 -114
- package/esm/shaders/coverageIndicator.wgsl.generated.d.ts +0 -1
- package/esm/shaders/coverageIndicator.wgsl.generated.js +0 -3
- package/src/shaders/coverageIndicator.generated.ts +0 -11
- package/src/shaders/coverageIndicator.glsl.generated.ts +0 -6
- package/src/shaders/coverageIndicator.iface.generated.ts +0 -172
- package/src/shaders/coverageIndicator.slang +0 -61
- package/src/shaders/coverageIndicator.wgsl.generated.ts +0 -4
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// AUTO-GENERATED by packages/shader-tools/src/shader-codegen from connectorMark.slang.
|
|
2
|
+
// Do not edit. Run `pnpm gen:shaders` to regenerate.
|
|
3
|
+
|
|
4
|
+
// Scalar twins of connectorMark.slang, transliterated from slangc's WGSL so
|
|
5
|
+
// the Canvas2D and SVG paths run the shader's own math. See adr-051.
|
|
6
|
+
|
|
7
|
+
function _max(a: number, b: number) {
|
|
8
|
+
return b > a || Number.isNaN(a) ? b : a
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function _min(a: number, b: number) {
|
|
12
|
+
return b < a || Number.isNaN(a) ? b : a
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function connectorBudgetPx(dx: number, dy: number): number {
|
|
16
|
+
let _t0 = _min(Math.abs(dy), 150.0)
|
|
17
|
+
return (Math.sqrt(((dx * dx) + (_t0 * _t0))) * 0.30000001192092896)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function connectorHandlePx(budget: number, maxHandlePx: number): number {
|
|
21
|
+
return _min(maxHandlePx, budget)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function connectorLiftPx(budget: number, dy: number, bend: number): number {
|
|
25
|
+
let _t0: number
|
|
26
|
+
if ((bend < -1.00000001504746622e+29)) {
|
|
27
|
+
_t0 = _min(budget, _max(0.0, (30.0 - Math.abs(dy))))
|
|
28
|
+
} else {
|
|
29
|
+
_t0 = (-_min(bend, 110.0) / 0.75)
|
|
30
|
+
}
|
|
31
|
+
return _t0
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function connectorTangent(strand: number, leading: number, reversed: number): number {
|
|
35
|
+
let _t0: number
|
|
36
|
+
if ((leading != 0.0)) {
|
|
37
|
+
_t0 = -1.0
|
|
38
|
+
} else {
|
|
39
|
+
_t0 = 1.0
|
|
40
|
+
}
|
|
41
|
+
let _t1 = (strand * _t0)
|
|
42
|
+
if ((reversed != 0.0)) {
|
|
43
|
+
_t0 = -1.0
|
|
44
|
+
} else {
|
|
45
|
+
_t0 = 1.0
|
|
46
|
+
}
|
|
47
|
+
return (_t1 * _t0)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function connectorStrokePx(width: number, dpr: number): number {
|
|
51
|
+
return _max(width, (1.5 / dpr))
|
|
52
|
+
}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
// The `connector` mark shape: one instance is a stroked cubic between two
|
|
2
|
+
// placed points, `x` on the displayed region whose payload holds the instance
|
|
3
|
+
// and `x2` on the region `x2Region` names, each at the centre of its own row.
|
|
4
|
+
// Both place through a uniform table of the view's displayed regions, so a
|
|
5
|
+
// pan or zoom writes the table and no buffer. The curve is the breakpoint and
|
|
6
|
+
// read-pair connector both views draw: its handles leave each end along the
|
|
7
|
+
// read's direction on screen, flipped at a split junction's leading end, and
|
|
8
|
+
// the pair of controls lifts into a bow over a shared row or drops by `bend`
|
|
9
|
+
// px into a dip, the depth a caller sizes to the room it has.
|
|
10
|
+
//
|
|
11
|
+
// The hull is a triangle strip along the curve inflated by the half stroke and
|
|
12
|
+
// one antialiasing ramp, and the fragment fades on its distance across, which
|
|
13
|
+
// the strip's straight sections carry exactly. An instance can end in an open
|
|
14
|
+
// arrowhead, and a straight one can be dashed.
|
|
15
|
+
//! targets: wgsl, glsl
|
|
16
|
+
//! topology: triangle-strip
|
|
17
|
+
//! coverage: analytic
|
|
18
|
+
//! export-consts: CONNECTOR_CURVE_SEGMENTS, CONNECTOR_BOW, CONNECTOR_MAX_REACH_PX, CONNECTOR_APEX_RATIO, CONNECTOR_MAX_HANDLE_PX, CONNECTOR_MINUS_1, CONNECTOR_MINUS_2, CONNECTOR_LEADING_2, CONNECTOR_STRAIGHT, CONNECTOR_DASHED, CONNECTOR_ARROW
|
|
19
|
+
//! js-export: connectorBudgetPx, connectorHandlePx, connectorLiftPx, connectorTangent, connectorStrokePx
|
|
20
|
+
|
|
21
|
+
import antialias;
|
|
22
|
+
import colorPack;
|
|
23
|
+
import hpmath;
|
|
24
|
+
import viewRegion;
|
|
25
|
+
|
|
26
|
+
public static const uint CONNECTOR_CURVE_SEGMENTS = 48u;
|
|
27
|
+
static const uint CURVE_VERTS = (CONNECTOR_CURVE_SEGMENTS + 1u) * 2u;
|
|
28
|
+
// Each arrowhead arm's block of the strip: the join's repeated vertex, then its
|
|
29
|
+
// quad with the first corner doubled, so both joins are degenerate triangles.
|
|
30
|
+
static const uint ARM_VERTS = 6u;
|
|
31
|
+
public static const uint VERTS_PER_INSTANCE = CURVE_VERTS + 2u * ARM_VERTS;
|
|
32
|
+
|
|
33
|
+
// The `bend` lane's value for a connector that bows up over its row rather
|
|
34
|
+
// than dipping by a set depth.
|
|
35
|
+
public static const float CONNECTOR_BOW = -1.0e30;
|
|
36
|
+
// Every shaping term stays under this fraction of the span the curve covers,
|
|
37
|
+
// so a handle never folds the cubic back over itself.
|
|
38
|
+
static const float CONNECTOR_SPAN_FACTOR = 0.3;
|
|
39
|
+
public static const float CONNECTOR_MAX_HANDLE_PX = 200.0;
|
|
40
|
+
// The handles are horizontal, so a tall vertical gap only widens the bulge;
|
|
41
|
+
// past this it earns no more.
|
|
42
|
+
static const float CONNECTOR_MAX_VERTICAL_SPAN_PX = 150.0;
|
|
43
|
+
// A symmetric cubic's extreme sits 3/4 of the way from its ends to its
|
|
44
|
+
// controls, so a dip asked to reach a depth puts the controls 4/3 past it.
|
|
45
|
+
public static const float CONNECTOR_APEX_RATIO = 0.75;
|
|
46
|
+
static const float CONNECTOR_MAX_BOW_PX = 30.0;
|
|
47
|
+
// The deepest a dip may reach below its ends, a ceiling on `bend`.
|
|
48
|
+
public static const float CONNECTOR_MAX_REACH_PX = 110.0;
|
|
49
|
+
|
|
50
|
+
// The `bits` lane.
|
|
51
|
+
public static const uint CONNECTOR_MINUS_1 = 1u;
|
|
52
|
+
public static const uint CONNECTOR_MINUS_2 = 2u;
|
|
53
|
+
public static const uint CONNECTOR_LEADING_2 = 4u;
|
|
54
|
+
public static const uint CONNECTOR_STRAIGHT = 8u;
|
|
55
|
+
public static const uint CONNECTOR_DASHED = 16u;
|
|
56
|
+
public static const uint CONNECTOR_ARROW = 32u;
|
|
57
|
+
|
|
58
|
+
struct ConnectorInstance {
|
|
59
|
+
uint x : ATTR0;
|
|
60
|
+
uint x2 : ATTR1;
|
|
61
|
+
uint x2Region : ATTR2;
|
|
62
|
+
uint row : ATTR3;
|
|
63
|
+
uint row2 : ATTR4;
|
|
64
|
+
float bend : ATTR5;
|
|
65
|
+
float width : ATTR6;
|
|
66
|
+
uint color : ATTR7;
|
|
67
|
+
uint bits : ATTR8;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
struct Uniforms {
|
|
71
|
+
float canvasHeight;
|
|
72
|
+
float canvasWidth;
|
|
73
|
+
float devicePixelRatio;
|
|
74
|
+
// Canvas y of row 0's centre, and the px between two rows' centres.
|
|
75
|
+
float rowOffsetPx;
|
|
76
|
+
float rowPitchPx;
|
|
77
|
+
float maxHandlePx;
|
|
78
|
+
float dashPx;
|
|
79
|
+
float gapPx;
|
|
80
|
+
float arrowPx;
|
|
81
|
+
uint regionCount;
|
|
82
|
+
float zero;
|
|
83
|
+
// The table entry of the region whose payload is drawing, which every
|
|
84
|
+
// instance's `x` is on.
|
|
85
|
+
float4 ownEntry;
|
|
86
|
+
float4 regionTable[VIEW_REGION_MAX];
|
|
87
|
+
};
|
|
88
|
+
[[vk::binding(1, 0)]] ConstantBuffer<Uniforms> u;
|
|
89
|
+
|
|
90
|
+
struct VsOut {
|
|
91
|
+
float4 position : SV_Position;
|
|
92
|
+
float4 color : COLOR0;
|
|
93
|
+
// Signed px from the centreline, and px along it from the `x` end.
|
|
94
|
+
float across : COLOR1;
|
|
95
|
+
float along : COLOR2;
|
|
96
|
+
nointerpolation float halfWidthPx : COLOR3;
|
|
97
|
+
nointerpolation float dashed : COLOR4;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// How much shaping a curve may spend: a share of the distance it covers.
|
|
101
|
+
public float connectorBudgetPx(float dx, float dy) {
|
|
102
|
+
float h = min(abs(dy), CONNECTOR_MAX_VERTICAL_SPAN_PX);
|
|
103
|
+
return sqrt(dx * dx + h * h) * CONNECTOR_SPAN_FACTOR;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
public float connectorHandlePx(float budget, float maxHandlePx) {
|
|
107
|
+
return min(maxHandlePx, budget);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// How far both controls rise above their ends, negative for a dip. A bow fades
|
|
111
|
+
// as the rows separate, since a cross-row curve already has height; a dip is
|
|
112
|
+
// not held to the budget, because a vertical offset cannot fold the curve.
|
|
113
|
+
public float connectorLiftPx(float budget, float dy, float bend) {
|
|
114
|
+
return bend < -1.0e29
|
|
115
|
+
? min(budget, max(0.0, CONNECTOR_MAX_BOW_PX - abs(dy)))
|
|
116
|
+
: -min(bend, CONNECTOR_MAX_REACH_PX) / CONNECTOR_APEX_RATIO;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// The screen sign of an end's handle: along the read's direction at a trailing
|
|
120
|
+
// end, against it at a split junction's leading end, mirrored on a reversed
|
|
121
|
+
// region.
|
|
122
|
+
public float connectorTangent(float strand, float leading, float reversed) {
|
|
123
|
+
return strand * (leading != 0.0 ? -1.0 : 1.0) * (reversed != 0.0 ? -1.0 : 1.0);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Floored at 1.5 device px, so the single antialiasing ramp has room.
|
|
127
|
+
public float connectorStrokePx(float width, float dpr) {
|
|
128
|
+
return max(width, 1.5 / dpr);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
struct Cubic {
|
|
132
|
+
float2 p0;
|
|
133
|
+
float2 p1;
|
|
134
|
+
float2 p2;
|
|
135
|
+
float2 p3;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
float2 cubicAt(Cubic c, float t) {
|
|
139
|
+
float s = 1.0 - t;
|
|
140
|
+
return s * s * s * c.p0 + 3.0 * s * s * t * c.p1 + 3.0 * s * t * t * c.p2
|
|
141
|
+
+ t * t * t * c.p3;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
float2 cubicDirection(Cubic c, float t) {
|
|
145
|
+
float s = 1.0 - t;
|
|
146
|
+
float2 d = 3.0 * s * s * (c.p1 - c.p0) + 6.0 * s * t * (c.p2 - c.p1)
|
|
147
|
+
+ 3.0 * t * t * (c.p3 - c.p2);
|
|
148
|
+
float len = length(d);
|
|
149
|
+
if (len > 1e-6) { return d / len; }
|
|
150
|
+
float2 chord = c.p3 - c.p0;
|
|
151
|
+
float chordLen = length(chord);
|
|
152
|
+
return chordLen > 1e-6 ? chord / chordLen : float2(1.0, 0.0);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
float bitSet(uint bits, uint bit) {
|
|
156
|
+
return (bits & bit) != 0u ? 1.0 : 0.0;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
Cubic placeCubic(ConnectorInstance inst, float4 entry2) {
|
|
160
|
+
Cubic c;
|
|
161
|
+
c.p0 = float2(viewRegionPx(inst.x, u.ownEntry, u.zero),
|
|
162
|
+
u.rowOffsetPx + float(inst.row) * u.rowPitchPx);
|
|
163
|
+
c.p3 = float2(viewRegionPx(inst.x2, entry2, u.zero),
|
|
164
|
+
u.rowOffsetPx + float(inst.row2) * u.rowPitchPx);
|
|
165
|
+
if ((inst.bits & CONNECTOR_STRAIGHT) != 0u) {
|
|
166
|
+
c.p1 = c.p0;
|
|
167
|
+
c.p2 = c.p3;
|
|
168
|
+
return c;
|
|
169
|
+
}
|
|
170
|
+
float2 d = c.p3 - c.p0;
|
|
171
|
+
float budget = connectorBudgetPx(d.x, d.y);
|
|
172
|
+
float handle = connectorHandlePx(budget, u.maxHandlePx);
|
|
173
|
+
float lift = connectorLiftPx(budget, d.y, inst.bend);
|
|
174
|
+
float t1 = connectorTangent(1.0 - 2.0 * bitSet(inst.bits, CONNECTOR_MINUS_1),
|
|
175
|
+
0.0, u.ownEntry.w < 0.0 ? 1.0 : 0.0);
|
|
176
|
+
float t2 = connectorTangent(1.0 - 2.0 * bitSet(inst.bits, CONNECTOR_MINUS_2),
|
|
177
|
+
bitSet(inst.bits, CONNECTOR_LEADING_2),
|
|
178
|
+
entry2.w < 0.0 ? 1.0 : 0.0);
|
|
179
|
+
c.p1 = float2(c.p0.x + handle * t1, c.p0.y - lift);
|
|
180
|
+
c.p2 = float2(c.p3.x + handle * t2, c.p3.y - lift);
|
|
181
|
+
return c;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// The curve's length up to segment `seg`, as the strip's chords measure it.
|
|
185
|
+
float lengthTo(Cubic c, uint seg) {
|
|
186
|
+
float total = 0.0;
|
|
187
|
+
float2 prev = c.p0;
|
|
188
|
+
for (uint k = 1u; k <= seg; k++) {
|
|
189
|
+
float2 next = cubicAt(c, float(k) / float(CONNECTOR_CURVE_SEGMENTS));
|
|
190
|
+
total += length(next - prev);
|
|
191
|
+
prev = next;
|
|
192
|
+
}
|
|
193
|
+
return total;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
struct StripVertex {
|
|
197
|
+
float2 screen;
|
|
198
|
+
float across;
|
|
199
|
+
float along;
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
StripVertex curveVertex(Cubic c, uint seg, float side, float hw, bool dashed) {
|
|
203
|
+
float t = float(seg) / float(CONNECTOR_CURVE_SEGMENTS);
|
|
204
|
+
float2 dir = cubicDirection(c, t);
|
|
205
|
+
StripVertex v;
|
|
206
|
+
v.across = side * hw;
|
|
207
|
+
v.screen = cubicAt(c, t) + float2(-dir.y, dir.x) * v.across;
|
|
208
|
+
v.along = dashed ? lengthTo(c, seg) : 0.0;
|
|
209
|
+
return v;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// An open arrowhead's arm `a` at the `x2` end, pointing the way the read
|
|
213
|
+
// continues: from the tip back and off the row by `arrowPx`.
|
|
214
|
+
float2 armEnd(Cubic c, uint a, float strand2, bool reversed2) {
|
|
215
|
+
float back = (reversed2 ? -strand2 : strand2) * -u.arrowPx;
|
|
216
|
+
return c.p3 + float2(back, a == 0u ? -u.arrowPx : u.arrowPx);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
StripVertex armCorner(Cubic c, uint a, uint corner, float hw, float strand2, bool reversed2) {
|
|
220
|
+
float2 end = armEnd(c, a, strand2, reversed2);
|
|
221
|
+
float2 axis = end - c.p3;
|
|
222
|
+
float len = max(length(axis), 1e-6);
|
|
223
|
+
float2 dir = axis / len;
|
|
224
|
+
StripVertex v;
|
|
225
|
+
v.across = (corner % 2u == 0u) ? -hw : hw;
|
|
226
|
+
v.along = 0.0;
|
|
227
|
+
float at = corner >= 2u ? len : 0.0;
|
|
228
|
+
v.screen = c.p3 + dir * at + float2(-dir.y, dir.x) * v.across;
|
|
229
|
+
return v;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
[shader("vertex")]
|
|
233
|
+
VsOut vs_main(ConnectorInstance inst, uint vid : SV_VertexID) {
|
|
234
|
+
bool placed = inst.x2Region < u.regionCount;
|
|
235
|
+
float4 entry2 = u.regionTable[min(inst.x2Region, VIEW_REGION_MAX - 1u)];
|
|
236
|
+
Cubic c = placeCubic(inst, entry2);
|
|
237
|
+
float halfWidth = 0.5 * connectorStrokePx(inst.width, u.devicePixelRatio);
|
|
238
|
+
float hw = halfWidth + aaHalfPx(u.devicePixelRatio);
|
|
239
|
+
bool dashed = (inst.bits & CONNECTOR_DASHED) != 0u;
|
|
240
|
+
bool arrow = (inst.bits & CONNECTOR_ARROW) != 0u;
|
|
241
|
+
float strand2 = 1.0 - 2.0 * bitSet(inst.bits, CONNECTOR_MINUS_2);
|
|
242
|
+
bool reversed2 = entry2.w < 0.0;
|
|
243
|
+
|
|
244
|
+
StripVertex v;
|
|
245
|
+
bool onArm = false;
|
|
246
|
+
if (vid < CURVE_VERTS) {
|
|
247
|
+
v = curveVertex(c, vid / 2u, (vid % 2u == 0u) ? -1.0 : 1.0, hw, dashed);
|
|
248
|
+
} else {
|
|
249
|
+
uint j = vid - CURVE_VERTS;
|
|
250
|
+
uint a = j / ARM_VERTS;
|
|
251
|
+
uint k = j % ARM_VERTS;
|
|
252
|
+
// The block starts from the vertex before it: the curve's last, or the
|
|
253
|
+
// first arm's last corner.
|
|
254
|
+
StripVertex start = a == 0u
|
|
255
|
+
? curveVertex(c, CONNECTOR_CURVE_SEGMENTS, 1.0, hw, dashed)
|
|
256
|
+
: (arrow ? armCorner(c, 0u, 3u, hw, strand2, reversed2)
|
|
257
|
+
: curveVertex(c, CONNECTOR_CURVE_SEGMENTS, 1.0, hw, dashed));
|
|
258
|
+
if (k == 0u || !arrow) {
|
|
259
|
+
v = start;
|
|
260
|
+
} else {
|
|
261
|
+
v = armCorner(c, a, k <= 2u ? 0u : k - 2u, hw, strand2, reversed2);
|
|
262
|
+
onArm = true;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
VsOut o;
|
|
267
|
+
o.position = placed
|
|
268
|
+
? float4(v.screen.x / u.canvasWidth * 2.0 - 1.0,
|
|
269
|
+
yPxToClipY(v.screen.y, u.canvasHeight), 0.0, 1.0)
|
|
270
|
+
: float4(-2.0, -2.0, 0.0, 1.0);
|
|
271
|
+
o.color = unpackRGBA(inst.color);
|
|
272
|
+
o.across = v.across;
|
|
273
|
+
o.along = v.along;
|
|
274
|
+
o.halfWidthPx = halfWidth;
|
|
275
|
+
o.dashed = dashed && !onArm ? 1.0 : 0.0;
|
|
276
|
+
return o;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
[shader("fragment")]
|
|
280
|
+
float4 fs_main(VsOut fragIn) : SV_Target {
|
|
281
|
+
float dash = fragIn.dashed > 0.5 && u.dashPx > 0.0
|
|
282
|
+
? dashCoverage(fragIn.along, u.dashPx, u.gapPx, u.devicePixelRatio)
|
|
283
|
+
: 1.0;
|
|
284
|
+
float alpha = edgeCoverage(fragIn.halfWidthPx - abs(fragIn.across), u.devicePixelRatio)
|
|
285
|
+
* dash;
|
|
286
|
+
return float4(fragIn.color.rgb, fragIn.color.a * alpha);
|
|
287
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// AUTO-GENERATED by packages/shader-tools/src/shader-codegen from connectorMark.slang.
|
|
2
|
+
// Do not edit. Run `pnpm gen:shaders` to regenerate.
|
|
3
|
+
|
|
4
|
+
export const WGSL_SOURCE = "struct Uniforms_std140_0\n{\n @align(16) canvasHeight_0 : f32,\n @align(4) canvasWidth_0 : f32,\n @align(8) devicePixelRatio_0 : f32,\n @align(4) rowOffsetPx_0 : f32,\n @align(16) rowPitchPx_0 : f32,\n @align(4) maxHandlePx_0 : f32,\n @align(8) dashPx_0 : f32,\n @align(4) gapPx_0 : f32,\n @align(16) arrowPx_0 : f32,\n @align(4) regionCount_0 : u32,\n @align(8) zero_0 : f32,\n @align(16) ownEntry_0 : vec4<f32>,\n @align(16) regionTable_0 : array<vec4<f32>, i32(256)>,\n};\n\n@binding(1) @group(0) var<uniform> u_0 : Uniforms_std140_0;\nfn hpSplitUint_0( value_0 : u32) -> vec2<f32>\n{\n var lo_0 : u32 = (value_0 & (u32(4095)));\n return vec2<f32>(f32(value_0 - lo_0), f32(lo_0));\n}\n\nfn hpViewportOffsetBp_0( splitPos_0 : vec2<f32>, bpRange_0 : vec3<f32>, hpZero_0 : f32) -> f32\n{\n var floorBp_0 : f32 = -3.00000000549775576e+38f + hpZero_0;\n return max(bpRange_0.x - splitPos_0.x, floorBp_0) + max(bpRange_0.y - splitPos_0.y, floorBp_0);\n}\n\nfn viewRegionPx_0( bp_0 : u32, r_0 : vec4<f32>, hpZero_1 : f32) -> f32\n{\n return r_0.x - hpViewportOffsetBp_0(hpSplitUint_0(bp_0), vec3<f32>(r_0.y, r_0.z, 0.0f), hpZero_1) * r_0.w;\n}\n\nfn connectorBudgetPx_0( dx_0 : f32, dy_0 : f32) -> f32\n{\n var _S1 : f32 = min(abs(dy_0), 150.0f);\n return sqrt(dx_0 * dx_0 + _S1 * _S1) * 0.30000001192092896f;\n}\n\nfn connectorHandlePx_0( budget_0 : f32, maxHandlePx_1 : f32) -> f32\n{\n return min(maxHandlePx_1, budget_0);\n}\n\nfn connectorLiftPx_0( budget_1 : f32, dy_1 : f32, bend_0 : f32) -> f32\n{\n var _S2 : f32;\n if(bend_0 < -1.00000001504746622e+29f)\n {\n _S2 = min(budget_1, max(0.0f, 30.0f - abs(dy_1)));\n }\n else\n {\n _S2 = - min(bend_0, 110.0f) / 0.75f;\n }\n return _S2;\n}\n\nfn bitSet_0( bits_0 : u32, bit_0 : u32) -> f32\n{\n var _S3 : f32;\n if(((bits_0 & (bit_0))) != u32(0))\n {\n _S3 = 1.0f;\n }\n else\n {\n _S3 = 0.0f;\n }\n return _S3;\n}\n\nfn connectorTangent_0( strand_0 : f32, leading_0 : f32, reversed_0 : f32) -> f32\n{\n var _S4 : f32;\n if(leading_0 != 0.0f)\n {\n _S4 = -1.0f;\n }\n else\n {\n _S4 = 1.0f;\n }\n var _S5 : f32 = strand_0 * _S4;\n if(reversed_0 != 0.0f)\n {\n _S4 = -1.0f;\n }\n else\n {\n _S4 = 1.0f;\n }\n return _S5 * _S4;\n}\n\nstruct Cubic_0\n{\n p0_0 : vec2<f32>,\n p1_0 : vec2<f32>,\n p2_0 : vec2<f32>,\n p3_0 : vec2<f32>,\n};\n\nstruct ConnectorInstance_0\n{\n x_0 : u32,\n x2_0 : u32,\n x2Region_0 : u32,\n row_0 : u32,\n row2_0 : u32,\n bend_1 : f32,\n width_0 : f32,\n color_0 : u32,\n bits_1 : u32,\n};\n\nfn placeCubic_0( inst_0 : ConnectorInstance_0, entry2_0 : vec4<f32>) -> Cubic_0\n{\n var c_0 : Cubic_0;\n c_0.p0_0 = vec2<f32>(viewRegionPx_0(inst_0.x_0, u_0.ownEntry_0, u_0.zero_0), u_0.rowOffsetPx_0 + f32(inst_0.row_0) * u_0.rowPitchPx_0);\n c_0.p3_0 = vec2<f32>(viewRegionPx_0(inst_0.x2_0, entry2_0, u_0.zero_0), u_0.rowOffsetPx_0 + f32(inst_0.row2_0) * u_0.rowPitchPx_0);\n if((((inst_0.bits_1) & (u32(8)))) != u32(0))\n {\n c_0.p1_0 = c_0.p0_0;\n c_0.p2_0 = c_0.p3_0;\n return c_0;\n }\n var d_0 : vec2<f32> = c_0.p3_0 - c_0.p0_0;\n var _S6 : f32 = d_0.y;\n var budget_2 : f32 = connectorBudgetPx_0(d_0.x, _S6);\n var handle_0 : f32 = connectorHandlePx_0(budget_2, u_0.maxHandlePx_0);\n var lift_0 : f32 = connectorLiftPx_0(budget_2, _S6, inst_0.bend_1);\n var _S7 : f32 = 1.0f - 2.0f * bitSet_0(inst_0.bits_1, u32(1));\n var _S8 : f32;\n if((u_0.ownEntry_0.w) < 0.0f)\n {\n _S8 = 1.0f;\n }\n else\n {\n _S8 = 0.0f;\n }\n var t1_0 : f32 = connectorTangent_0(_S7, 0.0f, _S8);\n var _S9 : f32 = 1.0f - 2.0f * bitSet_0(inst_0.bits_1, u32(2));\n var _S10 : f32 = bitSet_0(inst_0.bits_1, u32(4));\n if((entry2_0.w) < 0.0f)\n {\n _S8 = 1.0f;\n }\n else\n {\n _S8 = 0.0f;\n }\n var t2_0 : f32 = connectorTangent_0(_S9, _S10, _S8);\n c_0.p1_0 = vec2<f32>(c_0.p0_0.x + handle_0 * t1_0, c_0.p0_0.y - lift_0);\n c_0.p2_0 = vec2<f32>(c_0.p3_0.x + handle_0 * t2_0, c_0.p3_0.y - lift_0);\n return c_0;\n}\n\nfn connectorStrokePx_0( width_1 : f32, dpr_0 : f32) -> f32\n{\n return max(width_1, 1.5f / dpr_0);\n}\n\nfn aaPx_0( dpr_1 : f32) -> f32\n{\n return 1.0f / max(dpr_1, 1.0f);\n}\n\nfn aaHalfPx_0( dpr_2 : f32) -> f32\n{\n return 0.5f * aaPx_0(dpr_2);\n}\n\nfn cubicDirection_0( c_1 : Cubic_0, t_0 : f32) -> vec2<f32>\n{\n var s_0 : f32 = 1.0f - t_0;\n var d_1 : vec2<f32> = vec2<f32>((3.0f * s_0 * s_0)) * (c_1.p1_0 - c_1.p0_0) + vec2<f32>((6.0f * s_0 * t_0)) * (c_1.p2_0 - c_1.p1_0) + vec2<f32>((3.0f * t_0 * t_0)) * (c_1.p3_0 - c_1.p2_0);\n var len_0 : f32 = length(d_1);\n if(len_0 > 9.99999997475242708e-07f)\n {\n return d_1 / vec2<f32>(len_0);\n }\n var chord_0 : vec2<f32> = c_1.p3_0 - c_1.p0_0;\n var chordLen_0 : f32 = length(chord_0);\n var _S11 : vec2<f32>;\n if(chordLen_0 > 9.99999997475242708e-07f)\n {\n _S11 = chord_0 / vec2<f32>(chordLen_0);\n }\n else\n {\n _S11 = vec2<f32>(1.0f, 0.0f);\n }\n return _S11;\n}\n\nfn cubicAt_0( c_2 : Cubic_0, t_1 : f32) -> vec2<f32>\n{\n var s_1 : f32 = 1.0f - t_1;\n var _S12 : f32 = 3.0f * s_1;\n return vec2<f32>((s_1 * s_1 * s_1)) * c_2.p0_0 + vec2<f32>((_S12 * s_1 * t_1)) * c_2.p1_0 + vec2<f32>((_S12 * t_1 * t_1)) * c_2.p2_0 + vec2<f32>((t_1 * t_1 * t_1)) * c_2.p3_0;\n}\n\nfn lengthTo_0( c_3 : Cubic_0, seg_0 : u32) -> f32\n{\n var prev_0 : vec2<f32> = c_3.p0_0;\n var k_0 : u32 = u32(1);\n var total_0 : f32 = 0.0f;\n for(;;)\n {\n if(k_0 <= seg_0)\n {\n }\n else\n {\n break;\n }\n var next_0 : vec2<f32> = cubicAt_0(c_3, f32(k_0) / 48.0f);\n var total_1 : f32 = total_0 + length(next_0 - prev_0);\n var _S13 : u32 = k_0 + u32(1);\n prev_0 = next_0;\n k_0 = _S13;\n total_0 = total_1;\n }\n return total_0;\n}\n\nstruct StripVertex_0\n{\n screen_0 : vec2<f32>,\n across_0 : f32,\n along_0 : f32,\n};\n\nfn curveVertex_0( c_4 : Cubic_0, seg_1 : u32, side_0 : f32, hw_0 : f32, dashed_0 : bool) -> StripVertex_0\n{\n var t_2 : f32 = f32(seg_1) / 48.0f;\n var dir_0 : vec2<f32> = cubicDirection_0(c_4, t_2);\n var v_0 : StripVertex_0;\n var _S14 : f32 = side_0 * hw_0;\n v_0.across_0 = _S14;\n v_0.screen_0 = cubicAt_0(c_4, t_2) + vec2<f32>(- dir_0.y, dir_0.x) * vec2<f32>(_S14);\n var _S15 : f32;\n if(dashed_0)\n {\n _S15 = lengthTo_0(c_4, seg_1);\n }\n else\n {\n _S15 = 0.0f;\n }\n v_0.along_0 = _S15;\n return v_0;\n}\n\nfn armEnd_0( c_5 : Cubic_0, a_0 : u32, strand2_0 : f32, reversed2_0 : bool) -> vec2<f32>\n{\n var _S16 : f32;\n if(reversed2_0)\n {\n _S16 = - strand2_0;\n }\n else\n {\n _S16 = strand2_0;\n }\n var back_0 : f32 = _S16 * - u_0.arrowPx_0;\n if(a_0 == u32(0))\n {\n _S16 = - u_0.arrowPx_0;\n }\n else\n {\n _S16 = u_0.arrowPx_0;\n }\n return c_5.p3_0 + vec2<f32>(back_0, _S16);\n}\n\nfn armCorner_0( c_6 : Cubic_0, a_1 : u32, corner_0 : u32, hw_1 : f32, strand2_1 : f32, reversed2_1 : bool) -> StripVertex_0\n{\n var axis_0 : vec2<f32> = armEnd_0(c_6, a_1, strand2_1, reversed2_1) - c_6.p3_0;\n var _S17 : f32 = max(length(axis_0), 9.99999997475242708e-07f);\n var dir_1 : vec2<f32> = axis_0 / vec2<f32>(_S17);\n var v_1 : StripVertex_0;\n var at_0 : f32;\n if((corner_0 % u32(2)) == u32(0))\n {\n at_0 = - hw_1;\n }\n else\n {\n at_0 = hw_1;\n }\n v_1.across_0 = at_0;\n v_1.along_0 = 0.0f;\n if(corner_0 >= u32(2))\n {\n at_0 = _S17;\n }\n else\n {\n at_0 = 0.0f;\n }\n v_1.screen_0 = c_6.p3_0 + dir_1 * vec2<f32>(at_0) + vec2<f32>(- dir_1.y, dir_1.x) * vec2<f32>(v_1.across_0);\n return v_1;\n}\n\nfn yPxToClipY_0( yPx_0 : f32, canvasHeight_1 : f32) -> f32\n{\n return 1.0f - yPx_0 / canvasHeight_1 * 2.0f;\n}\n\nfn unpackRGBA_0( c_7 : u32) -> vec4<f32>\n{\n return vec4<f32>(f32((((c_7 >> (u32(0)))) & (u32(255)))), f32((((c_7 >> (u32(8)))) & (u32(255)))), f32((((c_7 >> (u32(16)))) & (u32(255)))), f32((((c_7 >> (u32(24)))) & (u32(255))))) / vec4<f32>(255.0f);\n}\n\nstruct VsOut_0\n{\n @builtin(position) position_0 : vec4<f32>,\n @location(0) color_1 : vec4<f32>,\n @location(1) across_1 : f32,\n @location(2) along_1 : f32,\n @interpolate(flat) @location(3) halfWidthPx_0 : f32,\n @interpolate(flat) @location(4) dashed_1 : f32,\n};\n\nstruct vertexInput_0\n{\n @location(0) x_1 : u32,\n @location(1) x2_1 : u32,\n @location(2) x2Region_1 : u32,\n @location(3) row_1 : u32,\n @location(4) row2_1 : u32,\n @location(5) bend_2 : f32,\n @location(6) width_2 : f32,\n @location(7) color_2 : u32,\n @location(8) bits_2 : u32,\n};\n\n@vertex\nfn vs_main( _S18 : vertexInput_0, @builtin(vertex_index) vid_0 : u32) -> VsOut_0\n{\n var _S19 : ConnectorInstance_0 = ConnectorInstance_0( _S18.x_1, _S18.x2_1, _S18.x2Region_1, _S18.row_1, _S18.row2_1, _S18.bend_2, _S18.width_2, _S18.color_2, _S18.bits_2 );\n var placed_0 : bool = (_S18.x2Region_1) < (u_0.regionCount_0);\n var c_8 : Cubic_0 = placeCubic_0(_S19, u_0.regionTable_0[min(_S18.x2Region_1, u32(255))]);\n var halfWidth_0 : f32 = 0.5f * connectorStrokePx_0(_S18.width_2, u_0.devicePixelRatio_0);\n var hw_2 : f32 = halfWidth_0 + aaHalfPx_0(u_0.devicePixelRatio_0);\n var dashed_2 : bool = (((_S18.bits_2) & (u32(16)))) != u32(0);\n var arrow_0 : bool = (((_S18.bits_2) & (u32(32)))) != u32(0);\n var strand2_2 : f32 = 1.0f - 2.0f * bitSet_0(_S18.bits_2, u32(2));\n var reversed2_2 : bool = (u_0.regionTable_0[min(_S18.x2Region_1, u32(255))].w) < 0.0f;\n var v_2 : StripVertex_0;\n var onArm_0 : bool;\n var _S20 : f32;\n if(vid_0 < u32(98))\n {\n var _S21 : u32 = vid_0 / u32(2);\n if((vid_0 % u32(2)) == u32(0))\n {\n _S20 = -1.0f;\n }\n else\n {\n _S20 = 1.0f;\n }\n v_2 = curveVertex_0(c_8, _S21, _S20, hw_2, dashed_2);\n onArm_0 = false;\n }\n else\n {\n var j_0 : u32 = vid_0 - u32(98);\n var a_2 : u32 = j_0 / u32(6);\n var k_1 : u32 = j_0 % u32(6);\n var start_0 : StripVertex_0;\n if(a_2 == u32(0))\n {\n start_0 = curveVertex_0(c_8, u32(48), 1.0f, hw_2, dashed_2);\n }\n else\n {\n if(arrow_0)\n {\n start_0 = armCorner_0(c_8, u32(0), u32(3), hw_2, strand2_2, reversed2_2);\n }\n else\n {\n start_0 = curveVertex_0(c_8, u32(48), 1.0f, hw_2, dashed_2);\n }\n }\n if(k_1 == u32(0))\n {\n onArm_0 = true;\n }\n else\n {\n onArm_0 = !arrow_0;\n }\n if(onArm_0)\n {\n v_2 = start_0;\n onArm_0 = false;\n }\n else\n {\n var _S22 : u32;\n if(k_1 <= u32(2))\n {\n _S22 = u32(0);\n }\n else\n {\n _S22 = k_1 - u32(2);\n }\n v_2 = armCorner_0(c_8, a_2, _S22, hw_2, strand2_2, reversed2_2);\n onArm_0 = true;\n }\n }\n var o_0 : VsOut_0;\n var _S23 : vec4<f32>;\n if(placed_0)\n {\n _S23 = vec4<f32>(v_2.screen_0.x / u_0.canvasWidth_0 * 2.0f - 1.0f, yPxToClipY_0(v_2.screen_0.y, u_0.canvasHeight_0), 0.0f, 1.0f);\n }\n else\n {\n _S23 = vec4<f32>(-2.0f, -2.0f, 0.0f, 1.0f);\n }\n o_0.position_0 = _S23;\n o_0.color_1 = unpackRGBA_0(_S18.color_2);\n o_0.across_1 = v_2.across_0;\n o_0.along_1 = v_2.along_0;\n o_0.halfWidthPx_0 = halfWidth_0;\n if(dashed_2)\n {\n onArm_0 = !onArm_0;\n }\n else\n {\n onArm_0 = false;\n }\n if(onArm_0)\n {\n _S20 = 1.0f;\n }\n else\n {\n _S20 = 0.0f;\n }\n o_0.dashed_1 = _S20;\n return o_0;\n}\n\nfn aaRamp_0( signedInk_0 : f32, widthPx_0 : f32) -> f32\n{\n return clamp(signedInk_0 / widthPx_0 + 0.5f, 0.0f, 1.0f);\n}\n\nfn dashCoverageAt_0( coord_0 : f32, dashPx_1 : f32, gapPx_1 : f32, aaPx_1 : f32) -> f32\n{\n var period_0 : f32 = dashPx_1 + gapPx_1;\n var shifted_0 : f32 = coord_0 + gapPx_1 * 0.5f;\n return aaRamp_0(dashPx_1 * 0.5f - abs(shifted_0 - period_0 * floor(shifted_0 / period_0) - period_0 * 0.5f), aaPx_1);\n}\n\nfn dashCoverage_0( coord_1 : f32, dashPx_2 : f32, gapPx_2 : f32, dpr_3 : f32) -> f32\n{\n return dashCoverageAt_0(coord_1, dashPx_2, gapPx_2, aaPx_0(dpr_3));\n}\n\nfn edgeCoverage_0( signedInkCssPx_0 : f32, dpr_4 : f32) -> f32\n{\n return aaRamp_0(signedInkCssPx_0, aaPx_0(dpr_4));\n}\n\nstruct pixelOutput_0\n{\n @location(0) output_0 : vec4<f32>,\n};\n\nstruct pixelInput_0\n{\n @location(0) color_3 : vec4<f32>,\n @location(1) across_2 : f32,\n @location(2) along_2 : f32,\n @interpolate(flat) @location(3) halfWidthPx_1 : f32,\n @interpolate(flat) @location(4) dashed_3 : f32,\n};\n\n@fragment\nfn fs_main( _S24 : pixelInput_0, @builtin(position) position_1 : vec4<f32>) -> pixelOutput_0\n{\n var _S25 : bool;\n if((_S24.dashed_3) > 0.5f)\n {\n _S25 = (u_0.dashPx_0) > 0.0f;\n }\n else\n {\n _S25 = false;\n }\n var dash_0 : f32;\n if(_S25)\n {\n dash_0 = dashCoverage_0(_S24.along_2, u_0.dashPx_0, u_0.gapPx_0, u_0.devicePixelRatio_0);\n }\n else\n {\n dash_0 = 1.0f;\n }\n var _S26 : pixelOutput_0 = pixelOutput_0( vec4<f32>(_S24.color_3.xyz, _S24.color_3.w * (edgeCoverage_0(_S24.halfWidthPx_1 - abs(_S24.across_2), u_0.devicePixelRatio_0) * dash_0)) );\n return _S26;\n}\n\n"
|
|
@@ -95,16 +95,14 @@ public struct CoverageBandUniforms {
|
|
|
95
95
|
};
|
|
96
96
|
|
|
97
97
|
// Coverage-band clip indicator triangle, in CSS px: half-width and height.
|
|
98
|
-
//
|
|
99
|
-
//
|
|
100
|
-
//
|
|
101
|
-
//
|
|
102
|
-
// cross-package copy can't drift either.
|
|
98
|
+
// coverageInterbase.slang hangs its bars directly below one, and the point
|
|
99
|
+
// mark that draws it reads the size from `@jbrowse/alignments-core`, which the
|
|
100
|
+
// `consts-out` directive above generates from these declarations, so the
|
|
101
|
+
// cross-package copy can't drift.
|
|
103
102
|
public static const float TRIANGLE_HW = 3.5;
|
|
104
103
|
public static const float TRIANGLE_H = 4.5;
|
|
105
104
|
|
|
106
|
-
// Shared vertex output for the band's
|
|
107
|
-
// pass carries a barycentric varying as well and declares its own.
|
|
105
|
+
// Shared vertex output for the band's solid-fill passes.
|
|
108
106
|
public struct CoverageVsOut {
|
|
109
107
|
public float4 position : SV_Position;
|
|
110
108
|
public float4 color : COLOR0;
|
|
@@ -295,11 +293,11 @@ public float3 covSnpColor(float ct, CoverageBandUniforms u) {
|
|
|
295
293
|
}
|
|
296
294
|
}
|
|
297
295
|
|
|
298
|
-
//
|
|
299
|
-
//
|
|
300
|
-
//
|
|
301
|
-
//
|
|
302
|
-
//
|
|
296
|
+
// The interbase histogram's fill: 1=insertion 2=softclip 3=hardclip, with
|
|
297
|
+
// anything else taking the insertion color — the same fallback
|
|
298
|
+
// `clipKindColor` takes for an out-of-range kind. Nothing reaches that arm
|
|
299
|
+
// today (the interbase compute only ever emits 1..3), which is exactly why the
|
|
300
|
+
// two spellings disagreeing would be invisible.
|
|
303
301
|
public float3 covClipKindColor(float ct, CoverageBandUniforms u) {
|
|
304
302
|
int ci = int(ct);
|
|
305
303
|
if (ci == 2) { return unpackRGBA(u.colorSoftclipIndicator).xyz; }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// AUTO-GENERATED by packages/shader-tools/src/shader-codegen from coverageInterbase.slang.
|
|
2
2
|
// Do not edit. Run `pnpm gen:shaders` to regenerate.
|
|
3
3
|
|
|
4
|
-
export const GLSL_VERTEX = "#version 300 es\nprecision highp float;\nprecision highp int;\nstruct CoverageBandUniforms_0\n{\n float bpHi_0;\n float bpLo_0;\n float bpLen_0;\n float hpZero_0;\n float canvasW_0;\n float canvasH_0;\n float covHeight_0;\n float covYOffset_0;\n float covTop_0;\n float regionMaxDepth_0;\n float depthDomainMax_0;\n float depthDomainMin_0;\n float coverageSymlogConstant_0;\n float binSize_0;\n float interbaseHeight_0;\n float snpMinFreq_0;\n float reversed_0;\n int coverageScaleType_0;\n uint colorCoverage_0;\n uint colorBaseA_0;\n uint colorBaseC_0;\n uint colorBaseG_0;\n uint colorBaseT_0;\n uint colorBaseN_0;\n uint colorInsertionIndicator_0;\n uint colorSoftclipIndicator_0;\n uint colorHardclipIndicator_0;\n};\n\n\nlayout(std140) uniform Uniforms\n{\n float bpHi_0;\n float bpLo_0;\n float bpLen_0;\n float hpZero_0;\n float canvasW_0;\n float canvasH_0;\n float covHeight_0;\n float covYOffset_0;\n float covTop_0;\n float regionMaxDepth_0;\n float depthDomainMax_0;\n float depthDomainMin_0;\n float coverageSymlogConstant_0;\n float binSize_0;\n float interbaseHeight_0;\n float snpMinFreq_0;\n float reversed_0;\n int coverageScaleType_0;\n uint colorCoverage_0;\n uint colorBaseA_0;\n uint colorBaseC_0;\n uint colorBaseG_0;\n uint colorBaseT_0;\n uint colorBaseN_0;\n uint colorInsertionIndicator_0;\n uint colorSoftclipIndicator_0;\n uint colorHardclipIndicator_0;\n}u_0;\n\nvec2 quadLocal_0(uint vid_0)\n{\n\n uint v_0 = vid_0 % 6U;\n\n bool _S1 = v_0 == 0U;\n\n bool _S2;\n\n if(_S1)\n {\n\n _S2 = true;\n\n }\n else\n {\n\n _S2 = v_0 == 2U;\n\n }\n\n if(_S2)\n {\n\n _S2 = true;\n\n }\n else\n {\n\n _S2 = v_0 == 3U;\n\n }\n\n float _S3;\n\n if(_S2)\n {\n\n _S3 = 0.0;\n\n }\n else\n {\n\n _S3 = 1.0;\n\n }\n if(_S1)\n {\n\n _S2 = true;\n\n }\n else\n {\n\n _S2 = v_0 == 1U;\n\n }\n\n if(_S2)\n {\n\n _S2 = true;\n\n }\n else\n {\n\n _S2 = v_0 == 4U;\n\n }\n\n float _S4;\n\n if(_S2)\n {\n\n _S4 = 0.0;\n\n }\n else\n {\n\n _S4 = 1.0;\n\n }\n\n return vec2(_S3, _S4);\n}\n\n\nvec2 hpSplitUint_0(uint value_0)\n{\n\n uint lo_0 = value_0 & 4095U;\n\n return vec2(float(value_0 - lo_0), float(lo_0));\n}\n\n\nfloat hpToClipX_0(vec2 splitPos_0, vec3 bpRange_0, float hpZero_1)\n{\n\n float floorBp_0 = -3.00000000549775576e+38 + hpZero_1;\n float step_0 = 2.0 / bpRange_0.z;\n\n\n return dot(vec3(-1.0, max(splitPos_0.x - bpRange_0.x, floorBp_0), max(splitPos_0.y - bpRange_0.y, floorBp_0)), vec3(1.0, step_0, step_0));\n}\n\n\nfloat covBpToClipX_0(uint bp_0, CoverageBandUniforms_0 u_1)\n{\n\n return hpToClipX_0(hpSplitUint_0(bp_0), vec3(u_1.bpHi_0, u_1.bpLo_0, u_1.bpLen_0), u_1.hpZero_0);\n}\n\
|
|
4
|
+
export const GLSL_VERTEX = "#version 300 es\nprecision highp float;\nprecision highp int;\nstruct CoverageBandUniforms_0\n{\n float bpHi_0;\n float bpLo_0;\n float bpLen_0;\n float hpZero_0;\n float canvasW_0;\n float canvasH_0;\n float covHeight_0;\n float covYOffset_0;\n float covTop_0;\n float regionMaxDepth_0;\n float depthDomainMax_0;\n float depthDomainMin_0;\n float coverageSymlogConstant_0;\n float binSize_0;\n float interbaseHeight_0;\n float snpMinFreq_0;\n float reversed_0;\n int coverageScaleType_0;\n uint colorCoverage_0;\n uint colorBaseA_0;\n uint colorBaseC_0;\n uint colorBaseG_0;\n uint colorBaseT_0;\n uint colorBaseN_0;\n uint colorInsertionIndicator_0;\n uint colorSoftclipIndicator_0;\n uint colorHardclipIndicator_0;\n};\n\n\nlayout(std140) uniform Uniforms\n{\n float bpHi_0;\n float bpLo_0;\n float bpLen_0;\n float hpZero_0;\n float canvasW_0;\n float canvasH_0;\n float covHeight_0;\n float covYOffset_0;\n float covTop_0;\n float regionMaxDepth_0;\n float depthDomainMax_0;\n float depthDomainMin_0;\n float coverageSymlogConstant_0;\n float binSize_0;\n float interbaseHeight_0;\n float snpMinFreq_0;\n float reversed_0;\n int coverageScaleType_0;\n uint colorCoverage_0;\n uint colorBaseA_0;\n uint colorBaseC_0;\n uint colorBaseG_0;\n uint colorBaseT_0;\n uint colorBaseN_0;\n uint colorInsertionIndicator_0;\n uint colorSoftclipIndicator_0;\n uint colorHardclipIndicator_0;\n}u_0;\n\nvec2 quadLocal_0(uint vid_0)\n{\n\n uint v_0 = vid_0 % 6U;\n\n bool _S1 = v_0 == 0U;\n\n bool _S2;\n\n if(_S1)\n {\n\n _S2 = true;\n\n }\n else\n {\n\n _S2 = v_0 == 2U;\n\n }\n\n if(_S2)\n {\n\n _S2 = true;\n\n }\n else\n {\n\n _S2 = v_0 == 3U;\n\n }\n\n float _S3;\n\n if(_S2)\n {\n\n _S3 = 0.0;\n\n }\n else\n {\n\n _S3 = 1.0;\n\n }\n if(_S1)\n {\n\n _S2 = true;\n\n }\n else\n {\n\n _S2 = v_0 == 1U;\n\n }\n\n if(_S2)\n {\n\n _S2 = true;\n\n }\n else\n {\n\n _S2 = v_0 == 4U;\n\n }\n\n float _S4;\n\n if(_S2)\n {\n\n _S4 = 0.0;\n\n }\n else\n {\n\n _S4 = 1.0;\n\n }\n\n return vec2(_S3, _S4);\n}\n\n\nvec2 hpSplitUint_0(uint value_0)\n{\n\n uint lo_0 = value_0 & 4095U;\n\n return vec2(float(value_0 - lo_0), float(lo_0));\n}\n\n\nfloat hpToClipX_0(vec2 splitPos_0, vec3 bpRange_0, float hpZero_1)\n{\n\n float floorBp_0 = -3.00000000549775576e+38 + hpZero_1;\n float step_0 = 2.0 / bpRange_0.z;\n\n\n return dot(vec3(-1.0, max(splitPos_0.x - bpRange_0.x, floorBp_0), max(splitPos_0.y - bpRange_0.y, floorBp_0)), vec3(1.0, step_0, step_0));\n}\n\n\nfloat covBpToClipX_0(uint bp_0, CoverageBandUniforms_0 u_1)\n{\n\n return hpToClipX_0(hpSplitUint_0(bp_0), vec3(u_1.bpHi_0, u_1.bpLo_0, u_1.bpLen_0), u_1.hpZero_0);\n}\n\nfloat covFlipX_0(float x_0, CoverageBandUniforms_0 u_2)\n{\n\n return mix(x_0, - x_0, u_2.reversed_0);\n}\n\n\nfloat clipXToPx_0(float clipX_0, float canvasWidth_0)\n{\n\n return (clipX_0 + 1.0) * 0.5 * canvasWidth_0;\n}\n\n\nfloat interbaseBarLeftPx_0(float centerPx_0)\n{\n\n return floor(centerPx_0);\n}\n\n\nfloat pxToClipX_0(float xPx_0, float canvasWidth_1)\n{\n\n return xPx_0 / canvasWidth_1 * 2.0 - 1.0;\n}\n\n\nfloat pxToClipLen_0(float px_0, float size_0)\n{\n\n return px_0 * 2.0 / size_0;\n}\n\n\nfloat interbaseEdgePx_0(float offset_0, float interbaseHeight_1)\n{\n\n return floor(4.5) + floor(offset_0 * interbaseHeight_1 + 0.5);\n}\n\n\nfloat yPxToClipY_0(float yPx_0, float canvasHeight_0)\n{\n\n return 1.0 - yPx_0 / canvasHeight_0 * 2.0;\n}\n\n\nfloat covAreaTop_0(CoverageBandUniforms_0 u_3)\n{\n\n return yPxToClipY_0(u_3.covTop_0, u_3.canvasH_0);\n}\n\n\nvec4 unpackRGBA_0(uint c_0)\n{\n\n return vec4(float((c_0 >> 0U) & 255U), float((c_0 >> 8U) & 255U), float((c_0 >> 16U) & 255U), float((c_0 >> 24U) & 255U)) / 255.0;\n}\n\n\nvec3 covClipKindColor_0(float ct_0, CoverageBandUniforms_0 u_4)\n{\n\n int ci_0 = int(ct_0);\n if(ci_0 == 2)\n {\n\n return unpackRGBA_0(u_4.colorSoftclipIndicator_0).xyz;\n }\n\n if(ci_0 == 3)\n {\n\n return unpackRGBA_0(u_4.colorHardclipIndicator_0).xyz;\n }\n\n return unpackRGBA_0(u_4.colorInsertionIndicator_0).xyz;\n}\n\n\nout vec4 v_color;\n\n\nlayout(location = 0)\nin uint a_position;\n\n\nlayout(location = 1)\nin float a_yOffset;\n\n\nlayout(location = 2)\nin float a_segHeight;\n\n\nlayout(location = 3)\nin float a_colorType;\n\n\nstruct CoverageVsOut_0\n{\n vec4 position_0;\n vec4 color_0;\n};\n\n\nvoid main()\n{\n vec2 local_0 = quadLocal_0(uint(gl_VertexID));\n\n CoverageBandUniforms_0 _S5 = CoverageBandUniforms_0(u_0.bpHi_0, u_0.bpLo_0, u_0.bpLen_0, u_0.hpZero_0, u_0.canvasW_0, u_0.canvasH_0, u_0.covHeight_0, u_0.covYOffset_0, u_0.covTop_0, u_0.regionMaxDepth_0, u_0.depthDomainMax_0, u_0.depthDomainMin_0, u_0.coverageSymlogConstant_0, u_0.binSize_0, u_0.interbaseHeight_0, u_0.snpMinFreq_0, u_0.reversed_0, u_0.coverageScaleType_0, u_0.colorCoverage_0, u_0.colorBaseA_0, u_0.colorBaseC_0, u_0.colorBaseG_0, u_0.colorBaseT_0, u_0.colorBaseN_0, u_0.colorInsertionIndicator_0, u_0.colorSoftclipIndicator_0, u_0.colorHardclipIndicator_0);\n\n\n float x0_0 = pxToClipX_0(interbaseBarLeftPx_0(clipXToPx_0(covFlipX_0(covBpToClipX_0(a_position, _S5), _S5), u_0.canvasW_0)), u_0.canvasW_0);\n\n float _S6 = covAreaTop_0(_S5);\n\n CoverageVsOut_0 o_0;\n\n o_0.position_0 = vec4(mix(x0_0, x0_0 + pxToClipLen_0(1.0, u_0.canvasW_0), local_0.x), mix(_S6 - pxToClipLen_0(interbaseEdgePx_0(a_yOffset + a_segHeight, u_0.interbaseHeight_0), u_0.canvasH_0), _S6 - pxToClipLen_0(interbaseEdgePx_0(a_yOffset, u_0.interbaseHeight_0), u_0.canvasH_0), local_0.y), 0.0, 1.0);\n o_0.color_0 = vec4(covClipKindColor_0(a_colorType, _S5), 1.0);\n CoverageVsOut_0 _S7 = o_0;\n\n gl_Position = o_0.position_0;\n\n v_color = _S7.color_0;\n\n return;\n}\n\n"
|
|
5
5
|
|
|
6
6
|
export const GLSL_FRAGMENT = "#version 300 es\nprecision highp float;\nprecision highp int;\nlayout(location = 0)\nout vec4 entryPointParam_fs_main_0;\n\n\nin vec4 v_color;\n\n\nvoid main()\n{\n\n entryPointParam_fs_main_0 = v_color;\n\n return;\n}\n\n"
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// Interbase histogram: slim 1px-wide bars indicating insertion / softclip /
|
|
2
|
-
// hardclip density across the coverage band, hanging from
|
|
3
|
-
//
|
|
2
|
+
// hardclip density across the coverage band, hanging from the indicator
|
|
3
|
+
// triangles' tip row. See coverageBand.slang.
|
|
4
4
|
//! targets: wgsl, glsl
|
|
5
5
|
//! layout-out: packages/alignments-core/src/interbaseHistogramLayout.generated.ts
|
|
6
|
-
//! js-export: interbaseEdgePx
|
|
6
|
+
//! js-export: interbaseEdgePx, interbaseBarLeftPx
|
|
7
7
|
//! js-export-out: packages/alignments-core/src/interbaseEdge.generated.ts
|
|
8
8
|
|
|
9
9
|
import coverageBand;
|
|
@@ -20,20 +20,24 @@ struct Instance {
|
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
// Screen-pixel Y of one edge of a bar, `offset` bars' worth of stacked height
|
|
23
|
-
// below the coverage-area top.
|
|
23
|
+
// below the coverage-area top, snapped to a whole pixel. The backends disagree
|
|
24
|
+
// on a half-covered row: Canvas2D saturates the ~40 bars stacked in one column
|
|
25
|
+
// at 40bp/px to opaque, while this pass resolves their union once and stays at
|
|
26
|
+
// 50%. drawInterbaseSegments `//! js-export`s this so both sides round alike.
|
|
24
27
|
//
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
// half-covered row: Canvas2D composites each of the ~40 bars that stack in one
|
|
29
|
-
// column at 40bp/px separately and saturates to opaque, while this pass resolves
|
|
30
|
-
// the union coverage once and stays at 50%. That read as a full row of 128,0,128
|
|
31
|
-
// against 191,127,191 and was the largest remaining cross-backend divergence.
|
|
32
|
-
// Whole-pixel edges leave no partial coverage to disagree about — which only
|
|
33
|
-
// holds while both sides round the same numbers the same way, so
|
|
34
|
-
// drawInterbaseSegments `//! js-export`s this rather than repeating it.
|
|
28
|
+
// The bar starts on the row holding the triangle's tip, floor(TRIANGLE_H),
|
|
29
|
+
// rather than the row after it: the tip covers only a sliver of that row, so
|
|
30
|
+
// starting below it leaves a visible gap between triangle and bar.
|
|
35
31
|
float interbaseEdgePx(float offset, float interbaseHeight) {
|
|
36
|
-
return floor(TRIANGLE_H + offset * interbaseHeight + 0.5);
|
|
32
|
+
return floor(TRIANGLE_H) + floor(offset * interbaseHeight + 0.5);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Left edge of the 1px bar centred on `centerPx`, snapped to the pixel column
|
|
36
|
+
// whose centre is nearest. Unsnapped, the bar straddles two columns: Canvas2D
|
|
37
|
+
// paints both at partial alpha while the GPU fills one solid, so the bar read
|
|
38
|
+
// paler than its triangle and the backends disagreed.
|
|
39
|
+
float interbaseBarLeftPx(float centerPx) {
|
|
40
|
+
return floor(centerPx);
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
[shader("vertex")]
|
|
@@ -41,18 +45,17 @@ CoverageVsOut vs_main(Instance inst, uint vid : SV_VertexID) {
|
|
|
41
45
|
CoverageVsOut o;
|
|
42
46
|
float2 local = quadLocal(vid);
|
|
43
47
|
|
|
44
|
-
float cx = covBpToClipX(inst.position, u);
|
|
45
|
-
float
|
|
48
|
+
float cx = covFlipX(covBpToClipX(inst.position, u), u);
|
|
49
|
+
float x0 = pxToClipX(interbaseBarLeftPx(clipXToPx(cx, u.canvasW)), u.canvasW);
|
|
50
|
+
float x1 = x0 + pxToClipLen(1.0, u.canvasW);
|
|
46
51
|
|
|
47
|
-
//
|
|
48
|
-
// triangle row (TRIANGLE_H is the same const coverageIndicator.slang draws
|
|
49
|
-
// with). Both edges snap to whole pixels BEFORE the clip-space conversion.
|
|
52
|
+
// Both edges snap to whole pixels BEFORE the clip-space conversion.
|
|
50
53
|
float topPx = interbaseEdgePx(inst.yOffset, u.interbaseHeight);
|
|
51
54
|
float botPx = interbaseEdgePx(inst.yOffset + inst.segHeight, u.interbaseHeight);
|
|
52
55
|
float sTop = covAreaTop(u) - pxToClipLen(topPx, u.canvasH);
|
|
53
56
|
float sBot = covAreaTop(u) - pxToClipLen(botPx, u.canvasH);
|
|
54
57
|
|
|
55
|
-
o.position =
|
|
58
|
+
o.position = float4(lerp(x0, x1, local.x), lerp(sBot, sTop, local.y), 0.0, 1.0);
|
|
56
59
|
o.color = float4(covClipKindColor(inst.colorType, u), 1.0);
|
|
57
60
|
return o;
|
|
58
61
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// AUTO-GENERATED by packages/shader-tools/src/shader-codegen from coverageInterbase.slang.
|
|
2
2
|
// Do not edit. Run `pnpm gen:shaders` to regenerate.
|
|
3
3
|
|
|
4
|
-
export const WGSL_SOURCE = "struct CoverageBandUniforms_std140_0\n{\n @align(16) bpHi_0 : f32,\n @align(4) bpLo_0 : f32,\n @align(8) bpLen_0 : f32,\n @align(4) hpZero_0 : f32,\n @align(16) canvasW_0 : f32,\n @align(4) canvasH_0 : f32,\n @align(8) covHeight_0 : f32,\n @align(4) covYOffset_0 : f32,\n @align(16) covTop_0 : f32,\n @align(4) regionMaxDepth_0 : f32,\n @align(8) depthDomainMax_0 : f32,\n @align(4) depthDomainMin_0 : f32,\n @align(16) coverageSymlogConstant_0 : f32,\n @align(4) binSize_0 : f32,\n @align(8) interbaseHeight_0 : f32,\n @align(4) snpMinFreq_0 : f32,\n @align(16) reversed_0 : f32,\n @align(4) coverageScaleType_0 : i32,\n @align(8) colorCoverage_0 : u32,\n @align(4) colorBaseA_0 : u32,\n @align(16) colorBaseC_0 : u32,\n @align(4) colorBaseG_0 : u32,\n @align(8) colorBaseT_0 : u32,\n @align(4) colorBaseN_0 : u32,\n @align(16) colorInsertionIndicator_0 : u32,\n @align(4) colorSoftclipIndicator_0 : u32,\n @align(8) colorHardclipIndicator_0 : u32,\n};\n\n@binding(1) @group(0) var<uniform> u_0 : CoverageBandUniforms_std140_0;\nfn quadLocal_0( vid_0 : u32) -> vec2<f32>\n{\n var v_0 : u32 = vid_0 % u32(6);\n var _S1 : bool = v_0 == u32(0);\n var _S2 : bool;\n if(_S1)\n {\n _S2 = true;\n }\n else\n {\n _S2 = v_0 == u32(2);\n }\n if(_S2)\n {\n _S2 = true;\n }\n else\n {\n _S2 = v_0 == u32(3);\n }\n var _S3 : f32;\n if(_S2)\n {\n _S3 = 0.0f;\n }\n else\n {\n _S3 = 1.0f;\n }\n if(_S1)\n {\n _S2 = true;\n }\n else\n {\n _S2 = v_0 == u32(1);\n }\n if(_S2)\n {\n _S2 = true;\n }\n else\n {\n _S2 = v_0 == u32(4);\n }\n var _S4 : f32;\n if(_S2)\n {\n _S4 = 0.0f;\n }\n else\n {\n _S4 = 1.0f;\n }\n return vec2<f32>(_S3, _S4);\n}\n\nfn hpSplitUint_0( value_0 : u32) -> vec2<f32>\n{\n var lo_0 : u32 = (value_0 & (u32(4095)));\n return vec2<f32>(f32(value_0 - lo_0), f32(lo_0));\n}\n\nfn hpToClipX_0( splitPos_0 : vec2<f32>, bpRange_0 : vec3<f32>, hpZero_1 : f32) -> f32\n{\n var floorBp_0 : f32 = -3.00000000549775576e+38f + hpZero_1;\n var step_0 : f32 = 2.0f / bpRange_0.z;\n return dot(vec3<f32>(-1.0f, max(splitPos_0.x - bpRange_0.x, floorBp_0), max(splitPos_0.y - bpRange_0.y, floorBp_0)), vec3<f32>(1.0f, step_0, step_0));\n}\n\nfn covBpToClipX_0( bp_0 : u32, u_1 : ptr<function, CoverageBandUniforms_std140_0>) -> f32\n{\n return hpToClipX_0(hpSplitUint_0(bp_0), vec3<f32>((*u_1).bpHi_0, (*u_1).bpLo_0, (*u_1).bpLen_0), (*u_1).hpZero_0);\n}\n\nfn
|
|
4
|
+
export const WGSL_SOURCE = "struct CoverageBandUniforms_std140_0\n{\n @align(16) bpHi_0 : f32,\n @align(4) bpLo_0 : f32,\n @align(8) bpLen_0 : f32,\n @align(4) hpZero_0 : f32,\n @align(16) canvasW_0 : f32,\n @align(4) canvasH_0 : f32,\n @align(8) covHeight_0 : f32,\n @align(4) covYOffset_0 : f32,\n @align(16) covTop_0 : f32,\n @align(4) regionMaxDepth_0 : f32,\n @align(8) depthDomainMax_0 : f32,\n @align(4) depthDomainMin_0 : f32,\n @align(16) coverageSymlogConstant_0 : f32,\n @align(4) binSize_0 : f32,\n @align(8) interbaseHeight_0 : f32,\n @align(4) snpMinFreq_0 : f32,\n @align(16) reversed_0 : f32,\n @align(4) coverageScaleType_0 : i32,\n @align(8) colorCoverage_0 : u32,\n @align(4) colorBaseA_0 : u32,\n @align(16) colorBaseC_0 : u32,\n @align(4) colorBaseG_0 : u32,\n @align(8) colorBaseT_0 : u32,\n @align(4) colorBaseN_0 : u32,\n @align(16) colorInsertionIndicator_0 : u32,\n @align(4) colorSoftclipIndicator_0 : u32,\n @align(8) colorHardclipIndicator_0 : u32,\n};\n\n@binding(1) @group(0) var<uniform> u_0 : CoverageBandUniforms_std140_0;\nfn quadLocal_0( vid_0 : u32) -> vec2<f32>\n{\n var v_0 : u32 = vid_0 % u32(6);\n var _S1 : bool = v_0 == u32(0);\n var _S2 : bool;\n if(_S1)\n {\n _S2 = true;\n }\n else\n {\n _S2 = v_0 == u32(2);\n }\n if(_S2)\n {\n _S2 = true;\n }\n else\n {\n _S2 = v_0 == u32(3);\n }\n var _S3 : f32;\n if(_S2)\n {\n _S3 = 0.0f;\n }\n else\n {\n _S3 = 1.0f;\n }\n if(_S1)\n {\n _S2 = true;\n }\n else\n {\n _S2 = v_0 == u32(1);\n }\n if(_S2)\n {\n _S2 = true;\n }\n else\n {\n _S2 = v_0 == u32(4);\n }\n var _S4 : f32;\n if(_S2)\n {\n _S4 = 0.0f;\n }\n else\n {\n _S4 = 1.0f;\n }\n return vec2<f32>(_S3, _S4);\n}\n\nfn hpSplitUint_0( value_0 : u32) -> vec2<f32>\n{\n var lo_0 : u32 = (value_0 & (u32(4095)));\n return vec2<f32>(f32(value_0 - lo_0), f32(lo_0));\n}\n\nfn hpToClipX_0( splitPos_0 : vec2<f32>, bpRange_0 : vec3<f32>, hpZero_1 : f32) -> f32\n{\n var floorBp_0 : f32 = -3.00000000549775576e+38f + hpZero_1;\n var step_0 : f32 = 2.0f / bpRange_0.z;\n return dot(vec3<f32>(-1.0f, max(splitPos_0.x - bpRange_0.x, floorBp_0), max(splitPos_0.y - bpRange_0.y, floorBp_0)), vec3<f32>(1.0f, step_0, step_0));\n}\n\nfn covBpToClipX_0( bp_0 : u32, u_1 : ptr<function, CoverageBandUniforms_std140_0>) -> f32\n{\n return hpToClipX_0(hpSplitUint_0(bp_0), vec3<f32>((*u_1).bpHi_0, (*u_1).bpLo_0, (*u_1).bpLen_0), (*u_1).hpZero_0);\n}\n\nfn covFlipX_0( x_0 : f32, u_2 : ptr<function, CoverageBandUniforms_std140_0>) -> f32\n{\n return mix(x_0, - x_0, (*u_2).reversed_0);\n}\n\nfn clipXToPx_0( clipX_0 : f32, canvasWidth_0 : f32) -> f32\n{\n return (clipX_0 + 1.0f) * 0.5f * canvasWidth_0;\n}\n\nfn interbaseBarLeftPx_0( centerPx_0 : f32) -> f32\n{\n return floor(centerPx_0);\n}\n\nfn pxToClipX_0( xPx_0 : f32, canvasWidth_1 : f32) -> f32\n{\n return xPx_0 / canvasWidth_1 * 2.0f - 1.0f;\n}\n\nfn pxToClipLen_0( px_0 : f32, size_0 : f32) -> f32\n{\n return px_0 * 2.0f / size_0;\n}\n\nfn interbaseEdgePx_0( offset_0 : f32, interbaseHeight_1 : f32) -> f32\n{\n return floor(4.5f) + floor(offset_0 * interbaseHeight_1 + 0.5f);\n}\n\nfn yPxToClipY_0( yPx_0 : f32, canvasHeight_0 : f32) -> f32\n{\n return 1.0f - yPx_0 / canvasHeight_0 * 2.0f;\n}\n\nfn covAreaTop_0( u_3 : ptr<function, CoverageBandUniforms_std140_0>) -> f32\n{\n return yPxToClipY_0((*u_3).covTop_0, (*u_3).canvasH_0);\n}\n\nfn unpackRGBA_0( c_0 : u32) -> vec4<f32>\n{\n return vec4<f32>(f32((((c_0 >> (u32(0)))) & (u32(255)))), f32((((c_0 >> (u32(8)))) & (u32(255)))), f32((((c_0 >> (u32(16)))) & (u32(255)))), f32((((c_0 >> (u32(24)))) & (u32(255))))) / vec4<f32>(255.0f);\n}\n\nfn covClipKindColor_0( ct_0 : f32, u_4 : ptr<function, CoverageBandUniforms_std140_0>) -> vec3<f32>\n{\n var ci_0 : i32 = i32(ct_0);\n if(ci_0 == i32(2))\n {\n return unpackRGBA_0((*u_4).colorSoftclipIndicator_0).xyz;\n }\n if(ci_0 == i32(3))\n {\n return unpackRGBA_0((*u_4).colorHardclipIndicator_0).xyz;\n }\n return unpackRGBA_0((*u_4).colorInsertionIndicator_0).xyz;\n}\n\nstruct CoverageVsOut_0\n{\n @builtin(position) position_0 : vec4<f32>,\n @location(0) color_0 : vec4<f32>,\n};\n\nstruct vertexInput_0\n{\n @location(0) position_1 : u32,\n @location(1) yOffset_0 : f32,\n @location(2) segHeight_0 : f32,\n @location(3) colorType_0 : f32,\n};\n\n@vertex\nfn vs_main( _S5 : vertexInput_0, @builtin(vertex_index) vid_1 : u32) -> CoverageVsOut_0\n{\n var local_0 : vec2<f32> = quadLocal_0(vid_1);\n var _S6 : CoverageBandUniforms_std140_0 = u_0;\n var _S7 : f32 = covBpToClipX_0(_S5.position_1, &(_S6));\n var _S8 : f32 = covFlipX_0(_S7, &(_S6));\n var x0_0 : f32 = pxToClipX_0(interbaseBarLeftPx_0(clipXToPx_0(_S8, u_0.canvasW_0)), u_0.canvasW_0);\n var x1_0 : f32 = x0_0 + pxToClipLen_0(1.0f, u_0.canvasW_0);\n var topPx_0 : f32 = interbaseEdgePx_0(_S5.yOffset_0, u_0.interbaseHeight_0);\n var botPx_0 : f32 = interbaseEdgePx_0(_S5.yOffset_0 + _S5.segHeight_0, u_0.interbaseHeight_0);\n var _S9 : f32 = covAreaTop_0(&(_S6));\n var o_0 : CoverageVsOut_0;\n o_0.position_0 = vec4<f32>(mix(x0_0, x1_0, local_0.x), mix(_S9 - pxToClipLen_0(botPx_0, u_0.canvasH_0), _S9 - pxToClipLen_0(topPx_0, u_0.canvasH_0), local_0.y), 0.0f, 1.0f);\n var _S10 : vec3<f32> = covClipKindColor_0(_S5.colorType_0, &(_S6));\n o_0.color_0 = vec4<f32>(_S10, 1.0f);\n return o_0;\n}\n\nstruct pixelOutput_0\n{\n @location(0) output_0 : vec4<f32>,\n};\n\nstruct pixelInput_0\n{\n @location(0) color_1 : vec4<f32>,\n};\n\n@fragment\nfn fs_main( _S11 : pixelInput_0, @builtin(position) position_2 : vec4<f32>) -> pixelOutput_0\n{\n var _S12 : pixelOutput_0 = pixelOutput_0( _S11.color_1 );\n return _S12;\n}\n\n"
|
|
@@ -15,7 +15,7 @@ public static const uint VERTS_PER_INSTANCE = 6u;
|
|
|
15
15
|
// via covNormalizeDepth, so each segment is a linear slice of a possibly
|
|
16
16
|
// log-scaled bar without any per-position un-mixing at draw time.
|
|
17
17
|
//
|
|
18
|
-
// Which means that on a LOG axis the
|
|
18
|
+
// Which means that on a LOG axis the colored fraction reads as the allele
|
|
19
19
|
// proportion and not as a count off the y-axis: a 50% allele is half the bar
|
|
20
20
|
// whatever the scale, so its top edge does not land on the depth the axis would
|
|
21
21
|
// read there. Deliberate — the alternative bakes the axis into the buffer and
|