@jbrowse/render-core 5.0.0-beta.7 → 5.0.0-beta.9
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/RenderCanvas.d.ts +2 -2
- package/esm/RenderLifecycleMixin.d.ts +7 -6
- package/esm/RenderLifecycleMixin.js +7 -6
- package/esm/canvas2dUtils.d.ts +58 -17
- package/esm/canvas2dUtils.js +82 -30
- package/esm/computePipeline.d.ts +4 -3
- package/esm/computePipeline.js +21 -14
- package/esm/coverageBand.d.ts +3 -3
- package/esm/coverageBand.js +2 -2
- package/esm/coverageBandBuffers.d.ts +2 -3
- package/esm/createRenderingBackend.d.ts +1 -1
- package/esm/displayPhase.d.ts +79 -109
- package/esm/displayPhase.js +42 -83
- package/esm/gpuDevice.d.ts +11 -10
- package/esm/gpuDevice.js +10 -11
- package/esm/graphicsCapabilities.d.ts +6 -7
- package/esm/graphicsCapabilities.js +3 -4
- package/esm/hal/createHal.js +1 -1
- package/esm/hal/deviceGpuCache.d.ts +25 -30
- package/esm/hal/deviceGpuCache.js +85 -97
- package/esm/hal/index.d.ts +2 -2
- package/esm/hal/index.js +1 -1
- package/esm/hal/mockHal.d.ts +8 -6
- package/esm/hal/mockHal.js +7 -2
- package/esm/hal/passIds.d.ts +8 -7
- package/esm/hal/passIds.js +11 -10
- package/esm/hal/types.d.ts +28 -12
- package/esm/hal/webgl2Hal.d.ts +11 -3
- package/esm/hal/webgl2Hal.js +116 -145
- package/esm/hal/webgpuHal.d.ts +8 -8
- package/esm/hal/webgpuHal.js +97 -124
- package/esm/instancePass.d.ts +2 -1
- package/esm/mapUploadSync.d.ts +2 -2
- package/esm/mapUploadSync.js +2 -2
- package/esm/marks/barMark.d.ts +6 -3
- package/esm/marks/barMark.js +19 -13
- package/esm/marks/drawAgainstHit.d.ts +58 -39
- package/esm/marks/drawAgainstHit.js +136 -96
- package/esm/marks/glyphPaint.d.ts +14 -2
- package/esm/marks/glyphPaint.js +16 -2
- package/esm/marks/index.d.ts +4 -2
- package/esm/marks/index.js +3 -2
- package/esm/marks/markBackend.d.ts +2 -2
- package/esm/marks/markBackend.js +2 -2
- package/esm/marks/markHit.d.ts +2 -2
- package/esm/marks/markHit.js +2 -2
- package/esm/marks/markPlan.d.ts +2 -2
- package/esm/marks/markPlan.js +2 -2
- package/esm/marks/markRamp.d.ts +1 -3
- package/esm/marks/markRamp.js +1 -5
- package/esm/marks/nearestMarkHit.d.ts +49 -0
- package/esm/marks/nearestMarkHit.js +126 -0
- package/esm/marks/pointMark.d.ts +9 -2
- package/esm/marks/pointMark.js +36 -31
- package/esm/marks/rowLane.d.ts +17 -0
- package/esm/marks/rowLane.js +11 -0
- package/esm/marks/spanMark.d.ts +6 -26
- package/esm/marks/spanMark.js +34 -31
- package/esm/marks/types.d.ts +51 -181
- package/esm/marks/types.js +91 -131
- package/esm/namedReactions.d.ts +3 -4
- package/esm/namedReactions.js +3 -4
- package/esm/scoreScale.d.ts +20 -0
- package/esm/scoreScale.js +77 -0
- package/esm/shaders/barMark.generated.d.ts +2 -3
- package/esm/shaders/barMark.generated.js +4 -3
- package/esm/shaders/barMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/barMark.glsl.generated.js +4 -0
- package/esm/shaders/barMark.iface.generated.d.ts +12 -6
- package/esm/shaders/barMark.iface.generated.js +27 -15
- package/esm/shaders/barMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/barMark.wgsl.generated.js +3 -0
- package/esm/shaders/coverageBar.generated.d.ts +2 -3
- package/esm/shaders/coverageBar.generated.js +4 -3
- package/esm/shaders/coverageBar.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageBar.glsl.generated.js +4 -0
- package/esm/shaders/coverageBar.iface.generated.js +1 -1
- package/esm/shaders/coverageBar.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageBar.wgsl.generated.js +3 -0
- package/esm/shaders/coverageIndicator.generated.d.ts +2 -3
- package/esm/shaders/coverageIndicator.generated.js +4 -3
- package/esm/shaders/coverageIndicator.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageIndicator.glsl.generated.js +4 -0
- package/esm/shaders/coverageIndicator.iface.generated.js +1 -1
- package/esm/shaders/coverageIndicator.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageIndicator.wgsl.generated.js +3 -0
- package/esm/shaders/coverageInterbase.generated.d.ts +2 -3
- package/esm/shaders/coverageInterbase.generated.js +4 -3
- package/esm/shaders/coverageInterbase.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageInterbase.glsl.generated.js +4 -0
- package/esm/shaders/coverageInterbase.iface.generated.js +1 -1
- package/esm/shaders/coverageInterbase.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageInterbase.wgsl.generated.js +3 -0
- package/esm/shaders/coverageMod.generated.d.ts +2 -3
- package/esm/shaders/coverageMod.generated.js +4 -3
- package/esm/shaders/coverageMod.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageMod.glsl.generated.js +4 -0
- package/esm/shaders/coverageMod.iface.generated.js +1 -1
- package/esm/shaders/coverageMod.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageMod.wgsl.generated.js +3 -0
- package/esm/shaders/coverageSnp.generated.d.ts +2 -3
- package/esm/shaders/coverageSnp.generated.js +4 -3
- package/esm/shaders/coverageSnp.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageSnp.glsl.generated.js +4 -0
- package/esm/shaders/coverageSnp.iface.generated.js +1 -1
- package/esm/shaders/coverageSnp.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageSnp.wgsl.generated.js +3 -0
- package/esm/shaders/pointMark.generated.d.ts +2 -3
- package/esm/shaders/pointMark.generated.js +4 -3
- package/esm/shaders/pointMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/pointMark.glsl.generated.js +4 -0
- package/esm/shaders/pointMark.iface.generated.d.ts +11 -3
- package/esm/shaders/pointMark.iface.generated.js +23 -9
- package/esm/shaders/pointMark.js.generated.d.ts +1 -1
- package/esm/shaders/pointMark.js.generated.js +51 -29
- package/esm/shaders/pointMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/pointMark.wgsl.generated.js +3 -0
- package/esm/shaders/scoreScale.js.generated.js +46 -22
- package/esm/shaders/spanMark.generated.d.ts +2 -3
- package/esm/shaders/spanMark.generated.js +4 -3
- package/esm/shaders/spanMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/spanMark.glsl.generated.js +4 -0
- package/esm/shaders/spanMark.iface.generated.js +1 -1
- package/esm/shaders/spanMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/spanMark.wgsl.generated.js +3 -0
- package/esm/slangPass.d.ts +9 -10
- package/esm/slangPass.js +9 -3
- package/esm/useGraphicsCapabilities.d.ts +1 -1
- package/esm/useGraphicsCapabilities.js +1 -1
- package/esm/webgpuUtils.d.ts +3 -11
- package/esm/webgpuUtils.js +12 -33
- package/package.json +3 -2
- package/src/shaders/barMark.generated.ts +6 -5
- package/src/shaders/barMark.glsl.generated.ts +6 -0
- package/src/shaders/barMark.iface.generated.ts +31 -15
- package/src/shaders/barMark.slang +11 -3
- package/src/shaders/barMark.wgsl.generated.ts +4 -0
- package/src/shaders/colorPack.slang +3 -2
- package/src/shaders/coverageBand.slang +5 -11
- package/src/shaders/coverageBar.generated.ts +6 -5
- package/src/shaders/coverageBar.glsl.generated.ts +6 -0
- package/src/shaders/coverageBar.iface.generated.ts +1 -1
- package/src/shaders/coverageBar.slang +1 -1
- package/src/shaders/coverageBar.wgsl.generated.ts +4 -0
- package/src/shaders/coverageIndicator.generated.ts +6 -5
- package/src/shaders/coverageIndicator.glsl.generated.ts +6 -0
- package/src/shaders/coverageIndicator.iface.generated.ts +1 -1
- package/src/shaders/coverageIndicator.wgsl.generated.ts +4 -0
- package/src/shaders/coverageInterbase.generated.ts +6 -5
- package/src/shaders/coverageInterbase.glsl.generated.ts +6 -0
- package/src/shaders/coverageInterbase.iface.generated.ts +1 -1
- package/src/shaders/coverageInterbase.wgsl.generated.ts +4 -0
- package/src/shaders/coverageMod.generated.ts +6 -5
- package/src/shaders/coverageMod.glsl.generated.ts +6 -0
- package/src/shaders/coverageMod.iface.generated.ts +1 -1
- package/src/shaders/coverageMod.wgsl.generated.ts +4 -0
- package/src/shaders/coverageSnp.generated.ts +6 -5
- package/src/shaders/coverageSnp.glsl.generated.ts +6 -0
- package/src/shaders/coverageSnp.iface.generated.ts +1 -1
- package/src/shaders/coverageSnp.wgsl.generated.ts +4 -0
- package/src/shaders/hpmath.slang +18 -6
- package/src/shaders/pointMark.generated.ts +6 -6
- package/src/shaders/pointMark.glsl.generated.ts +6 -0
- package/src/shaders/pointMark.iface.generated.ts +28 -9
- package/src/shaders/pointMark.js.generated.ts +48 -29
- package/src/shaders/pointMark.slang +18 -5
- package/src/shaders/pointMark.wgsl.generated.ts +4 -0
- package/src/shaders/scoreScale.js.generated.ts +43 -22
- package/src/shaders/scoreScale.slang +37 -53
- package/src/shaders/spanMark.generated.ts +6 -5
- package/src/shaders/spanMark.glsl.generated.ts +6 -0
- package/src/shaders/spanMark.iface.generated.ts +1 -1
- package/src/shaders/spanMark.wgsl.generated.ts +4 -0
- package/src/shaders/valueScale.slang +8 -45
|
@@ -16,49 +16,68 @@ function _min(a: number, b: number) {
|
|
|
16
16
|
return b < a || Number.isNaN(a) ? b : a
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
function log1pf(x: number): number {
|
|
20
|
+
let u = (1.0 + x)
|
|
21
|
+
let _t0: number
|
|
22
|
+
if ((u == 1.0)) {
|
|
23
|
+
_t0 = x
|
|
24
|
+
} else {
|
|
25
|
+
_t0 = (Math.log(u) * (x / (u - 1.0)))
|
|
26
|
+
}
|
|
27
|
+
return _t0
|
|
28
|
+
}
|
|
29
|
+
|
|
19
30
|
function symlogTransform(x: number, c: number): number {
|
|
20
|
-
return ((((Math.sign(x)) | 0)) *
|
|
31
|
+
return ((((Math.sign(x)) | 0)) * log1pf(Math.abs((x / c))))
|
|
21
32
|
}
|
|
22
33
|
|
|
23
34
|
function normalizeScore(score: number, domainMin: number, domainMax: number, scaleType: number, symlogConstant: number): number {
|
|
35
|
+
let tMax: number
|
|
36
|
+
let tMin: number
|
|
37
|
+
let t: number
|
|
24
38
|
if ((scaleType == 2)) {
|
|
25
|
-
let
|
|
26
|
-
let
|
|
27
|
-
|
|
28
|
-
|
|
39
|
+
let _t0 = symlogTransform(score, symlogConstant)
|
|
40
|
+
let _t1 = symlogTransform(domainMin, symlogConstant)
|
|
41
|
+
tMax = symlogTransform(domainMax, symlogConstant)
|
|
42
|
+
tMin = _t1
|
|
43
|
+
t = _t0
|
|
44
|
+
} else {
|
|
45
|
+
if ((scaleType == 1)) {
|
|
46
|
+
if ((domainMin > 0.0)) {
|
|
47
|
+
tMax = domainMin
|
|
48
|
+
} else {
|
|
49
|
+
tMax = 1.0
|
|
50
|
+
}
|
|
51
|
+
let _t2 = Math.log2(_max(score, tMax))
|
|
52
|
+
let _t3 = Math.log2(tMax)
|
|
53
|
+
tMax = Math.log2(_max(domainMax, tMax))
|
|
54
|
+
tMin = _t3
|
|
55
|
+
t = _t2
|
|
56
|
+
} else {
|
|
57
|
+
tMax = domainMax
|
|
58
|
+
tMin = domainMin
|
|
59
|
+
t = score
|
|
29
60
|
}
|
|
30
|
-
return _clamp(((symlogTransform(score, symlogConstant) - tMin) / tRange), 0.0, 1.0)
|
|
31
61
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if ((
|
|
35
|
-
|
|
62
|
+
let tRange = (tMax - tMin)
|
|
63
|
+
if ((tRange <= 0.0)) {
|
|
64
|
+
if ((t > tMin)) {
|
|
65
|
+
tMax = 1.0
|
|
36
66
|
} else {
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
let logMin = Math.log2(floorV)
|
|
40
|
-
let logRange = (Math.log2(_max(domainMax, floorV)) - logMin)
|
|
41
|
-
if ((logRange <= 0.0)) {
|
|
42
|
-
return 0.0
|
|
67
|
+
tMax = 0.0
|
|
43
68
|
}
|
|
44
|
-
return
|
|
69
|
+
return tMax
|
|
45
70
|
}
|
|
46
|
-
|
|
47
|
-
if ((range <= 0.0)) {
|
|
48
|
-
return 0.0
|
|
49
|
-
}
|
|
50
|
-
return _clamp(((score - domainMin) / range), 0.0, 1.0)
|
|
71
|
+
return _clamp(((t - tMin) / tRange), 0.0, 1.0)
|
|
51
72
|
}
|
|
52
73
|
|
|
53
|
-
export function
|
|
54
|
-
return ((1.0 -
|
|
74
|
+
export function valueToYPxScaled(value: number, domainMin: number, domainMax: number, h: number, scaleType: number): number {
|
|
75
|
+
return ((1.0 - normalizeScore(value, domainMin, domainMax, scaleType, 1.0)) * h)
|
|
55
76
|
}
|
|
56
77
|
|
|
57
|
-
export function
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
return valueToYPx(value, domainMin, domainMax, h)
|
|
78
|
+
export function pointYPx(value: number, domainMin: number, domainMax: number, h: number, scaleType: number, insetPx: number): number {
|
|
79
|
+
let _t0 = _min(insetPx, (h * 0.5))
|
|
80
|
+
return (_t0 + valueToYPxScaled(value, domainMin, domainMax, (h - (2.0 * _t0)), scaleType))
|
|
62
81
|
}
|
|
63
82
|
|
|
64
83
|
export function pointDrawsBar(spanPx: number, radiusPx: number): boolean {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// The `point` mark shape: one glyph per instance, placed at a genomic x and at
|
|
2
|
-
// a y read off a per-instance value through
|
|
2
|
+
// a y read off a per-instance value through `valueScale`. The glyph
|
|
3
3
|
// channel picks between a disc, an inverted triangle and a diamond, and an
|
|
4
4
|
// instance whose x..x2 extent is wider than the glyph draws as a horizontal bar
|
|
5
5
|
// instead — the shape's own answer to "this datum has extent".
|
|
@@ -7,9 +7,8 @@
|
|
|
7
7
|
// All four are a 6-vertex quad; the fragment shader carves the shape.
|
|
8
8
|
//! targets: wgsl, glsl
|
|
9
9
|
//! export-consts: DIAMOND_GLYPH_SCALE, GLYPH_DISC, GLYPH_TRIANGLE, GLYPH_DIAMOND
|
|
10
|
-
//! js-export:
|
|
11
|
-
// `
|
|
12
|
-
// of the scale — the bar shape's painter and hit test import this twin too.
|
|
10
|
+
//! js-export: valueToYPxScaled, pointDrawsBar, pointYPx
|
|
11
|
+
// `valueScale`'s twin is lifted here, once, for the bar shape too.
|
|
13
12
|
|
|
14
13
|
import antialias;
|
|
15
14
|
import hpmath;
|
|
@@ -26,6 +25,7 @@ struct PointMarkInstance {
|
|
|
26
25
|
float y : ATTR2;
|
|
27
26
|
uint color : ATTR3;
|
|
28
27
|
uint glyph : ATTR4;
|
|
28
|
+
uint row : ATTR5;
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
struct Uniforms {
|
|
@@ -43,6 +43,12 @@ struct Uniforms {
|
|
|
43
43
|
float zero;
|
|
44
44
|
float viewportWidth;
|
|
45
45
|
float radiusPx;
|
|
46
|
+
// CSS px per row band, the value scale ruling each on its own; the canvas
|
|
47
|
+
// height where every instance is on row 0 (ADR-126).
|
|
48
|
+
float rowHeight;
|
|
49
|
+
// Ends of the value range, inset by `glyphPaint`'s `pointInsetPx` where the
|
|
50
|
+
// display wants its edge glyphs whole; 0 centres a point on the plot's edge.
|
|
51
|
+
float insetPx;
|
|
46
52
|
// Read by the glyph pad alone; every other length in this block is CSS px.
|
|
47
53
|
float devicePixelRatio;
|
|
48
54
|
};
|
|
@@ -92,6 +98,13 @@ static const float INV_SQRT5 = 0.4472136;
|
|
|
92
98
|
// colour swap. LocusZoom's lead-SNP convention, generalized.
|
|
93
99
|
static const float DIAMOND_GLYPH_SCALE = 1.6;
|
|
94
100
|
|
|
101
|
+
// The shape's own placement: the vertex branch, the Canvas2D painter, the ink
|
|
102
|
+
// box and the hit test all read a value's y through this.
|
|
103
|
+
float pointYPx(float value, float domainMin, float domainMax, float h, int scaleType, float insetPx) {
|
|
104
|
+
float inset = min(insetPx, h * 0.5);
|
|
105
|
+
return inset + valueToYPxScaled(value, domainMin, domainMax, h - 2.0 * inset, scaleType);
|
|
106
|
+
}
|
|
107
|
+
|
|
95
108
|
// The glyph channel's values. The numbering is a contract between whatever
|
|
96
109
|
// packs the channel, the Canvas2D painter and the branches below, so it is
|
|
97
110
|
// authored once here and `//! export-consts`ed.
|
|
@@ -110,7 +123,7 @@ VsOut vs_main(PointMarkInstance inst, uint vid : SV_VertexID) {
|
|
|
110
123
|
|
|
111
124
|
float startClipX = bpToClipX(inst.x, u);
|
|
112
125
|
float endClipX = bpToClipX(inst.x2, u);
|
|
113
|
-
float yPx =
|
|
126
|
+
float yPx = u.rowHeight * float(inst.row) + pointYPx(inst.y, u.domainMin, u.domainMax, u.rowHeight, u.valueScaleType, u.insetPx);
|
|
114
127
|
float centerClipY = yPxToClipY(yPx, u.canvasHeight);
|
|
115
128
|
|
|
116
129
|
// Genomic span in CSS px (clip width spans -1..1 across viewportWidth).
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// AUTO-GENERATED by packages/shader-tools/src/shader-codegen from pointMark.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) bpRangeX_0 : vec3<f32>,\n @align(4) canvasHeight_0 : f32,\n @align(16) domainMin_0 : f32,\n @align(4) domainMax_0 : f32,\n @align(8) valueScaleType_0 : i32,\n @align(4) rampMode_0 : i32,\n @align(16) rampMin_0 : f32,\n @align(4) rampMax_0 : f32,\n @align(8) zero_0 : f32,\n @align(4) viewportWidth_0 : f32,\n @align(16) radiusPx_0 : f32,\n @align(4) rowHeight_0 : f32,\n @align(8) insetPx_0 : f32,\n @align(4) devicePixelRatio_0 : f32,\n};\n\n@binding(1) @group(0) var<uniform> u_0 : Uniforms_std140_0;\n@binding(2) @group(0) var colorRamp_texture_0 : texture_2d<f32>;\n\n@binding(3) @group(0) var colorRamp_sampler_0 : sampler;\n\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_0 : f32) -> f32\n{\n var step_0 : f32 = 2.0f / bpRange_0.z;\n var _S5 : f32 = - (1.0f / hpZero_0);\n return dot(vec3<f32>(-1.0f, max(splitPos_0.x - bpRange_0.x, _S5), max(splitPos_0.y - bpRange_0.y, _S5)), vec3<f32>(1.0f, step_0, step_0));\n}\n\nfn bpToClipX_0( bp_0 : u32, u_1 : ptr<function, Uniforms_std140_0>) -> f32\n{\n return hpToClipX_0(hpSplitUint_0(bp_0), (*u_1).bpRangeX_0, (*u_1).zero_0);\n}\n\nfn log1pf_0( x_0 : f32) -> f32\n{\n var u_2 : f32 = 1.0f + x_0;\n var _S6 : f32;\n if(u_2 == 1.0f)\n {\n _S6 = x_0;\n }\n else\n {\n _S6 = log(u_2) * (x_0 / (u_2 - 1.0f));\n }\n return _S6;\n}\n\nfn symlogTransform_0( x_1 : f32, c_0 : f32) -> f32\n{\n return f32((i32(sign((x_1))))) * log1pf_0(abs(x_1 / c_0));\n}\n\nfn normalizeScore_0( score_0 : f32, domainMin_1 : f32, domainMax_1 : f32, scaleType_0 : i32, symlogConstant_0 : f32) -> f32\n{\n var tMax_0 : f32;\n var tMin_0 : f32;\n var t_0 : f32;\n if(scaleType_0 == i32(2))\n {\n var _S7 : f32 = symlogTransform_0(score_0, symlogConstant_0);\n var _S8 : f32 = symlogTransform_0(domainMin_1, symlogConstant_0);\n tMax_0 = symlogTransform_0(domainMax_1, symlogConstant_0);\n tMin_0 = _S8;\n t_0 = _S7;\n }\n else\n {\n if(scaleType_0 == i32(1))\n {\n if(domainMin_1 > 0.0f)\n {\n tMax_0 = domainMin_1;\n }\n else\n {\n tMax_0 = 1.0f;\n }\n var _S9 : f32 = log2(max(score_0, tMax_0));\n var _S10 : f32 = log2(tMax_0);\n tMax_0 = log2(max(domainMax_1, tMax_0));\n tMin_0 = _S10;\n t_0 = _S9;\n }\n else\n {\n tMax_0 = domainMax_1;\n tMin_0 = domainMin_1;\n t_0 = score_0;\n }\n }\n var tRange_0 : f32 = tMax_0 - tMin_0;\n if(tRange_0 <= 0.0f)\n {\n if(t_0 > tMin_0)\n {\n tMax_0 = 1.0f;\n }\n else\n {\n tMax_0 = 0.0f;\n }\n return tMax_0;\n }\n return clamp((t_0 - tMin_0) / tRange_0, 0.0f, 1.0f);\n}\n\nfn valueToYPxScaled_0( value_1 : f32, domainMin_2 : f32, domainMax_2 : f32, h_0 : f32, scaleType_1 : i32) -> f32\n{\n return (1.0f - normalizeScore_0(value_1, domainMin_2, domainMax_2, scaleType_1, 1.0f)) * h_0;\n}\n\nfn pointYPx_0( value_2 : f32, domainMin_3 : f32, domainMax_3 : f32, h_1 : f32, scaleType_2 : i32, insetPx_1 : f32) -> f32\n{\n var _S11 : f32 = min(insetPx_1, h_1 * 0.5f);\n return _S11 + valueToYPxScaled_0(value_2, domainMin_3, domainMax_3, h_1 - 2.0f * _S11, scaleType_2);\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 clipLenToPx_0( clipLen_0 : f32, size_0 : f32) -> f32\n{\n return clipLen_0 * 0.5f * size_0;\n}\n\nfn pointDrawsBar_0( spanPx_0 : f32, radiusPx_1 : f32) -> bool\n{\n return spanPx_0 > (radiusPx_1 * 2.0f);\n}\n\nfn unpackRGBA_0( c_1 : u32) -> vec4<f32>\n{\n return vec4<f32>(f32((((c_1 >> (u32(0)))) & (u32(255)))), f32((((c_1 >> (u32(8)))) & (u32(255)))), f32((((c_1 >> (u32(16)))) & (u32(255)))), f32((((c_1 >> (u32(24)))) & (u32(255))))) / vec4<f32>(255.0f);\n}\n\nfn rampColor_0( ramp_texture_0 : texture_2d<f32>, ramp_sampler_0 : sampler, t_1 : f32) -> vec4<f32>\n{\n return (textureSampleLevel((ramp_texture_0), (ramp_sampler_0), (vec2<f32>((clamp(t_1, 0.0f, 1.0f) * 255.0f + 0.5f) / 256.0f, 0.5f)), (0.0f)));\n}\n\nfn markInstanceColor_0( ramp_texture_1 : texture_2d<f32>, ramp_sampler_1 : sampler, packed_0 : u32, rampMode_1 : i32, rampMin_1 : f32, rampMax_1 : f32) -> vec4<f32>\n{\n if(rampMode_1 == i32(0))\n {\n return unpackRGBA_0(packed_0);\n }\n var scaleType_3 : i32;\n if(rampMode_1 == i32(2))\n {\n scaleType_3 = i32(1);\n }\n else\n {\n scaleType_3 = i32(0);\n }\n return rampColor_0(ramp_texture_1, ramp_sampler_1, normalizeScore_0((bitcast<f32>((packed_0))), rampMin_1, rampMax_1, scaleType_3, 1.0f));\n}\n\nfn pxToClipLen_0( px_0 : f32, size_1 : f32) -> f32\n{\n return px_0 * 2.0f / size_1;\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 crispSquareTopLeftPx_0( centerPx_0 : f32, diameterPx_0 : f32) -> f32\n{\n return floor(centerPx_0 - diameterPx_0 * 0.5f + 0.5f);\n}\n\nfn crispSquareCornerPx_0( centerPx_1 : vec2<f32>, diameterPx_1 : f32, q_0 : vec2<f32>) -> vec2<f32>\n{\n return vec2<f32>(crispSquareTopLeftPx_0(centerPx_1.x, diameterPx_1), crispSquareTopLeftPx_0(centerPx_1.y, diameterPx_1)) + q_0 * vec2<f32>(diameterPx_1);\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 crispSquareCornerClip_0( centerClipX_0 : f32, centerYPx_0 : f32, diameterPx_2 : f32, q_1 : vec2<f32>, viewportWidth_1 : f32, canvasHeight_2 : f32) -> vec4<f32>\n{\n var vPx_0 : vec2<f32> = crispSquareCornerPx_0(vec2<f32>(clipXToPx_0(centerClipX_0, viewportWidth_1), centerYPx_0), diameterPx_2, q_1);\n return vec4<f32>(pxToClipX_0(vPx_0.x, viewportWidth_1), yPxToClipY_0(vPx_0.y, canvasHeight_2), 0.0f, 1.0f);\n}\n\nfn aaPx_0( dpr_0 : f32) -> f32\n{\n return 1.0f / max(dpr_0, 1.0f);\n}\n\nfn aaHalfPx_0( dpr_1 : f32) -> f32\n{\n return 0.5f * aaPx_0(dpr_1);\n}\n\nfn discExpand_0( radiusPx_2 : f32, dpr_2 : f32) -> f32\n{\n return (radiusPx_2 + aaHalfPx_0(dpr_2)) / max(radiusPx_2, 0.5f);\n}\n\nstruct VsOut_0\n{\n @builtin(position) position_0 : vec4<f32>,\n @location(0) color_0 : vec4<f32>,\n @location(2) localPos_0 : vec2<f32>,\n @interpolate(flat) @location(1) shape_0 : f32,\n};\n\nstruct vertexInput_0\n{\n @location(0) x_2 : u32,\n @location(1) x2_0 : u32,\n @location(2) y_0 : f32,\n @location(3) color_1 : u32,\n @location(4) glyph_0 : u32,\n @location(5) row_0 : u32,\n};\n\n@vertex\nfn vs_main( _S12 : vertexInput_0, @builtin(vertex_index) vid_1 : u32) -> VsOut_0\n{\n var q_2 : vec2<f32> = quadLocal_0(vid_1 % u32(6));\n var local_0 : vec2<f32> = q_2 * vec2<f32>(2.0f) - vec2<f32>(1.0f);\n var xZero_0 : bool = (q_2.x) < 0.5f;\n var _S13 : Uniforms_std140_0 = u_0;\n var _S14 : f32 = bpToClipX_0(_S12.x_2, &(_S13));\n var _S15 : f32 = bpToClipX_0(_S12.x2_0, &(_S13));\n var yPx_1 : f32 = u_0.rowHeight_0 * f32(_S12.row_0) + pointYPx_0(_S12.y_0, u_0.domainMin_0, u_0.domainMax_0, u_0.rowHeight_0, u_0.valueScaleType_0, u_0.insetPx_0);\n var centerClipY_0 : f32 = yPxToClipY_0(yPx_1, u_0.canvasHeight_0);\n var isBar_0 : bool = pointDrawsBar_0(clipLenToPx_0(abs(_S15 - _S14), u_0.viewportWidth_0), u_0.radiusPx_0);\n var o_0 : VsOut_0;\n o_0.color_0 = markInstanceColor_0(colorRamp_texture_0, colorRamp_sampler_0, _S12.color_1, u_0.rampMode_0, u_0.rampMin_0, u_0.rampMax_0);\n var x_3 : f32;\n if(isBar_0)\n {\n if(xZero_0)\n {\n x_3 = min(_S14, _S15);\n }\n else\n {\n x_3 = max(_S14, _S15);\n }\n o_0.position_0 = vec4<f32>(x_3, centerClipY_0 + pxToClipLen_0(local_0.y * u_0.radiusPx_0, u_0.canvasHeight_0), 0.0f, 1.0f);\n o_0.localPos_0 = local_0;\n o_0.shape_0 = 3.0f;\n }\n else\n {\n var _S16 : bool;\n if((_S12.glyph_0) == u32(0))\n {\n _S16 = (u_0.radiusPx_0 * 2.0f) <= 3.0f;\n }\n else\n {\n _S16 = false;\n }\n if(_S16)\n {\n o_0.position_0 = crispSquareCornerClip_0(_S14, yPx_1, u_0.radiusPx_0 * 2.0f, q_2, u_0.viewportWidth_0, u_0.canvasHeight_0);\n o_0.localPos_0 = local_0;\n o_0.shape_0 = 3.0f;\n }\n else\n {\n var expand_0 : f32 = discExpand_0(u_0.radiusPx_0, u_0.devicePixelRatio_0);\n var _S17 : bool = (_S12.glyph_0) == u32(2);\n if(_S17)\n {\n x_3 = 1.60000002384185791f;\n }\n else\n {\n x_3 = 1.0f;\n }\n var halfPx_0 : f32 = u_0.radiusPx_0 * expand_0 * x_3;\n o_0.position_0 = vec4<f32>(_S14 + pxToClipLen_0(local_0.x * halfPx_0, u_0.viewportWidth_0), centerClipY_0 + pxToClipLen_0(local_0.y * halfPx_0, u_0.canvasHeight_0), 0.0f, 1.0f);\n o_0.localPos_0 = local_0 * vec2<f32>(expand_0);\n if((_S12.glyph_0) == u32(1))\n {\n x_3 = 2.0f;\n }\n else\n {\n if(_S17)\n {\n x_3 = 1.0f;\n }\n else\n {\n x_3 = 0.0f;\n }\n }\n o_0.shape_0 = x_3;\n }\n }\n return o_0;\n}\n\nfn discCoverage_0( localPos_1 : vec2<f32>) -> f32\n{\n return 1.0f - length(localPos_1);\n}\n\nfn aaGradient_0( d_0 : f32) -> f32\n{\n return max(length(vec2<f32>(dpdx(d_0), dpdy(d_0))), 0.00000999999974738f);\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 glyphEdgeAlpha_0( coverage_0 : f32) -> f32\n{\n return aaRamp_0(coverage_0, aaGradient_0(coverage_0));\n}\n\nstruct pixelOutput_0\n{\n @location(0) output_0 : vec4<f32>,\n};\n\nstruct pixelInput_0\n{\n @location(0) color_2 : vec4<f32>,\n @location(2) localPos_2 : vec2<f32>,\n @interpolate(flat) @location(1) shape_1 : f32,\n};\n\n@fragment\nfn fs_main( _S18 : pixelInput_0, @builtin(position) position_1 : vec4<f32>) -> pixelOutput_0\n{\n var coverage_1 : f32;\n if((_S18.shape_1) > 2.5f)\n {\n coverage_1 = 1.0f;\n }\n else\n {\n if((_S18.shape_1) > 1.5f)\n {\n var _S19 : f32 = _S18.localPos_2.y;\n var _S20 : f32 = _S18.localPos_2.x;\n coverage_1 = min(1.0f - _S19, min((2.0f * _S20 + _S19 + 1.0f) * 0.44721359014511108f, (-2.0f * _S20 + _S19 + 1.0f) * 0.44721359014511108f));\n }\n else\n {\n if((_S18.shape_1) > 0.5f)\n {\n coverage_1 = 1.0f - (abs(_S18.localPos_2.x) + abs(_S18.localPos_2.y));\n }\n else\n {\n coverage_1 = discCoverage_0(_S18.localPos_2);\n }\n }\n }\n var alpha_0 : f32 = glyphEdgeAlpha_0(coverage_1);\n if(alpha_0 <= 0.0f)\n {\n discard;\n }\n var _S21 : pixelOutput_0 = pixelOutput_0( vec4<f32>(_S18.color_2.xyz, _S18.color_2.w * alpha_0) );\n return _S21;\n}\n\n"
|
|
@@ -16,36 +16,57 @@ function _min(a: number, b: number) {
|
|
|
16
16
|
return b < a || Number.isNaN(a) ? b : a
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
function log1pf(x: number): number {
|
|
20
|
+
let u = (1.0 + x)
|
|
21
|
+
let _t0: number
|
|
22
|
+
if ((u == 1.0)) {
|
|
23
|
+
_t0 = x
|
|
24
|
+
} else {
|
|
25
|
+
_t0 = (Math.log(u) * (x / (u - 1.0)))
|
|
26
|
+
}
|
|
27
|
+
return _t0
|
|
28
|
+
}
|
|
29
|
+
|
|
19
30
|
function symlogTransform(x: number, c: number): number {
|
|
20
|
-
return ((((Math.sign(x)) | 0)) *
|
|
31
|
+
return ((((Math.sign(x)) | 0)) * log1pf(Math.abs((x / c))))
|
|
21
32
|
}
|
|
22
33
|
|
|
23
34
|
export function normalizeScore(score: number, domainMin: number, domainMax: number, scaleType: number, symlogConstant: number): number {
|
|
35
|
+
let tMax: number
|
|
36
|
+
let tMin: number
|
|
37
|
+
let t: number
|
|
24
38
|
if ((scaleType == 2)) {
|
|
25
|
-
let
|
|
26
|
-
let
|
|
27
|
-
|
|
28
|
-
|
|
39
|
+
let _t0 = symlogTransform(score, symlogConstant)
|
|
40
|
+
let _t1 = symlogTransform(domainMin, symlogConstant)
|
|
41
|
+
tMax = symlogTransform(domainMax, symlogConstant)
|
|
42
|
+
tMin = _t1
|
|
43
|
+
t = _t0
|
|
44
|
+
} else {
|
|
45
|
+
if ((scaleType == 1)) {
|
|
46
|
+
if ((domainMin > 0.0)) {
|
|
47
|
+
tMax = domainMin
|
|
48
|
+
} else {
|
|
49
|
+
tMax = 1.0
|
|
50
|
+
}
|
|
51
|
+
let _t2 = Math.log2(_max(score, tMax))
|
|
52
|
+
let _t3 = Math.log2(tMax)
|
|
53
|
+
tMax = Math.log2(_max(domainMax, tMax))
|
|
54
|
+
tMin = _t3
|
|
55
|
+
t = _t2
|
|
56
|
+
} else {
|
|
57
|
+
tMax = domainMax
|
|
58
|
+
tMin = domainMin
|
|
59
|
+
t = score
|
|
29
60
|
}
|
|
30
|
-
return _clamp(((symlogTransform(score, symlogConstant) - tMin) / tRange), 0.0, 1.0)
|
|
31
61
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if ((
|
|
35
|
-
|
|
62
|
+
let tRange = (tMax - tMin)
|
|
63
|
+
if ((tRange <= 0.0)) {
|
|
64
|
+
if ((t > tMin)) {
|
|
65
|
+
tMax = 1.0
|
|
36
66
|
} else {
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
let logMin = Math.log2(floorV)
|
|
40
|
-
let logRange = (Math.log2(_max(domainMax, floorV)) - logMin)
|
|
41
|
-
if ((logRange <= 0.0)) {
|
|
42
|
-
return 0.0
|
|
67
|
+
tMax = 0.0
|
|
43
68
|
}
|
|
44
|
-
return
|
|
45
|
-
}
|
|
46
|
-
let range = (domainMax - domainMin)
|
|
47
|
-
if ((range <= 0.0)) {
|
|
48
|
-
return 0.0
|
|
69
|
+
return tMax
|
|
49
70
|
}
|
|
50
|
-
return _clamp(((
|
|
71
|
+
return _clamp(((t - tMin) / tRange), 0.0, 1.0)
|
|
51
72
|
}
|
|
@@ -1,69 +1,53 @@
|
|
|
1
|
-
// The score → [0,1] normalizer every score-scaled
|
|
2
|
-
//
|
|
1
|
+
// The score → [0,1] normalizer every score-scaled mark is placed and coloured
|
|
2
|
+
// by — wiggle, the coverage band, the bar and point shapes, their ramps — and
|
|
3
|
+
// the scale-type vocabulary its branches switch on. `makeScoreNormalizer`
|
|
4
|
+
// (render-core's scoreScale.ts) is its loop-hoisted twin.
|
|
3
5
|
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// band's depth axis (`coverageBand.slang`, via `normalizeDepthScalar`). They
|
|
7
|
-
// carried a branch-for-branch copy each, and the copies did not agree: the
|
|
8
|
-
// coverage one compared `scaleType` against bare 2 and 1 rather than the
|
|
9
|
-
// constants below, and answered 0 on a degenerate domain where wiggle's divided
|
|
10
|
-
// by a 1e-6 floor and saturated. This module is one answer to both.
|
|
11
|
-
//
|
|
12
|
-
// The degenerate domain answers 0, which is what the JS twin
|
|
13
|
-
// (`makeScoreNormalizer`, packages/wiggle-core/src/normalize.ts) has always
|
|
14
|
-
// answered. Returning 0 avoids the NaN the 1e-6 floor was there for just as
|
|
15
|
-
// well, so the divergence bought nothing and cost a documented exception.
|
|
16
|
-
//
|
|
17
|
-
// `SCALE_TYPE_LINEAR` is deliberately absent: it is "neither of these", and a
|
|
18
|
-
// third constant would be a value nothing compares against.
|
|
6
|
+
// A domain with no range is a step: a score above its min maps to 1 and any
|
|
7
|
+
// other to 0, so a score above a pinned domain sits off the top everywhere.
|
|
19
8
|
//! export-consts: SCALE_TYPE_LOG, SCALE_TYPE_SYMLOG
|
|
20
9
|
//! js-export: normalizeScore
|
|
21
|
-
//! js-skip:
|
|
10
|
+
//! js-skip: log1pf — JS has Math.log1p, so a twin of this would be the float32 workaround spelled out where the language already answers it
|
|
11
|
+
//! js-skip: symlogTransform — render-core scoreScale.ts reaches Math.log1p directly, one call inside a normalizer it hoists the whole log domain out of, so a per-call twin of this would have no caller. What both backends must agree on is normalizeScore, which is exported and swept by normalizeScoreParity.test.ts
|
|
22
12
|
module scoreScale;
|
|
23
13
|
|
|
24
|
-
//
|
|
25
|
-
// @jbrowse/wiggle-core through `wiggleCommon.slang`'s `export-consts` — the
|
|
26
|
-
// constant evaluator resolves through imports, and wiggle-core is where
|
|
27
|
-
// `WiggleScaleType` is declared, so the numbers stay next to the type they
|
|
28
|
-
// name rather than next to the module that happens to author them.
|
|
14
|
+
// `ScaleTypeCode` in scoreScale.ts is these two and 0, for linear.
|
|
29
15
|
public static const int SCALE_TYPE_LOG = 1;
|
|
30
16
|
public static const int SCALE_TYPE_SYMLOG = 2;
|
|
31
17
|
|
|
18
|
+
// log(1 + x) for x that `1.0 + x` rounds away: a symlog domain narrower than
|
|
19
|
+
// its constant lands entirely in that region, and in float32 the rounding
|
|
20
|
+
// survives the normalize's divide by a tiny domain range — 0.2px of a 40px row
|
|
21
|
+
// on domain [-1, 0.75] with constant 100.5, against the Canvas2D twin's
|
|
22
|
+
// Math.log1p. Kahan's identity: `u - 1.0` is exact where `u` is near 1, so the
|
|
23
|
+
// ratio is the correction the sum lost.
|
|
24
|
+
float log1pf(float x) {
|
|
25
|
+
float u = 1.0 + x;
|
|
26
|
+
return u == 1.0 ? x : log(u) * (x / (u - 1.0));
|
|
27
|
+
}
|
|
28
|
+
|
|
32
29
|
public float symlogTransform(float x, float c) {
|
|
33
|
-
return sign(x) *
|
|
30
|
+
return sign(x) * log1pf(abs(x / c));
|
|
34
31
|
}
|
|
35
32
|
|
|
36
33
|
public float normalizeScore(float score, float domainMin, float domainMax, int scaleType, float symlogConstant) {
|
|
34
|
+
float t = score;
|
|
35
|
+
float tMin = domainMin;
|
|
36
|
+
float tMax = domainMax;
|
|
37
37
|
if (scaleType == SCALE_TYPE_SYMLOG) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
//
|
|
43
|
-
float tMin = symlogTransform(domainMin, symlogConstant);
|
|
44
|
-
float tMax = symlogTransform(domainMax, symlogConstant);
|
|
45
|
-
float tRange = tMax - tMin;
|
|
46
|
-
if (tRange <= 0.0) { return 0.0; }
|
|
47
|
-
float t = symlogTransform(score, symlogConstant);
|
|
48
|
-
return clamp((t - tMin) / tRange, 0.0, 1.0);
|
|
49
|
-
}
|
|
50
|
-
if (scaleType == SCALE_TYPE_LOG) {
|
|
51
|
-
// Floor at the domain's own min, not at 1, so a domain sitting entirely
|
|
52
|
-
// below 1 (mappability, a methylation fraction, any normalized ratio) still
|
|
53
|
-
// has a range to spread over instead of collapsing to a flat baseline. Same
|
|
54
|
-
// rule and same reasoning as JS `makeScoreNormalizer`, which keeps its own
|
|
55
|
-
// hand-written copy because it hoists this arithmetic out of a per-feature
|
|
56
|
-
// loop — so this one is `//! js-export`ed as the ORACLE the two are swept
|
|
57
|
-
// against (`normalizeScoreParity.test.ts`), not to retire it.
|
|
38
|
+
t = symlogTransform(score, symlogConstant);
|
|
39
|
+
tMin = symlogTransform(domainMin, symlogConstant);
|
|
40
|
+
tMax = symlogTransform(domainMax, symlogConstant);
|
|
41
|
+
} else if (scaleType == SCALE_TYPE_LOG) {
|
|
42
|
+
// The domain's own min, so a domain entirely below 1 still spreads.
|
|
58
43
|
float floorV = domainMin > 0.0 ? domainMin : 1.0;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
44
|
+
t = log2(max(score, floorV));
|
|
45
|
+
tMin = log2(floorV);
|
|
46
|
+
tMax = log2(max(domainMax, floorV));
|
|
47
|
+
}
|
|
48
|
+
float tRange = tMax - tMin;
|
|
49
|
+
if (tRange <= 0.0) {
|
|
50
|
+
return t > tMin ? 1.0 : 0.0;
|
|
65
51
|
}
|
|
66
|
-
|
|
67
|
-
if (range <= 0.0) { return 0.0; }
|
|
68
|
-
return clamp((score - domainMin) / range, 0.0, 1.0);
|
|
52
|
+
return clamp((t - tMin) / tRange, 0.0, 1.0);
|
|
69
53
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// AUTO-GENERATED by packages/shader-tools/src/shader-codegen from spanMark.slang.
|
|
2
2
|
// Do not edit. Run `pnpm gen:shaders` to regenerate.
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export const GLSL_VERTEX = "#version 300 es\nprecision highp float;\nprecision highp int;\nstruct RowRectUniforms_0\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float minCellDenomPx_0;\n float minCellPx_0;\n float zero_0;\n float rowHeight_0;\n float rowProportion_0;\n float scrollTop_0;\n};\n\n\nlayout(std140) uniform Uniforms\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float minCellDenomPx_0;\n float minCellPx_0;\n float zero_0;\n float rowHeight_0;\n float rowProportion_0;\n float scrollTop_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\nfloat drawnRowHeightPx_0(float rowHeight_1, float rowProportion_1)\n{\n\n return max(rowHeight_1 * rowProportion_1, 1.0);\n}\n\nfloat rowBandOffsetPx_0(float rowHeight_2, float rowProportion_2)\n{\n\n return (rowHeight_2 - drawnRowHeightPx_0(rowHeight_2, rowProportion_2)) * 0.5;\n}\n\n\nstruct RowBand_0\n{\n float height_0;\n float offset_0;\n};\n\n\nRowBand_0 rowBandPx_0(float rowHeight_3, float rowProportion_3)\n{\n\n RowBand_0 band_0;\n band_0.height_0 = drawnRowHeightPx_0(rowHeight_3, rowProportion_3);\n band_0.offset_0 = rowBandOffsetPx_0(rowHeight_3, rowProportion_3);\n return band_0;\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_0)\n{\n float step_0 = 2.0 / bpRange_0.z;\n float _S5 = - (1.0 / hpZero_0);\n\n return dot(vec3(-1.0, max(splitPos_0.x - bpRange_0.x, _S5), max(splitPos_0.y - bpRange_0.y, _S5)), vec3(1.0, step_0, step_0));\n}\n\n\nfloat extendToMinWidthPx_0(float x1_0, float x2_0, float minWidth_0)\n{\n\n float dx_0 = x2_0 - x1_0;\n\n float _S6;\n if((abs(dx_0)) < minWidth_0)\n {\n\n if(dx_0 < 0.0)\n {\n\n _S6 = - minWidth_0;\n\n }\n else\n {\n\n _S6 = minWidth_0;\n\n }\n\n _S6 = x1_0 + _S6;\n\n }\n else\n {\n\n _S6 = x2_0;\n\n }\n\n return _S6;\n}\n\nfloat extendToMinWidthX_0(float x1_1, float x2_1, float minWidthPx_0, float canvasWidth_0)\n{\n\n return extendToMinWidthPx_0(x1_1, x2_1, minWidthPx_0 * 2.0 / canvasWidth_0);\n}\n\n\nfloat yPxToClipY_0(float yPx_0, float canvasHeight_1)\n{\n\n return 1.0 - yPx_0 / canvasHeight_1 * 2.0;\n}\n\n\nvec4 rowRectClipPos_0(uint startBp_0, uint endBp_0, float rowIndex_0, uint vid_1, RowRectUniforms_0 u_1)\n{\n\n vec2 local_0 = quadLocal_0(vid_1);\n\n RowBand_0 band_1 = rowBandPx_0(u_1.rowHeight_0, u_1.rowProportion_0);\n float rowY_0 = band_1.offset_0 + u_1.rowHeight_0 * rowIndex_0 - u_1.scrollTop_0;\n\n float sx1_0 = hpToClipX_0(hpSplitUint_0(startBp_0), u_1.bpRangeX_0, u_1.zero_0);\n\n return vec4(mix(sx1_0, extendToMinWidthX_0(sx1_0, hpToClipX_0(hpSplitUint_0(endBp_0), u_1.bpRangeX_0, u_1.zero_0), u_1.minCellPx_0, u_1.minCellDenomPx_0), local_0.x), yPxToClipY_0(mix(rowY_0, rowY_0 + band_1.height_0, local_0.y), u_1.canvasHeight_0), 0.0, 1.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\nstruct RowRectVsOut_0\n{\n vec4 position_0;\n vec4 color_0;\n};\n\n\nstruct RowRectInstance_0\n{\n uint x_0;\n uint x2_2;\n uint row_0;\n uint color_1;\n};\n\n\nRowRectVsOut_0 rowRectVertex_0(RowRectInstance_0 inst_0, uint vid_2, RowRectUniforms_0 u_2)\n{\n\n RowRectVsOut_0 o_0;\n o_0.position_0 = rowRectClipPos_0(inst_0.x_0, inst_0.x2_2, float(inst_0.row_0), vid_2, u_2);\n o_0.color_0 = unpackRGBA_0(inst_0.color_1);\n return o_0;\n}\n\n\nout vec4 v_color;\n\n\nlayout(location = 0)\nin uint a_x;\n\n\nlayout(location = 1)\nin uint a_x2;\n\n\nlayout(location = 2)\nin uint a_row;\n\n\nlayout(location = 3)\nin uint a_color;\n\n\nvoid main()\n{\n\n RowRectUniforms_0 _S7 = RowRectUniforms_0(u_0.bpRangeX_0, u_0.canvasHeight_0, u_0.minCellDenomPx_0, u_0.minCellPx_0, u_0.zero_0, u_0.rowHeight_0, u_0.rowProportion_0, u_0.scrollTop_0);\n\n RowRectInstance_0 _S8 = RowRectInstance_0(a_x, a_x2, a_row, a_color);\n RowRectVsOut_0 _S9 = rowRectVertex_0(_S8, uint(gl_VertexID), _S7);\n\n gl_Position = _S9.position_0;\n\n v_color = _S9.color_0;\n\n return;\n}\n\n"
|
|
7
|
-
|
|
8
|
-
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"
|
|
4
|
+
import type { ShaderSource } from '@jbrowse/render-core/hal'
|
|
9
5
|
|
|
10
6
|
export * from './spanMark.iface.generated.ts'
|
|
7
|
+
|
|
8
|
+
export const SOURCE: ShaderSource = {
|
|
9
|
+
wgsl: () => import('./spanMark.wgsl.generated.ts'),
|
|
10
|
+
glsl: () => import('./spanMark.glsl.generated.ts'),
|
|
11
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// AUTO-GENERATED by packages/shader-tools/src/shader-codegen from spanMark.slang.
|
|
2
|
+
// Do not edit. Run `pnpm gen:shaders` to regenerate.
|
|
3
|
+
|
|
4
|
+
export const GLSL_VERTEX = "#version 300 es\nprecision highp float;\nprecision highp int;\nstruct RowRectUniforms_0\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float minCellDenomPx_0;\n float minCellPx_0;\n float zero_0;\n float rowHeight_0;\n float rowProportion_0;\n float scrollTop_0;\n};\n\n\nlayout(std140) uniform Uniforms\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float minCellDenomPx_0;\n float minCellPx_0;\n float zero_0;\n float rowHeight_0;\n float rowProportion_0;\n float scrollTop_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\nfloat drawnRowHeightPx_0(float rowHeight_1, float rowProportion_1)\n{\n\n return max(rowHeight_1 * rowProportion_1, 1.0);\n}\n\nfloat rowBandOffsetPx_0(float rowHeight_2, float rowProportion_2)\n{\n\n return (rowHeight_2 - drawnRowHeightPx_0(rowHeight_2, rowProportion_2)) * 0.5;\n}\n\n\nstruct RowBand_0\n{\n float height_0;\n float offset_0;\n};\n\n\nRowBand_0 rowBandPx_0(float rowHeight_3, float rowProportion_3)\n{\n\n RowBand_0 band_0;\n band_0.height_0 = drawnRowHeightPx_0(rowHeight_3, rowProportion_3);\n band_0.offset_0 = rowBandOffsetPx_0(rowHeight_3, rowProportion_3);\n return band_0;\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_0)\n{\n float step_0 = 2.0 / bpRange_0.z;\n float _S5 = - (1.0 / hpZero_0);\n\n return dot(vec3(-1.0, max(splitPos_0.x - bpRange_0.x, _S5), max(splitPos_0.y - bpRange_0.y, _S5)), vec3(1.0, step_0, step_0));\n}\n\n\nfloat extendToMinWidthPx_0(float x1_0, float x2_0, float minWidth_0)\n{\n\n float dx_0 = x2_0 - x1_0;\n\n float _S6;\n if((abs(dx_0)) < minWidth_0)\n {\n\n if(dx_0 < 0.0)\n {\n\n _S6 = - minWidth_0;\n\n }\n else\n {\n\n _S6 = minWidth_0;\n\n }\n\n _S6 = x1_0 + _S6;\n\n }\n else\n {\n\n _S6 = x2_0;\n\n }\n\n return _S6;\n}\n\nfloat extendToMinWidthX_0(float x1_1, float x2_1, float minWidthPx_0, float canvasWidth_0)\n{\n\n return extendToMinWidthPx_0(x1_1, x2_1, minWidthPx_0 * 2.0 / canvasWidth_0);\n}\n\n\nfloat yPxToClipY_0(float yPx_0, float canvasHeight_1)\n{\n\n return 1.0 - yPx_0 / canvasHeight_1 * 2.0;\n}\n\n\nvec4 rowRectClipPos_0(uint startBp_0, uint endBp_0, float rowIndex_0, uint vid_1, RowRectUniforms_0 u_1)\n{\n\n vec2 local_0 = quadLocal_0(vid_1);\n\n RowBand_0 band_1 = rowBandPx_0(u_1.rowHeight_0, u_1.rowProportion_0);\n float rowY_0 = band_1.offset_0 + u_1.rowHeight_0 * rowIndex_0 - u_1.scrollTop_0;\n\n float sx1_0 = hpToClipX_0(hpSplitUint_0(startBp_0), u_1.bpRangeX_0, u_1.zero_0);\n\n return vec4(mix(sx1_0, extendToMinWidthX_0(sx1_0, hpToClipX_0(hpSplitUint_0(endBp_0), u_1.bpRangeX_0, u_1.zero_0), u_1.minCellPx_0, u_1.minCellDenomPx_0), local_0.x), yPxToClipY_0(mix(rowY_0, rowY_0 + band_1.height_0, local_0.y), u_1.canvasHeight_0), 0.0, 1.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\nstruct RowRectVsOut_0\n{\n vec4 position_0;\n vec4 color_0;\n};\n\n\nstruct RowRectInstance_0\n{\n uint x_0;\n uint x2_2;\n uint row_0;\n uint color_1;\n};\n\n\nRowRectVsOut_0 rowRectVertex_0(RowRectInstance_0 inst_0, uint vid_2, RowRectUniforms_0 u_2)\n{\n\n RowRectVsOut_0 o_0;\n o_0.position_0 = rowRectClipPos_0(inst_0.x_0, inst_0.x2_2, float(inst_0.row_0), vid_2, u_2);\n o_0.color_0 = unpackRGBA_0(inst_0.color_1);\n return o_0;\n}\n\n\nout vec4 v_color;\n\n\nlayout(location = 0)\nin uint a_x;\n\n\nlayout(location = 1)\nin uint a_x2;\n\n\nlayout(location = 2)\nin uint a_row;\n\n\nlayout(location = 3)\nin uint a_color;\n\n\nvoid main()\n{\n\n RowRectUniforms_0 _S7 = RowRectUniforms_0(u_0.bpRangeX_0, u_0.canvasHeight_0, u_0.minCellDenomPx_0, u_0.minCellPx_0, u_0.zero_0, u_0.rowHeight_0, u_0.rowProportion_0, u_0.scrollTop_0);\n\n RowRectInstance_0 _S8 = RowRectInstance_0(a_x, a_x2, a_row, a_color);\n RowRectVsOut_0 _S9 = rowRectVertex_0(_S8, uint(gl_VertexID), _S7);\n\n gl_Position = _S9.position_0;\n\n v_color = _S9.color_0;\n\n return;\n}\n\n"
|
|
5
|
+
|
|
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"
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import type { VertexAttributeLayout, ShaderBinding } from '@jbrowse/render-core/hal'
|
|
5
5
|
|
|
6
6
|
export const BINDINGS: readonly ShaderBinding[] = [
|
|
7
|
-
{ index: 1, kind: 'uniform', name: 'u' },
|
|
7
|
+
{ index: 1, kind: 'uniform', name: 'u', stages: ['vertex'] },
|
|
8
8
|
]
|
|
9
9
|
|
|
10
10
|
export const VERTS_PER_INSTANCE = 6
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// AUTO-GENERATED by packages/shader-tools/src/shader-codegen from spanMark.slang.
|
|
2
|
+
// Do not edit. Run `pnpm gen:shaders` to regenerate.
|
|
3
|
+
|
|
4
|
+
export const WGSL_SOURCE = "struct RowRectUniforms_std140_0\n{\n @align(16) bpRangeX_0 : vec3<f32>,\n @align(4) canvasHeight_0 : f32,\n @align(16) minCellDenomPx_0 : f32,\n @align(4) minCellPx_0 : f32,\n @align(8) zero_0 : f32,\n @align(4) rowHeight_0 : f32,\n @align(16) rowProportion_0 : f32,\n @align(4) scrollTop_0 : f32,\n};\n\n@binding(1) @group(0) var<uniform> u_0 : RowRectUniforms_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 drawnRowHeightPx_0( rowHeight_1 : f32, rowProportion_1 : f32) -> f32\n{\n return max(rowHeight_1 * rowProportion_1, 1.0f);\n}\n\nfn rowBandOffsetPx_0( rowHeight_2 : f32, rowProportion_2 : f32) -> f32\n{\n return (rowHeight_2 - drawnRowHeightPx_0(rowHeight_2, rowProportion_2)) * 0.5f;\n}\n\nstruct RowBand_0\n{\n height_0 : f32,\n offset_0 : f32,\n};\n\nfn rowBandPx_0( rowHeight_3 : f32, rowProportion_3 : f32) -> RowBand_0\n{\n var band_0 : RowBand_0;\n band_0.height_0 = drawnRowHeightPx_0(rowHeight_3, rowProportion_3);\n band_0.offset_0 = rowBandOffsetPx_0(rowHeight_3, rowProportion_3);\n return band_0;\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_0 : f32) -> f32\n{\n var step_0 : f32 = 2.0f / bpRange_0.z;\n var _S5 : f32 = - (1.0f / hpZero_0);\n return dot(vec3<f32>(-1.0f, max(splitPos_0.x - bpRange_0.x, _S5), max(splitPos_0.y - bpRange_0.y, _S5)), vec3<f32>(1.0f, step_0, step_0));\n}\n\nfn extendToMinWidthPx_0( x1_0 : f32, x2_0 : f32, minWidth_0 : f32) -> f32\n{\n var dx_0 : f32 = x2_0 - x1_0;\n var _S6 : f32;\n if((abs(dx_0)) < minWidth_0)\n {\n if(dx_0 < 0.0f)\n {\n _S6 = - minWidth_0;\n }\n else\n {\n _S6 = minWidth_0;\n }\n _S6 = x1_0 + _S6;\n }\n else\n {\n _S6 = x2_0;\n }\n return _S6;\n}\n\nfn extendToMinWidthX_0( x1_1 : f32, x2_1 : f32, minWidthPx_0 : f32, canvasWidth_0 : f32) -> f32\n{\n return extendToMinWidthPx_0(x1_1, x2_1, minWidthPx_0 * 2.0f / canvasWidth_0);\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 rowRectClipPos_0( startBp_0 : u32, endBp_0 : u32, rowIndex_0 : f32, vid_1 : u32, u_1 : ptr<function, RowRectUniforms_std140_0>) -> vec4<f32>\n{\n var local_0 : vec2<f32> = quadLocal_0(vid_1);\n var band_1 : RowBand_0 = rowBandPx_0((*u_1).rowHeight_0, (*u_1).rowProportion_0);\n var rowY_0 : f32 = band_1.offset_0 + (*u_1).rowHeight_0 * rowIndex_0 - (*u_1).scrollTop_0;\n var sx1_0 : f32 = hpToClipX_0(hpSplitUint_0(startBp_0), (*u_1).bpRangeX_0, (*u_1).zero_0);\n return vec4<f32>(mix(sx1_0, extendToMinWidthX_0(sx1_0, hpToClipX_0(hpSplitUint_0(endBp_0), (*u_1).bpRangeX_0, (*u_1).zero_0), (*u_1).minCellPx_0, (*u_1).minCellDenomPx_0), local_0.x), yPxToClipY_0(mix(rowY_0, rowY_0 + band_1.height_0, local_0.y), (*u_1).canvasHeight_0), 0.0f, 1.0f);\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\nstruct RowRectVsOut_0\n{\n @builtin(position) position_0 : vec4<f32>,\n @location(0) color_0 : vec4<f32>,\n};\n\nstruct RowRectInstance_0\n{\n x_0 : u32,\n x2_2 : u32,\n row_0 : u32,\n color_1 : u32,\n};\n\nfn rowRectVertex_0( inst_0 : RowRectInstance_0, vid_2 : u32, u_2 : ptr<function, RowRectUniforms_std140_0>) -> RowRectVsOut_0\n{\n var o_0 : RowRectVsOut_0;\n var _S7 : vec4<f32> = rowRectClipPos_0(inst_0.x_0, inst_0.x2_2, f32(inst_0.row_0), vid_2, &((*u_2)));\n o_0.position_0 = _S7;\n o_0.color_0 = unpackRGBA_0(inst_0.color_1);\n return o_0;\n}\n\nstruct vertexInput_0\n{\n @location(0) x_1 : u32,\n @location(1) x2_3 : u32,\n @location(2) row_1 : u32,\n @location(3) color_2 : u32,\n};\n\n@vertex\nfn vs_main( _S8 : vertexInput_0, @builtin(vertex_index) vid_3 : u32) -> RowRectVsOut_0\n{\n var _S9 : RowRectInstance_0 = RowRectInstance_0( _S8.x_1, _S8.x2_3, _S8.row_1, _S8.color_2 );\n var _S10 : RowRectUniforms_std140_0 = u_0;\n var _S11 : RowRectVsOut_0 = rowRectVertex_0(_S9, vid_3, &(_S10));\n return _S11;\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};\n\n@fragment\nfn fs_main( _S12 : pixelInput_0, @builtin(position) position_1 : vec4<f32>) -> pixelOutput_0\n{\n var _S13 : pixelOutput_0 = pixelOutput_0( _S12.color_3 );\n return _S13;\n}\n\n"
|
|
@@ -1,52 +1,15 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
// -log10 p is already a pre-transform); `valueToYPxScaled` below takes a
|
|
6
|
-
// declared one.
|
|
7
|
-
//
|
|
8
|
-
// Two shapes compose it (ADR-095): `pointMark` reads it for a glyph centre and
|
|
9
|
-
// `barMark` for both cuts of a bar. Each keeps its own anchor (ADR-097) — a
|
|
10
|
-
// point centres on the value, a bar grows from `origin` to it — so only the
|
|
11
|
-
// scale lives here.
|
|
12
|
-
//
|
|
13
|
-
// max(range, 1e-6) guards a degenerate (min == max) domain from dividing by
|
|
14
|
-
// zero. JS spelled that guard `|| 1`, and the two are NOT the same: `|| 1`
|
|
15
|
-
// invents a phantom unit-wide domain, so with bounds pinned to a single value
|
|
16
|
-
// a value half a unit above it drew half-way up the Canvas2D canvas while the
|
|
17
|
-
// GPU clamped it to the top. Pinning a degenerate domain means everything above
|
|
18
|
-
// it is off the top, which is what this does; the parity test pins the case.
|
|
19
|
-
//
|
|
20
|
-
// A declared log scale takes the log arm of `scoreScale`'s `normalizeScore`,
|
|
21
|
-
// the normalizer wiggle and the coverage band are already placed by, so a mark
|
|
22
|
-
// display's axis ticks and its shader agree by construction. The linear arm
|
|
23
|
-
// stays this module's own: `normalizeScore` answers 0 on a degenerate domain
|
|
24
|
-
// and this answers 1, and that difference is a pinned cross-backend value
|
|
25
|
-
// (ADR-097).
|
|
26
|
-
//
|
|
27
|
-
// The JS twin is lifted by `pointMark.slang`'s `//! js-export` rather than
|
|
28
|
-
// here, the way hpmath's `expandToMinWidthPx` reaches JS through
|
|
29
|
-
// `coverageBar.slang`: one twin, in the generated module every consumer of the
|
|
30
|
-
// scale already imports.
|
|
1
|
+
// A quantitative mark's value → canvas y: `scoreScale`'s normalizer, flipped
|
|
2
|
+
// so a bigger value sits higher. Only the scale lives here; each shape keeps
|
|
3
|
+
// its own anchor (ADR-097). `pointMark.slang` lifts the JS twin.
|
|
4
|
+
//! js-skip: valueToYPx — the linear case of valueToYPxScaled, whose twin pointMark.slang lifts; a shader reading it alone (the score example's scoreBarHeightPx) lifts the caller it sits inside
|
|
31
5
|
module valueScale;
|
|
32
6
|
|
|
33
7
|
import scoreScale;
|
|
34
8
|
|
|
35
|
-
public float
|
|
36
|
-
|
|
37
|
-
(value - domainMin) / max(domainMax - domainMin, 1e-6),
|
|
38
|
-
0.0,
|
|
39
|
-
1.0,
|
|
40
|
-
);
|
|
41
|
-
return (1.0 - norm) * h;
|
|
9
|
+
public float valueToYPxScaled(float value, float domainMin, float domainMax, float h, int scaleType) {
|
|
10
|
+
return (1.0 - normalizeScore(value, domainMin, domainMax, scaleType, 1.0)) * h;
|
|
42
11
|
}
|
|
43
12
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
// above.
|
|
47
|
-
public float valueToYPxScaled(float value, float domainMin, float domainMax, float h, int scaleType) {
|
|
48
|
-
if (scaleType == SCALE_TYPE_LOG) {
|
|
49
|
-
return (1.0 - normalizeScore(value, domainMin, domainMax, SCALE_TYPE_LOG, 1.0)) * h;
|
|
50
|
-
}
|
|
51
|
-
return valueToYPx(value, domainMin, domainMax, h);
|
|
13
|
+
public float valueToYPx(float value, float domainMin, float domainMax, float h) {
|
|
14
|
+
return valueToYPxScaled(value, domainMin, domainMax, h, 0);
|
|
52
15
|
}
|