@jbrowse/render-core 5.0.0-beta.3 → 5.0.0-beta.4
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/hal/webgpuHal.js +6 -6
- package/esm/marks/markBackend.d.ts +7 -7
- package/esm/marks/markBackend.js +20 -16
- package/esm/marks/markHit.d.ts +25 -0
- package/esm/marks/markHit.js +46 -0
- package/esm/marks/pointMark.js +12 -19
- package/esm/marks/spanMark.js +5 -17
- package/esm/marks/types.d.ts +11 -1
- package/esm/marks/types.js +24 -3
- package/esm/renderBlock.d.ts +14 -0
- package/esm/renderBlock.js +25 -0
- package/esm/shaders/pointMark.generated.d.ts +2 -2
- package/esm/shaders/pointMark.generated.js +2 -2
- package/esm/shaders/pointMark.js.generated.d.ts +1 -0
- package/esm/shaders/pointMark.js.generated.js +3 -0
- package/package.json +2 -1
- package/src/shaders/pointMark.generated.ts +2 -2
- package/src/shaders/pointMark.js.generated.ts +4 -0
- package/src/shaders/pointMark.slang +24 -11
package/esm/hal/webgpuHal.js
CHANGED
|
@@ -375,12 +375,12 @@ export class WebGPUHal extends GpuHalBase {
|
|
|
375
375
|
createTexture(passId, binding, data, width, height) {
|
|
376
376
|
const existing = this.passTextures.get(passId);
|
|
377
377
|
if (existing) {
|
|
378
|
-
// Same hazard as a buffer,
|
|
379
|
-
// `uploadTexture` in tree is a colour ramp
|
|
380
|
-
//
|
|
381
|
-
//
|
|
382
|
-
//
|
|
383
|
-
//
|
|
378
|
+
// Same hazard as a buffer, and no longer a hypothetical one: every
|
|
379
|
+
// `uploadTexture` in tree is a colour ramp, and since the ramp became a
|
|
380
|
+
// `defineMark` `texture` they are all written by `GpuMarkBackend`'s
|
|
381
|
+
// `bindRamp` from inside `drawRegion` — mid-frame, between an encoded
|
|
382
|
+
// draw and its submit. The deferral is what makes replacing one there
|
|
383
|
+
// safe.
|
|
384
384
|
this.destroyWhenIdle(existing.texture);
|
|
385
385
|
}
|
|
386
386
|
const texture = this.device.createTexture({
|
|
@@ -7,12 +7,7 @@ import type { ClearColor, PerRegionRenderingBackend } from '../perRegionRenderin
|
|
|
7
7
|
import type { RenderBlock } from '../renderBlock.ts';
|
|
8
8
|
import type { FrameDimensions } from '../renderingBackendBase.ts';
|
|
9
9
|
import type { Mark } from './types.ts';
|
|
10
|
-
/**
|
|
11
|
-
* Pack and upload one region's buffers for a mark list — every mark that owns
|
|
12
|
-
* one, which is the whole list minus those drawing off another's (`bufferOf`).
|
|
13
|
-
* That skip is the reason a display's upload is this call rather than a loop:
|
|
14
|
-
* uploading to a borrowed pass is silent, and its buffer is the lender's.
|
|
15
|
-
*/
|
|
10
|
+
/** Pack and upload one region's buffers for a mark list. */
|
|
16
11
|
export declare function uploadMarks<TRegion, TState extends FrameDimensions>(hal: GpuHal, regionKey: number, marks: readonly Mark<TRegion, TState>[], data: TRegion): void;
|
|
17
12
|
/**
|
|
18
13
|
* Draw one already-clipped block through a mark list.
|
|
@@ -23,6 +18,12 @@ export declare function uploadMarks<TRegion, TState extends FrameDimensions>(hal
|
|
|
23
18
|
* coverage strip inside the column it hands over. `GpuPerRegionRenderingBackend`
|
|
24
19
|
* sets both per block already, so for a backend on that scaffold the viewport
|
|
25
20
|
* set here is the same rect twice.
|
|
21
|
+
*
|
|
22
|
+
* A caller that narrows it must hand over marks declaring no `band`, and that
|
|
23
|
+
* is the one way the two clips do not compose: a banded mark scissors to its
|
|
24
|
+
* strip and hands the BLOCK COLUMN back rather than what the caller had. The
|
|
25
|
+
* split is deliberate — `render-core/CLAUDE.md` §Drawing has which displays
|
|
26
|
+
* take which side — but nothing enforces it, so it is stated at both.
|
|
26
27
|
*/
|
|
27
28
|
export declare function drawMarks<TRegion, TState extends FrameDimensions>(hal: GpuHal, scratch: ArrayBuffer, marks: readonly Mark<TRegion, TState>[], block: RenderBlock, clip: BlockClipResult, region: TRegion, state: TState, regionKey: number): void;
|
|
28
29
|
/**
|
|
@@ -36,7 +37,6 @@ export declare class GpuMarkBackend<TRegion, TState extends FrameDimensions> ext
|
|
|
36
37
|
protected regionPasses: InstancePass<TRegion>[];
|
|
37
38
|
constructor(hal: GpuHal, marks: readonly Mark<TRegion, TState>[], clear?: ((state: TState) => ClearColor) | undefined);
|
|
38
39
|
protected clearColor(state: TState): ClearColor;
|
|
39
|
-
upload(regionKey: number, data: TRegion): void;
|
|
40
40
|
private boundRamps;
|
|
41
41
|
private bindRamp;
|
|
42
42
|
protected drawRegion(block: RenderBlock, clip: BlockClipResult, region: TRegion, state: TState): void;
|
package/esm/marks/markBackend.js
CHANGED
|
@@ -3,17 +3,17 @@ import { createRenderingBackend } from '../createRenderingBackend.js';
|
|
|
3
3
|
import { uploadPass } from '../instancePass.js';
|
|
4
4
|
import { Canvas2DPerRegionRenderingBackend, GpuPerRegionRenderingBackend, } from '../perRegionRenderingBackend.js';
|
|
5
5
|
import { paintMarkBlocks } from './markPaint.js';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
// The passes a mark list owns a buffer for: the whole list minus those drawing
|
|
7
|
+
// off another's (`bufferOf`). Uploading to a borrowed pass is silent and its
|
|
8
|
+
// buffer is the lender's, so the skip is stated once, here — module-local,
|
|
9
|
+
// because `marks/backend` is a published subpath and nothing outside wants it.
|
|
10
|
+
function ownedPasses(marks) {
|
|
11
|
+
return marks.filter(m => !m.bufferOf).map(m => m.pass);
|
|
12
|
+
}
|
|
13
|
+
/** Pack and upload one region's buffers for a mark list. */
|
|
12
14
|
export function uploadMarks(hal, regionKey, marks, data) {
|
|
13
|
-
for (const
|
|
14
|
-
|
|
15
|
-
uploadPass(hal, regionKey, mark.pass, data);
|
|
16
|
-
}
|
|
15
|
+
for (const pass of ownedPasses(marks)) {
|
|
16
|
+
uploadPass(hal, regionKey, pass, data);
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
@@ -25,6 +25,12 @@ export function uploadMarks(hal, regionKey, marks, data) {
|
|
|
25
25
|
* coverage strip inside the column it hands over. `GpuPerRegionRenderingBackend`
|
|
26
26
|
* sets both per block already, so for a backend on that scaffold the viewport
|
|
27
27
|
* set here is the same rect twice.
|
|
28
|
+
*
|
|
29
|
+
* A caller that narrows it must hand over marks declaring no `band`, and that
|
|
30
|
+
* is the one way the two clips do not compose: a banded mark scissors to its
|
|
31
|
+
* strip and hands the BLOCK COLUMN back rather than what the caller had. The
|
|
32
|
+
* split is deliberate — `render-core/CLAUDE.md` §Drawing has which displays
|
|
33
|
+
* take which side — but nothing enforces it, so it is stated at both.
|
|
28
34
|
*/
|
|
29
35
|
export function drawMarks(hal, scratch, marks, block, clip, region, state, regionKey) {
|
|
30
36
|
hal.setViewport(clip.pxX, 0, clip.pxW, clip.pxH);
|
|
@@ -46,20 +52,18 @@ const INERT_RAMP = new Uint8Array(COLOR_RAMP_LUT_ENTRIES * 4);
|
|
|
46
52
|
export class GpuMarkBackend extends GpuPerRegionRenderingBackend {
|
|
47
53
|
marks;
|
|
48
54
|
clear;
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
regionPasses
|
|
55
|
+
// The base's upload loop already IS the mark walk, so this backend names its
|
|
56
|
+
// passes instead of overriding `upload` with a second spelling of it.
|
|
57
|
+
regionPasses;
|
|
52
58
|
constructor(hal, marks, clear) {
|
|
53
59
|
super(hal);
|
|
54
60
|
this.marks = marks;
|
|
55
61
|
this.clear = clear;
|
|
62
|
+
this.regionPasses = ownedPasses(marks);
|
|
56
63
|
}
|
|
57
64
|
clearColor(state) {
|
|
58
65
|
return this.clear ? this.clear(state) : super.clearColor(state);
|
|
59
66
|
}
|
|
60
|
-
upload(regionKey, data) {
|
|
61
|
-
uploadMarks(this.hal, regionKey, this.marks, data);
|
|
62
|
-
}
|
|
63
67
|
// The ramp each textured pass holds, by the table's identity — the mirror of
|
|
64
68
|
// the one texture the HAL keeps per pass, so an unchanged ramp costs a frame
|
|
65
69
|
// nothing and a backend rebuilt after context loss re-uploads. Per pass and
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { MarkHit } from './types.ts';
|
|
2
|
+
/** One instance's ink measured against a cursor — a `MarkHit` before it is one. */
|
|
3
|
+
export type InkHit = Omit<MarkHit, 'index'>;
|
|
4
|
+
/**
|
|
5
|
+
* Where a rect's ink sits nearest `(xPx, yPx)`, and how far: the point itself
|
|
6
|
+
* where the cursor is inside, else the nearest point on the edge.
|
|
7
|
+
*/
|
|
8
|
+
export declare function inkOnRect(xPx: number, yPx: number, left: number, top: number, width: number, height: number): InkHit;
|
|
9
|
+
/** The same for a mark with no extent to clamp into. */
|
|
10
|
+
export declare function inkAtPoint(xPx: number, yPx: number, x: number, y: number): InkHit;
|
|
11
|
+
/**
|
|
12
|
+
* The nearest of `candidates` by where each one's ink is, or undefined when
|
|
13
|
+
* none beats `maxDistSq`.
|
|
14
|
+
*
|
|
15
|
+
* This is the whole of every shape's `hitNearest` but the geometry: `inkAt`
|
|
16
|
+
* answers where instance `i` put ink and how far that is, and this keeps the
|
|
17
|
+
* closest. Only a STRICTLY nearer candidate replaces the best, so on a tie the
|
|
18
|
+
* first wins — which is what makes a caller that iterates back to front get the
|
|
19
|
+
* mark on top, and it is a rule that used to be spelled out five times over.
|
|
20
|
+
*
|
|
21
|
+
* `inkAt` may answer `undefined` for an instance that drew nothing at all, as
|
|
22
|
+
* against one that drew somewhere far away: a bar clipped out of its band has
|
|
23
|
+
* no ink to be near.
|
|
24
|
+
*/
|
|
25
|
+
export declare function nearestInk(candidates: Iterable<number>, maxDistSq: number, inkAt: (index: number) => InkHit | undefined): MarkHit | undefined;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a rect's ink sits nearest `(xPx, yPx)`, and how far: the point itself
|
|
3
|
+
* where the cursor is inside, else the nearest point on the edge.
|
|
4
|
+
*/
|
|
5
|
+
export function inkOnRect(xPx, yPx, left, top, width, height) {
|
|
6
|
+
const x = Math.min(Math.max(xPx, left), left + width);
|
|
7
|
+
const y = Math.min(Math.max(yPx, top), top + height);
|
|
8
|
+
const dx = xPx - x;
|
|
9
|
+
const dy = yPx - y;
|
|
10
|
+
return { x, y, distSq: dx * dx + dy * dy };
|
|
11
|
+
}
|
|
12
|
+
/** The same for a mark with no extent to clamp into. */
|
|
13
|
+
export function inkAtPoint(xPx, yPx, x, y) {
|
|
14
|
+
const dx = xPx - x;
|
|
15
|
+
const dy = yPx - y;
|
|
16
|
+
return { x, y, distSq: dx * dx + dy * dy };
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The nearest of `candidates` by where each one's ink is, or undefined when
|
|
20
|
+
* none beats `maxDistSq`.
|
|
21
|
+
*
|
|
22
|
+
* This is the whole of every shape's `hitNearest` but the geometry: `inkAt`
|
|
23
|
+
* answers where instance `i` put ink and how far that is, and this keeps the
|
|
24
|
+
* closest. Only a STRICTLY nearer candidate replaces the best, so on a tie the
|
|
25
|
+
* first wins — which is what makes a caller that iterates back to front get the
|
|
26
|
+
* mark on top, and it is a rule that used to be spelled out five times over.
|
|
27
|
+
*
|
|
28
|
+
* `inkAt` may answer `undefined` for an instance that drew nothing at all, as
|
|
29
|
+
* against one that drew somewhere far away: a bar clipped out of its band has
|
|
30
|
+
* no ink to be near.
|
|
31
|
+
*/
|
|
32
|
+
export function nearestInk(candidates, maxDistSq, inkAt) {
|
|
33
|
+
let best;
|
|
34
|
+
let bestDistSq = maxDistSq;
|
|
35
|
+
for (const index of candidates) {
|
|
36
|
+
const ink = inkAt(index);
|
|
37
|
+
if (ink && ink.distSq < bestDistSq) {
|
|
38
|
+
bestDistSq = ink.distSq;
|
|
39
|
+
// Field by field, not `{ index, ...ink }`, which is both slower and one
|
|
40
|
+
// shape away from minting a hidden class per ink source and making every
|
|
41
|
+
// downstream `hit.x` read polymorphic.
|
|
42
|
+
best = { index, x: ink.x, y: ink.y, distSq: ink.distSq };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return best;
|
|
46
|
+
}
|
package/esm/marks/pointMark.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { bpRangeXTuple } from '../blockClipUtils.js';
|
|
2
2
|
import { getDpr, makeBpMapper } from '../canvas2dUtils.js';
|
|
3
3
|
import * as shader from '../shaders/pointMark.generated.js';
|
|
4
|
-
import { valueToYPx } from '../shaders/pointMark.js.generated.js';
|
|
4
|
+
import { pointDrawsBar, valueToYPx } from '../shaders/pointMark.js.generated.js';
|
|
5
5
|
import { slangPass } from '../slangPass.js';
|
|
6
6
|
import { abgrToCssRgba } from './colorFill.js';
|
|
7
7
|
import { appendGlyph } from './glyphPaint.js';
|
|
8
|
+
import { inkAtPoint, inkOnRect, nearestInk } from './markHit.js';
|
|
8
9
|
export const pointMark = {
|
|
9
10
|
id: 'point',
|
|
10
11
|
pass: {
|
|
@@ -57,7 +58,7 @@ export const pointMark = {
|
|
|
57
58
|
const xEnd = bpToPx(x2[i]);
|
|
58
59
|
const yPx = valueToYPx(y[i], domainMin, domainMax, canvasHeight);
|
|
59
60
|
const widthPx = Math.abs(xEnd - xStart);
|
|
60
|
-
if (widthPx
|
|
61
|
+
if (pointDrawsBar(widthPx, r)) {
|
|
61
62
|
ctx.rect(Math.min(xStart, xEnd), yPx - r, widthPx, diameterPx);
|
|
62
63
|
}
|
|
63
64
|
else {
|
|
@@ -73,26 +74,18 @@ export const pointMark = {
|
|
|
73
74
|
const domainMin = domain[0];
|
|
74
75
|
const domainMax = domain[1];
|
|
75
76
|
const canvasHeight = frame.canvasHeight;
|
|
76
|
-
|
|
77
|
-
let bestDistSq = maxDistSq;
|
|
78
|
-
for (const i of candidates) {
|
|
77
|
+
return nearestInk(candidates, maxDistSq, i => {
|
|
79
78
|
const xStart = bpToPx(x[i]);
|
|
80
79
|
const xEnd = bpToPx(x2[i]);
|
|
81
|
-
|
|
82
|
-
//
|
|
83
|
-
// glyph
|
|
80
|
+
const cy = valueToYPx(y[i], domainMin, domainMax, canvasHeight);
|
|
81
|
+
// A bar is the rect the painter fills, unpadded on every side, so the
|
|
82
|
+
// drawn bar and this box are one rectangle. A glyph has no rect to clamp
|
|
83
|
+
// into and offers its centre.
|
|
84
84
|
const lo = Math.min(xStart, xEnd);
|
|
85
85
|
const hi = Math.max(xStart, xEnd);
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const distSq = dx * dx + dy * dy;
|
|
91
|
-
if (distSq < bestDistSq) {
|
|
92
|
-
bestDistSq = distSq;
|
|
93
|
-
best = { index: i, x: ptX, y: ptY, distSq };
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return best;
|
|
86
|
+
return pointDrawsBar(hi - lo, diameterPx / 2)
|
|
87
|
+
? inkOnRect(xPx, yPx, lo, cy - diameterPx / 2, hi - lo, diameterPx)
|
|
88
|
+
: inkAtPoint(xPx, yPx, xStart, cy);
|
|
89
|
+
});
|
|
97
90
|
},
|
|
98
91
|
};
|
package/esm/marks/spanMark.js
CHANGED
|
@@ -4,6 +4,7 @@ import { drawnRowHeightPx, rowBandOffsetPx, } from '../shaders/rowRect.js.genera
|
|
|
4
4
|
import * as shader from '../shaders/spanMark.generated.js';
|
|
5
5
|
import { slangPass } from '../slangPass.js';
|
|
6
6
|
import { makeAbgrFill } from './colorFill.js';
|
|
7
|
+
import { inkOnRect, nearestInk } from './markHit.js';
|
|
7
8
|
export const spanMark = {
|
|
8
9
|
id: 'span',
|
|
9
10
|
pass: {
|
|
@@ -46,26 +47,13 @@ export const spanMark = {
|
|
|
46
47
|
const h = drawnRowHeightPx(rowHeight, rowProportion);
|
|
47
48
|
const offset = rowBandOffsetPx(rowHeight, rowProportion);
|
|
48
49
|
const bpToPx = makeBpMapper(block);
|
|
49
|
-
|
|
50
|
-
let bestDistSq = maxDistSq;
|
|
51
|
-
for (const i of candidates) {
|
|
50
|
+
return nearestInk(candidates, maxDistSq, i => {
|
|
52
51
|
const xa = bpToPx(x[i]);
|
|
53
52
|
const xb = bpToPx(x2[i]);
|
|
54
53
|
const width = Math.max(minWidthPx, Math.abs(xb - xa));
|
|
55
|
-
const left = spanLeft(xa, xb, width);
|
|
56
|
-
const top = offset + rowHeight * row[i] - scrollTop;
|
|
57
54
|
// the rect `paintBlock` fills, less `seamPx`, which is painter-only
|
|
58
|
-
// overdraw
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const dx = xPx - nx;
|
|
62
|
-
const dy = yPx - ny;
|
|
63
|
-
const distSq = dx * dx + dy * dy;
|
|
64
|
-
if (distSq < bestDistSq) {
|
|
65
|
-
bestDistSq = distSq;
|
|
66
|
-
best = { index: i, x: nx, y: ny, distSq };
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return best;
|
|
55
|
+
// overdraw
|
|
56
|
+
return inkOnRect(xPx, yPx, spanLeft(xa, xb, width), offset + rowHeight * row[i] - scrollTop, width, h);
|
|
57
|
+
});
|
|
70
58
|
},
|
|
71
59
|
};
|
package/esm/marks/types.d.ts
CHANGED
|
@@ -69,7 +69,9 @@ export interface MarkShape<TChannels, TParams> {
|
|
|
69
69
|
/**
|
|
70
70
|
* The shape's draw predicate over (block, frame, params) — not over its
|
|
71
71
|
* instances, which it is never handed. Both backends skip the block when it
|
|
72
|
-
* says no
|
|
72
|
+
* says no, and so does `hitNearest`: a block with no ink on it has nothing
|
|
73
|
+
* to be near. Optional: a shape whose every block can carry ink leaves it
|
|
74
|
+
* off.
|
|
73
75
|
*
|
|
74
76
|
* Placement is one use: the canvas continuation marker exists only where a
|
|
75
77
|
* block meets a canvas edge, and an interior block would otherwise shade a
|
|
@@ -189,6 +191,14 @@ export interface Mark<TRegion, TState extends MarkFrame> {
|
|
|
189
191
|
* uploads it once per pass and re-uploads only when the bytes' identity moves,
|
|
190
192
|
* so a ramp change costs one texture and no instance byte.
|
|
191
193
|
*
|
|
194
|
+
* **Per pass per FRAME, though the lens is handed a region too.** LD reads its
|
|
195
|
+
* ramp off the payload's own metric — a pre-computed file with no D' column
|
|
196
|
+
* downgrades the request, and the metric that arrived is the authoritative one
|
|
197
|
+
* — which is exact because LD holds one region. A display with several regions
|
|
198
|
+
* wanting different ramps for one pass would re-upload the texture per region
|
|
199
|
+
* per frame; correct, since each recorded draw keeps the table bound when it
|
|
200
|
+
* was encoded, but a texture per region per frame is not what this is for.
|
|
201
|
+
*
|
|
192
202
|
* `band` is the strip of the canvas the mark is clipped to, for a display that
|
|
193
203
|
* stacks bands on one canvas (MAF's coverage strip over its rows viewport).
|
|
194
204
|
* The GPU scissors to it and Canvas2D clips to it, a zero-height band draws
|
package/esm/marks/types.js
CHANGED
|
@@ -35,6 +35,14 @@ import { devicePxBand, withClip } from '../canvas2dUtils.js';
|
|
|
35
35
|
* uploads it once per pass and re-uploads only when the bytes' identity moves,
|
|
36
36
|
* so a ramp change costs one texture and no instance byte.
|
|
37
37
|
*
|
|
38
|
+
* **Per pass per FRAME, though the lens is handed a region too.** LD reads its
|
|
39
|
+
* ramp off the payload's own metric — a pre-computed file with no D' column
|
|
40
|
+
* downgrades the request, and the metric that arrived is the authoritative one
|
|
41
|
+
* — which is exact because LD holds one region. A display with several regions
|
|
42
|
+
* wanting different ramps for one pass would re-upload the texture per region
|
|
43
|
+
* per frame; correct, since each recorded draw keeps the table bound when it
|
|
44
|
+
* was encoded, but a texture per region per frame is not what this is for.
|
|
45
|
+
*
|
|
38
46
|
* `band` is the strip of the canvas the mark is clipped to, for a display that
|
|
39
47
|
* stacks bands on one canvas (MAF's coverage strip over its rows viewport).
|
|
40
48
|
* The GPU scissors to it and Canvas2D clips to it, a zero-height band draws
|
|
@@ -109,10 +117,23 @@ export function defineMark(spec) {
|
|
|
109
117
|
},
|
|
110
118
|
hitNearest: shape.hitNearest
|
|
111
119
|
? (region, block, state, xPx, yPx, candidates, maxDistSq) => {
|
|
120
|
+
const strip = band?.(state);
|
|
112
121
|
const c = channels(region);
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
122
|
+
let hit;
|
|
123
|
+
// The three gates `paintBlock` takes, in its order — the band on its
|
|
124
|
+
// HEIGHT, as there, so a band both backends decline answers nothing
|
|
125
|
+
// either. The cursor being inside the strip is a fourth, and the ink
|
|
126
|
+
// being inside it the fifth: a band is a CLIP, so ink outside one was
|
|
127
|
+
// never drawn and cannot be the nearest thing to anything.
|
|
128
|
+
if ((!strip || strip.height > 0) &&
|
|
129
|
+
c !== undefined &&
|
|
130
|
+
!bandExcludes(strip, yPx)) {
|
|
131
|
+
const p = params(state, region, block);
|
|
132
|
+
if (!shape.paintsBlock || shape.paintsBlock(block, state, p)) {
|
|
133
|
+
hit = shape.hitNearest(c, block, state, p, xPx, yPx, candidates, maxDistSq);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return hit && !bandExcludes(strip, hit.y) ? hit : undefined;
|
|
116
137
|
}
|
|
117
138
|
: undefined,
|
|
118
139
|
};
|
package/esm/renderBlock.d.ts
CHANGED
|
@@ -23,3 +23,17 @@ export interface RenderBlock extends BpRegionBounds {
|
|
|
23
23
|
export declare function buildRenderBlocks(regions: (BpRegionBounds & {
|
|
24
24
|
displayedRegionIndex: number;
|
|
25
25
|
})[]): RenderBlock[];
|
|
26
|
+
/**
|
|
27
|
+
* One display key's whole canvas as a single block.
|
|
28
|
+
*
|
|
29
|
+
* For a display whose x axis is not the block's bp span: a dotplot segment, a
|
|
30
|
+
* synteny ribbon, a Hi-C or LD diamond each read their screen x off the
|
|
31
|
+
* payload's own coordinates through a transform the shader and the painter both
|
|
32
|
+
* apply — a `panPx` fold from the fetch-time base for the first two, the
|
|
33
|
+
* diagonal `viewScale`/`viewOffsetX` for the last two. So the block carries
|
|
34
|
+
* nothing but its key and the identity bp span that keeps `clipBlock`
|
|
35
|
+
* well-formed.
|
|
36
|
+
*/
|
|
37
|
+
export declare function canvasWideBlock(displayedRegionIndex: number, canvasWidth: number): RenderBlock;
|
|
38
|
+
/** {@link canvasWideBlock} per key, in the keys' own order. */
|
|
39
|
+
export declare function canvasWideBlocks(keys: Iterable<number>, canvasWidth: number): RenderBlock[];
|
package/esm/renderBlock.js
CHANGED
|
@@ -8,3 +8,28 @@ export function buildRenderBlocks(regions) {
|
|
|
8
8
|
reversed: r.reversed ?? false,
|
|
9
9
|
}));
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* One display key's whole canvas as a single block.
|
|
13
|
+
*
|
|
14
|
+
* For a display whose x axis is not the block's bp span: a dotplot segment, a
|
|
15
|
+
* synteny ribbon, a Hi-C or LD diamond each read their screen x off the
|
|
16
|
+
* payload's own coordinates through a transform the shader and the painter both
|
|
17
|
+
* apply — a `panPx` fold from the fetch-time base for the first two, the
|
|
18
|
+
* diagonal `viewScale`/`viewOffsetX` for the last two. So the block carries
|
|
19
|
+
* nothing but its key and the identity bp span that keeps `clipBlock`
|
|
20
|
+
* well-formed.
|
|
21
|
+
*/
|
|
22
|
+
export function canvasWideBlock(displayedRegionIndex, canvasWidth) {
|
|
23
|
+
return {
|
|
24
|
+
displayedRegionIndex,
|
|
25
|
+
start: 0,
|
|
26
|
+
end: canvasWidth,
|
|
27
|
+
screenStartPx: 0,
|
|
28
|
+
screenEndPx: canvasWidth,
|
|
29
|
+
reversed: false,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/** {@link canvasWideBlock} per key, in the keys' own order. */
|
|
33
|
+
export function canvasWideBlocks(keys, canvasWidth) {
|
|
34
|
+
return [...keys].map(key => canvasWideBlock(key, canvasWidth));
|
|
35
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export declare 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) zero_0 : f32,\n @align(4) viewportWidth_0 : f32,\n @align(16) radiusPx_0 : f32,\n @align(4) devicePixelRatio_0 : f32,\n};\n\n@binding(1) @group(0) var<uniform> u_0 : Uniforms_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_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 valueToYPx_0( value_1 : f32, domainMin_1 : f32, domainMax_1 : f32, h_0 : f32) -> f32\n{\n return (1.0f - clamp((value_1 - domainMin_1) / max(domainMax_1 - domainMin_1, 9.99999997475242708e-07f), 0.0f, 1.0f)) * h_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 clipLenToPx_0( clipLen_0 : f32, size_0 : f32) -> f32\n{\n return clipLen_0 * 0.5f * size_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 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(
|
|
2
|
-
export declare const GLSL_VERTEX = "#version 300 es\nprecision highp float;\nprecision highp int;\nstruct Uniforms_0\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float domainMin_0;\n float domainMax_0;\n float zero_0;\n float viewportWidth_0;\n float radiusPx_0;\n float devicePixelRatio_0;\n};\n\n\nlayout(std140) uniform Uniforms\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float domainMin_0;\n float domainMax_0;\n float zero_0;\n float viewportWidth_0;\n float radiusPx_0;\n float devicePixelRatio_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_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 bpToClipX_0(uint bp_0, Uniforms_0 u_1)\n{\n\n return hpToClipX_0(hpSplitUint_0(bp_0), u_1.bpRangeX_0, u_1.zero_0);\n}\n\n\nfloat valueToYPx_0(float value_1, float domainMin_1, float domainMax_1, float h_0)\n{\n\n return (1.0 - clamp((value_1 - domainMin_1) / max(domainMax_1 - domainMin_1, 9.99999997475242708e-07), 0.0, 1.0)) * h_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\nfloat clipLenToPx_0(float clipLen_0, float size_0)\n{\n\n return clipLen_0 * 0.5 * size_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\nfloat pxToClipLen_0(float px_0, float size_1)\n{\n\n return px_0 * 2.0 / size_1;\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 crispSquareTopLeftPx_0(float centerPx_0, float diameterPx_0)\n{\n\n return floor(centerPx_0 - diameterPx_0 * 0.5 + 0.5);\n}\n\n\n\nvec2 crispSquareCornerPx_0(vec2 centerPx_1, float diameterPx_1, vec2 q_0)\n{\n\n\n\n return vec2(crispSquareTopLeftPx_0(centerPx_1.x, diameterPx_1), crispSquareTopLeftPx_0(centerPx_1.y, diameterPx_1)) + q_0 * diameterPx_1;\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\nvec4 crispSquareCornerClip_0(float centerClipX_0, float centerYPx_0, float diameterPx_2, vec2 q_1, float viewportWidth_1, float canvasHeight_2)\n{\n\n\n\n vec2 vPx_0 = crispSquareCornerPx_0(vec2(clipXToPx_0(centerClipX_0, viewportWidth_1), centerYPx_0), diameterPx_2, q_1);\n return vec4(pxToClipX_0(vPx_0.x, viewportWidth_1), yPxToClipY_0(vPx_0.y, canvasHeight_2), 0.0, 1.0);\n}\n\n\nfloat aaPx_0(float dpr_0)\n{\n\n return 1.0 / max(dpr_0, 1.0);\n}\n\n\nfloat aaHalfPx_0(float dpr_1)\n{\n\n return 0.5 * aaPx_0(dpr_1);\n}\n\n\nfloat discExpand_0(float
|
|
1
|
+
export declare 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) zero_0 : f32,\n @align(4) viewportWidth_0 : f32,\n @align(16) radiusPx_0 : f32,\n @align(4) devicePixelRatio_0 : f32,\n};\n\n@binding(1) @group(0) var<uniform> u_0 : Uniforms_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_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 valueToYPx_0( value_1 : f32, domainMin_1 : f32, domainMax_1 : f32, h_0 : f32) -> f32\n{\n return (1.0f - clamp((value_1 - domainMin_1) / max(domainMax_1 - domainMin_1, 9.99999997475242708e-07f), 0.0f, 1.0f)) * h_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 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_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 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_0 : 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};\n\n@vertex\nfn vs_main( _S6 : 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 _S7 : Uniforms_std140_0 = u_0;\n var _S8 : f32 = bpToClipX_0(_S6.x_0, &(_S7));\n var _S9 : f32 = bpToClipX_0(_S6.x2_0, &(_S7));\n var yPx_1 : f32 = valueToYPx_0(_S6.y_0, u_0.domainMin_0, u_0.domainMax_0, u_0.canvasHeight_0);\n var centerClipY_0 : f32 = yPxToClipY_0(yPx_1, u_0.canvasHeight_0);\n var isBar_0 : bool = pointDrawsBar_0(clipLenToPx_0(abs(_S9 - _S8), u_0.viewportWidth_0), u_0.radiusPx_0);\n var o_0 : VsOut_0;\n o_0.color_0 = unpackRGBA_0(_S6.color_1);\n var x_1 : f32;\n if(isBar_0)\n {\n if(xZero_0)\n {\n x_1 = min(_S8, _S9);\n }\n else\n {\n x_1 = max(_S8, _S9);\n }\n o_0.position_0 = vec4<f32>(x_1, 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 _S10 : bool;\n if((_S6.glyph_0) == u32(0))\n {\n _S10 = (u_0.radiusPx_0 * 2.0f) <= 3.0f;\n }\n else\n {\n _S10 = false;\n }\n if(_S10)\n {\n o_0.position_0 = crispSquareCornerClip_0(_S8, 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 _S11 : bool = (_S6.glyph_0) == u32(2);\n if(_S11)\n {\n x_1 = 1.60000002384185791f;\n }\n else\n {\n x_1 = 1.0f;\n }\n var halfPx_0 : f32 = u_0.radiusPx_0 * expand_0 * x_1;\n o_0.position_0 = vec4<f32>(_S8 + 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((_S6.glyph_0) == u32(1))\n {\n x_1 = 2.0f;\n }\n else\n {\n if(_S11)\n {\n x_1 = 1.0f;\n }\n else\n {\n x_1 = 0.0f;\n }\n }\n o_0.shape_0 = x_1;\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( _S12 : pixelInput_0, @builtin(position) position_1 : vec4<f32>) -> pixelOutput_0\n{\n var coverage_1 : f32;\n if((_S12.shape_1) > 2.5f)\n {\n coverage_1 = 1.0f;\n }\n else\n {\n if((_S12.shape_1) > 1.5f)\n {\n var _S13 : f32 = _S12.localPos_2.y;\n var _S14 : f32 = _S12.localPos_2.x;\n coverage_1 = min(1.0f - _S13, min((2.0f * _S14 + _S13 + 1.0f) * 0.44721359014511108f, (-2.0f * _S14 + _S13 + 1.0f) * 0.44721359014511108f));\n }\n else\n {\n if((_S12.shape_1) > 0.5f)\n {\n coverage_1 = 1.0f - (abs(_S12.localPos_2.x) + abs(_S12.localPos_2.y));\n }\n else\n {\n coverage_1 = discCoverage_0(_S12.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 _S15 : pixelOutput_0 = pixelOutput_0( vec4<f32>(_S12.color_2.xyz, _S12.color_2.w * alpha_0) );\n return _S15;\n}\n\n";
|
|
2
|
+
export declare const GLSL_VERTEX = "#version 300 es\nprecision highp float;\nprecision highp int;\nstruct Uniforms_0\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float domainMin_0;\n float domainMax_0;\n float zero_0;\n float viewportWidth_0;\n float radiusPx_0;\n float devicePixelRatio_0;\n};\n\n\nlayout(std140) uniform Uniforms\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float domainMin_0;\n float domainMax_0;\n float zero_0;\n float viewportWidth_0;\n float radiusPx_0;\n float devicePixelRatio_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_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 bpToClipX_0(uint bp_0, Uniforms_0 u_1)\n{\n\n return hpToClipX_0(hpSplitUint_0(bp_0), u_1.bpRangeX_0, u_1.zero_0);\n}\n\n\nfloat valueToYPx_0(float value_1, float domainMin_1, float domainMax_1, float h_0)\n{\n\n return (1.0 - clamp((value_1 - domainMin_1) / max(domainMax_1 - domainMin_1, 9.99999997475242708e-07), 0.0, 1.0)) * h_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\nfloat clipLenToPx_0(float clipLen_0, float size_0)\n{\n\n return clipLen_0 * 0.5 * size_0;\n}\n\n\nbool pointDrawsBar_0(float spanPx_0, float radiusPx_1)\n{\n\n return spanPx_0 > (radiusPx_1 * 2.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\nfloat pxToClipLen_0(float px_0, float size_1)\n{\n\n return px_0 * 2.0 / size_1;\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 crispSquareTopLeftPx_0(float centerPx_0, float diameterPx_0)\n{\n\n return floor(centerPx_0 - diameterPx_0 * 0.5 + 0.5);\n}\n\n\n\nvec2 crispSquareCornerPx_0(vec2 centerPx_1, float diameterPx_1, vec2 q_0)\n{\n\n\n\n return vec2(crispSquareTopLeftPx_0(centerPx_1.x, diameterPx_1), crispSquareTopLeftPx_0(centerPx_1.y, diameterPx_1)) + q_0 * diameterPx_1;\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\nvec4 crispSquareCornerClip_0(float centerClipX_0, float centerYPx_0, float diameterPx_2, vec2 q_1, float viewportWidth_1, float canvasHeight_2)\n{\n\n\n\n vec2 vPx_0 = crispSquareCornerPx_0(vec2(clipXToPx_0(centerClipX_0, viewportWidth_1), centerYPx_0), diameterPx_2, q_1);\n return vec4(pxToClipX_0(vPx_0.x, viewportWidth_1), yPxToClipY_0(vPx_0.y, canvasHeight_2), 0.0, 1.0);\n}\n\n\nfloat aaPx_0(float dpr_0)\n{\n\n return 1.0 / max(dpr_0, 1.0);\n}\n\n\nfloat aaHalfPx_0(float dpr_1)\n{\n\n return 0.5 * aaPx_0(dpr_1);\n}\n\n\nfloat discExpand_0(float radiusPx_2, float dpr_2)\n{\n\n return (radiusPx_2 + aaHalfPx_0(dpr_2)) / max(radiusPx_2, 0.5);\n}\n\n\nout vec4 v_color;\n\n\nout vec2 v_localPos;\n\n\nflat out float v_shape;\n\n\nlayout(location = 0)\nin uint a_x;\n\n\nlayout(location = 1)\nin uint a_x2;\n\n\nlayout(location = 2)\nin float a_y;\n\n\nlayout(location = 3)\nin uint a_color;\n\n\nlayout(location = 4)\nin uint a_glyph;\n\n\nstruct VsOut_0\n{\n vec4 position_0;\n vec4 color_0;\n vec2 localPos_0;\n float shape_0;\n};\n\n\nvoid main()\n{\n\n\n vec2 q_2 = quadLocal_0(uint(gl_VertexID) % 6U);\n vec2 local_0 = q_2 * 2.0 - 1.0;\n bool xZero_0 = (q_2.x) < 0.5;\n\n Uniforms_0 _S6 = Uniforms_0(u_0.bpRangeX_0, u_0.canvasHeight_0, u_0.domainMin_0, u_0.domainMax_0, u_0.zero_0, u_0.viewportWidth_0, u_0.radiusPx_0, u_0.devicePixelRatio_0);\n\n float startClipX_0 = bpToClipX_0(a_x, _S6);\n float endClipX_0 = bpToClipX_0(a_x2, _S6);\n float yPx_1 = valueToYPx_0(a_y, u_0.domainMin_0, u_0.domainMax_0, u_0.canvasHeight_0);\n float centerClipY_0 = yPxToClipY_0(yPx_1, u_0.canvasHeight_0);\n\n bool isBar_0 = pointDrawsBar_0(clipLenToPx_0(abs(endClipX_0 - startClipX_0), u_0.viewportWidth_0), u_0.radiusPx_0);\n\n VsOut_0 o_0;\n o_0.color_0 = unpackRGBA_0(a_color);\n\n float x_0;\n if(isBar_0)\n {\n\n if(xZero_0)\n {\n\n x_0 = min(startClipX_0, endClipX_0);\n\n }\n else\n {\n\n x_0 = max(startClipX_0, endClipX_0);\n\n }\n\n\n o_0.position_0 = vec4(x_0, centerClipY_0 + pxToClipLen_0(local_0.y * u_0.radiusPx_0, u_0.canvasHeight_0), 0.0, 1.0);\n o_0.localPos_0 = local_0;\n o_0.shape_0 = 3.0;\n\n }\n else\n {\n\n bool _S7;\n\n if(a_glyph == 0U)\n {\n\n _S7 = (u_0.radiusPx_0 * 2.0) <= 3.0;\n\n }\n else\n {\n\n _S7 = false;\n\n }\n\n if(_S7)\n {\n\n\n o_0.position_0 = crispSquareCornerClip_0(startClipX_0, yPx_1, u_0.radiusPx_0 * 2.0, q_2, u_0.viewportWidth_0, u_0.canvasHeight_0);\n\n o_0.localPos_0 = local_0;\n o_0.shape_0 = 3.0;\n\n }\n else\n {\n\n float expand_0 = discExpand_0(u_0.radiusPx_0, u_0.devicePixelRatio_0);\n if(a_glyph == 2U)\n {\n\n x_0 = 1.60000002384185791;\n\n }\n else\n {\n\n x_0 = 1.0;\n\n }\n float halfPx_0 = u_0.radiusPx_0 * expand_0 * x_0;\n\n\n o_0.position_0 = vec4(startClipX_0 + 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.0, 1.0);\n o_0.localPos_0 = local_0 * expand_0;\n if(a_glyph == 1U)\n {\n\n x_0 = 2.0;\n\n }\n else\n {\n\n if(a_glyph == 2U)\n {\n\n x_0 = 1.0;\n\n }\n else\n {\n\n x_0 = 0.0;\n\n }\n\n }\n\n o_0.shape_0 = x_0;\n\n }\n\n }\n\n VsOut_0 _S8 = o_0;\n\n gl_Position = o_0.position_0;\n\n v_color = _S8.color_0;\n\n v_localPos = _S8.localPos_0;\n\n v_shape = _S8.shape_0;\n\n return;\n}\n\n";
|
|
3
3
|
export declare const GLSL_FRAGMENT = "#version 300 es\nprecision highp float;\nprecision highp int;\nfloat discCoverage_0(vec2 localPos_0)\n{\n\n return 1.0 - length(localPos_0);\n}\n\n\nfloat aaGradient_0(float d_0)\n{\n\n return max(length(vec2(dFdx(d_0), dFdy(d_0))), 0.00000999999974738);\n}\n\n\n\nfloat aaRamp_0(float signedInk_0, float widthPx_0)\n{\n\n return clamp(signedInk_0 / widthPx_0 + 0.5, 0.0, 1.0);\n}\n\n\nfloat glyphEdgeAlpha_0(float coverage_0)\n{\n\n return aaRamp_0(coverage_0, aaGradient_0(coverage_0));\n}\n\n\nlayout(location = 0)\nout vec4 entryPointParam_fs_main_0;\n\n\nin vec4 v_color;\n\n\nin vec2 v_localPos;\n\n\nflat in float v_shape;\n\n\nvoid main()\n{\n\n float coverage_1;\n\n if(v_shape > 2.5)\n {\n\n coverage_1 = 1.0;\n\n }\n else\n {\n\n if(v_shape > 1.5)\n {\n\n float _S1 = v_localPos.y;\n float _S2 = v_localPos.x;\n\n coverage_1 = min(1.0 - _S1, min((2.0 * _S2 + _S1 + 1.0) * 0.44721359014511108, (-2.0 * _S2 + _S1 + 1.0) * 0.44721359014511108));\n\n }\n else\n {\n\n if(v_shape > 0.5)\n {\n\n coverage_1 = 1.0 - (abs(v_localPos.x) + abs(v_localPos.y));\n\n }\n else\n {\n\n coverage_1 = discCoverage_0(v_localPos);\n\n }\n\n }\n\n }\n\n float alpha_0 = glyphEdgeAlpha_0(coverage_1);\n if(alpha_0 <= 0.0)\n {\n\n discard;\n\n }\n\n entryPointParam_fs_main_0 = vec4(v_color.xyz, v_color.w * alpha_0);\n\n return;\n}\n\n";
|
|
4
4
|
export * from './pointMark.iface.generated.ts';
|
|
5
5
|
export * from './pointMark.consts.generated.ts';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// AUTO-GENERATED by packages/shader-tools/src/shader-codegen from pointMark.slang.
|
|
2
2
|
// Do not edit. Run `pnpm gen:shaders` to regenerate.
|
|
3
|
-
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) zero_0 : f32,\n @align(4) viewportWidth_0 : f32,\n @align(16) radiusPx_0 : f32,\n @align(4) devicePixelRatio_0 : f32,\n};\n\n@binding(1) @group(0) var<uniform> u_0 : Uniforms_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_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 valueToYPx_0( value_1 : f32, domainMin_1 : f32, domainMax_1 : f32, h_0 : f32) -> f32\n{\n return (1.0f - clamp((value_1 - domainMin_1) / max(domainMax_1 - domainMin_1, 9.99999997475242708e-07f), 0.0f, 1.0f)) * h_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 clipLenToPx_0( clipLen_0 : f32, size_0 : f32) -> f32\n{\n return clipLen_0 * 0.5f * size_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 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(
|
|
4
|
-
export const GLSL_VERTEX = "#version 300 es\nprecision highp float;\nprecision highp int;\nstruct Uniforms_0\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float domainMin_0;\n float domainMax_0;\n float zero_0;\n float viewportWidth_0;\n float radiusPx_0;\n float devicePixelRatio_0;\n};\n\n\nlayout(std140) uniform Uniforms\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float domainMin_0;\n float domainMax_0;\n float zero_0;\n float viewportWidth_0;\n float radiusPx_0;\n float devicePixelRatio_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_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 bpToClipX_0(uint bp_0, Uniforms_0 u_1)\n{\n\n return hpToClipX_0(hpSplitUint_0(bp_0), u_1.bpRangeX_0, u_1.zero_0);\n}\n\n\nfloat valueToYPx_0(float value_1, float domainMin_1, float domainMax_1, float h_0)\n{\n\n return (1.0 - clamp((value_1 - domainMin_1) / max(domainMax_1 - domainMin_1, 9.99999997475242708e-07), 0.0, 1.0)) * h_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\nfloat clipLenToPx_0(float clipLen_0, float size_0)\n{\n\n return clipLen_0 * 0.5 * size_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\nfloat pxToClipLen_0(float px_0, float size_1)\n{\n\n return px_0 * 2.0 / size_1;\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 crispSquareTopLeftPx_0(float centerPx_0, float diameterPx_0)\n{\n\n return floor(centerPx_0 - diameterPx_0 * 0.5 + 0.5);\n}\n\n\n\nvec2 crispSquareCornerPx_0(vec2 centerPx_1, float diameterPx_1, vec2 q_0)\n{\n\n\n\n return vec2(crispSquareTopLeftPx_0(centerPx_1.x, diameterPx_1), crispSquareTopLeftPx_0(centerPx_1.y, diameterPx_1)) + q_0 * diameterPx_1;\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\nvec4 crispSquareCornerClip_0(float centerClipX_0, float centerYPx_0, float diameterPx_2, vec2 q_1, float viewportWidth_1, float canvasHeight_2)\n{\n\n\n\n vec2 vPx_0 = crispSquareCornerPx_0(vec2(clipXToPx_0(centerClipX_0, viewportWidth_1), centerYPx_0), diameterPx_2, q_1);\n return vec4(pxToClipX_0(vPx_0.x, viewportWidth_1), yPxToClipY_0(vPx_0.y, canvasHeight_2), 0.0, 1.0);\n}\n\n\nfloat aaPx_0(float dpr_0)\n{\n\n return 1.0 / max(dpr_0, 1.0);\n}\n\n\nfloat aaHalfPx_0(float dpr_1)\n{\n\n return 0.5 * aaPx_0(dpr_1);\n}\n\n\nfloat discExpand_0(float
|
|
3
|
+
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) zero_0 : f32,\n @align(4) viewportWidth_0 : f32,\n @align(16) radiusPx_0 : f32,\n @align(4) devicePixelRatio_0 : f32,\n};\n\n@binding(1) @group(0) var<uniform> u_0 : Uniforms_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_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 valueToYPx_0( value_1 : f32, domainMin_1 : f32, domainMax_1 : f32, h_0 : f32) -> f32\n{\n return (1.0f - clamp((value_1 - domainMin_1) / max(domainMax_1 - domainMin_1, 9.99999997475242708e-07f), 0.0f, 1.0f)) * h_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 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_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 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_0 : 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};\n\n@vertex\nfn vs_main( _S6 : 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 _S7 : Uniforms_std140_0 = u_0;\n var _S8 : f32 = bpToClipX_0(_S6.x_0, &(_S7));\n var _S9 : f32 = bpToClipX_0(_S6.x2_0, &(_S7));\n var yPx_1 : f32 = valueToYPx_0(_S6.y_0, u_0.domainMin_0, u_0.domainMax_0, u_0.canvasHeight_0);\n var centerClipY_0 : f32 = yPxToClipY_0(yPx_1, u_0.canvasHeight_0);\n var isBar_0 : bool = pointDrawsBar_0(clipLenToPx_0(abs(_S9 - _S8), u_0.viewportWidth_0), u_0.radiusPx_0);\n var o_0 : VsOut_0;\n o_0.color_0 = unpackRGBA_0(_S6.color_1);\n var x_1 : f32;\n if(isBar_0)\n {\n if(xZero_0)\n {\n x_1 = min(_S8, _S9);\n }\n else\n {\n x_1 = max(_S8, _S9);\n }\n o_0.position_0 = vec4<f32>(x_1, 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 _S10 : bool;\n if((_S6.glyph_0) == u32(0))\n {\n _S10 = (u_0.radiusPx_0 * 2.0f) <= 3.0f;\n }\n else\n {\n _S10 = false;\n }\n if(_S10)\n {\n o_0.position_0 = crispSquareCornerClip_0(_S8, 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 _S11 : bool = (_S6.glyph_0) == u32(2);\n if(_S11)\n {\n x_1 = 1.60000002384185791f;\n }\n else\n {\n x_1 = 1.0f;\n }\n var halfPx_0 : f32 = u_0.radiusPx_0 * expand_0 * x_1;\n o_0.position_0 = vec4<f32>(_S8 + 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((_S6.glyph_0) == u32(1))\n {\n x_1 = 2.0f;\n }\n else\n {\n if(_S11)\n {\n x_1 = 1.0f;\n }\n else\n {\n x_1 = 0.0f;\n }\n }\n o_0.shape_0 = x_1;\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( _S12 : pixelInput_0, @builtin(position) position_1 : vec4<f32>) -> pixelOutput_0\n{\n var coverage_1 : f32;\n if((_S12.shape_1) > 2.5f)\n {\n coverage_1 = 1.0f;\n }\n else\n {\n if((_S12.shape_1) > 1.5f)\n {\n var _S13 : f32 = _S12.localPos_2.y;\n var _S14 : f32 = _S12.localPos_2.x;\n coverage_1 = min(1.0f - _S13, min((2.0f * _S14 + _S13 + 1.0f) * 0.44721359014511108f, (-2.0f * _S14 + _S13 + 1.0f) * 0.44721359014511108f));\n }\n else\n {\n if((_S12.shape_1) > 0.5f)\n {\n coverage_1 = 1.0f - (abs(_S12.localPos_2.x) + abs(_S12.localPos_2.y));\n }\n else\n {\n coverage_1 = discCoverage_0(_S12.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 _S15 : pixelOutput_0 = pixelOutput_0( vec4<f32>(_S12.color_2.xyz, _S12.color_2.w * alpha_0) );\n return _S15;\n}\n\n";
|
|
4
|
+
export const GLSL_VERTEX = "#version 300 es\nprecision highp float;\nprecision highp int;\nstruct Uniforms_0\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float domainMin_0;\n float domainMax_0;\n float zero_0;\n float viewportWidth_0;\n float radiusPx_0;\n float devicePixelRatio_0;\n};\n\n\nlayout(std140) uniform Uniforms\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float domainMin_0;\n float domainMax_0;\n float zero_0;\n float viewportWidth_0;\n float radiusPx_0;\n float devicePixelRatio_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_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 bpToClipX_0(uint bp_0, Uniforms_0 u_1)\n{\n\n return hpToClipX_0(hpSplitUint_0(bp_0), u_1.bpRangeX_0, u_1.zero_0);\n}\n\n\nfloat valueToYPx_0(float value_1, float domainMin_1, float domainMax_1, float h_0)\n{\n\n return (1.0 - clamp((value_1 - domainMin_1) / max(domainMax_1 - domainMin_1, 9.99999997475242708e-07), 0.0, 1.0)) * h_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\nfloat clipLenToPx_0(float clipLen_0, float size_0)\n{\n\n return clipLen_0 * 0.5 * size_0;\n}\n\n\nbool pointDrawsBar_0(float spanPx_0, float radiusPx_1)\n{\n\n return spanPx_0 > (radiusPx_1 * 2.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\nfloat pxToClipLen_0(float px_0, float size_1)\n{\n\n return px_0 * 2.0 / size_1;\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 crispSquareTopLeftPx_0(float centerPx_0, float diameterPx_0)\n{\n\n return floor(centerPx_0 - diameterPx_0 * 0.5 + 0.5);\n}\n\n\n\nvec2 crispSquareCornerPx_0(vec2 centerPx_1, float diameterPx_1, vec2 q_0)\n{\n\n\n\n return vec2(crispSquareTopLeftPx_0(centerPx_1.x, diameterPx_1), crispSquareTopLeftPx_0(centerPx_1.y, diameterPx_1)) + q_0 * diameterPx_1;\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\nvec4 crispSquareCornerClip_0(float centerClipX_0, float centerYPx_0, float diameterPx_2, vec2 q_1, float viewportWidth_1, float canvasHeight_2)\n{\n\n\n\n vec2 vPx_0 = crispSquareCornerPx_0(vec2(clipXToPx_0(centerClipX_0, viewportWidth_1), centerYPx_0), diameterPx_2, q_1);\n return vec4(pxToClipX_0(vPx_0.x, viewportWidth_1), yPxToClipY_0(vPx_0.y, canvasHeight_2), 0.0, 1.0);\n}\n\n\nfloat aaPx_0(float dpr_0)\n{\n\n return 1.0 / max(dpr_0, 1.0);\n}\n\n\nfloat aaHalfPx_0(float dpr_1)\n{\n\n return 0.5 * aaPx_0(dpr_1);\n}\n\n\nfloat discExpand_0(float radiusPx_2, float dpr_2)\n{\n\n return (radiusPx_2 + aaHalfPx_0(dpr_2)) / max(radiusPx_2, 0.5);\n}\n\n\nout vec4 v_color;\n\n\nout vec2 v_localPos;\n\n\nflat out float v_shape;\n\n\nlayout(location = 0)\nin uint a_x;\n\n\nlayout(location = 1)\nin uint a_x2;\n\n\nlayout(location = 2)\nin float a_y;\n\n\nlayout(location = 3)\nin uint a_color;\n\n\nlayout(location = 4)\nin uint a_glyph;\n\n\nstruct VsOut_0\n{\n vec4 position_0;\n vec4 color_0;\n vec2 localPos_0;\n float shape_0;\n};\n\n\nvoid main()\n{\n\n\n vec2 q_2 = quadLocal_0(uint(gl_VertexID) % 6U);\n vec2 local_0 = q_2 * 2.0 - 1.0;\n bool xZero_0 = (q_2.x) < 0.5;\n\n Uniforms_0 _S6 = Uniforms_0(u_0.bpRangeX_0, u_0.canvasHeight_0, u_0.domainMin_0, u_0.domainMax_0, u_0.zero_0, u_0.viewportWidth_0, u_0.radiusPx_0, u_0.devicePixelRatio_0);\n\n float startClipX_0 = bpToClipX_0(a_x, _S6);\n float endClipX_0 = bpToClipX_0(a_x2, _S6);\n float yPx_1 = valueToYPx_0(a_y, u_0.domainMin_0, u_0.domainMax_0, u_0.canvasHeight_0);\n float centerClipY_0 = yPxToClipY_0(yPx_1, u_0.canvasHeight_0);\n\n bool isBar_0 = pointDrawsBar_0(clipLenToPx_0(abs(endClipX_0 - startClipX_0), u_0.viewportWidth_0), u_0.radiusPx_0);\n\n VsOut_0 o_0;\n o_0.color_0 = unpackRGBA_0(a_color);\n\n float x_0;\n if(isBar_0)\n {\n\n if(xZero_0)\n {\n\n x_0 = min(startClipX_0, endClipX_0);\n\n }\n else\n {\n\n x_0 = max(startClipX_0, endClipX_0);\n\n }\n\n\n o_0.position_0 = vec4(x_0, centerClipY_0 + pxToClipLen_0(local_0.y * u_0.radiusPx_0, u_0.canvasHeight_0), 0.0, 1.0);\n o_0.localPos_0 = local_0;\n o_0.shape_0 = 3.0;\n\n }\n else\n {\n\n bool _S7;\n\n if(a_glyph == 0U)\n {\n\n _S7 = (u_0.radiusPx_0 * 2.0) <= 3.0;\n\n }\n else\n {\n\n _S7 = false;\n\n }\n\n if(_S7)\n {\n\n\n o_0.position_0 = crispSquareCornerClip_0(startClipX_0, yPx_1, u_0.radiusPx_0 * 2.0, q_2, u_0.viewportWidth_0, u_0.canvasHeight_0);\n\n o_0.localPos_0 = local_0;\n o_0.shape_0 = 3.0;\n\n }\n else\n {\n\n float expand_0 = discExpand_0(u_0.radiusPx_0, u_0.devicePixelRatio_0);\n if(a_glyph == 2U)\n {\n\n x_0 = 1.60000002384185791;\n\n }\n else\n {\n\n x_0 = 1.0;\n\n }\n float halfPx_0 = u_0.radiusPx_0 * expand_0 * x_0;\n\n\n o_0.position_0 = vec4(startClipX_0 + 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.0, 1.0);\n o_0.localPos_0 = local_0 * expand_0;\n if(a_glyph == 1U)\n {\n\n x_0 = 2.0;\n\n }\n else\n {\n\n if(a_glyph == 2U)\n {\n\n x_0 = 1.0;\n\n }\n else\n {\n\n x_0 = 0.0;\n\n }\n\n }\n\n o_0.shape_0 = x_0;\n\n }\n\n }\n\n VsOut_0 _S8 = o_0;\n\n gl_Position = o_0.position_0;\n\n v_color = _S8.color_0;\n\n v_localPos = _S8.localPos_0;\n\n v_shape = _S8.shape_0;\n\n return;\n}\n\n";
|
|
5
5
|
export const GLSL_FRAGMENT = "#version 300 es\nprecision highp float;\nprecision highp int;\nfloat discCoverage_0(vec2 localPos_0)\n{\n\n return 1.0 - length(localPos_0);\n}\n\n\nfloat aaGradient_0(float d_0)\n{\n\n return max(length(vec2(dFdx(d_0), dFdy(d_0))), 0.00000999999974738);\n}\n\n\n\nfloat aaRamp_0(float signedInk_0, float widthPx_0)\n{\n\n return clamp(signedInk_0 / widthPx_0 + 0.5, 0.0, 1.0);\n}\n\n\nfloat glyphEdgeAlpha_0(float coverage_0)\n{\n\n return aaRamp_0(coverage_0, aaGradient_0(coverage_0));\n}\n\n\nlayout(location = 0)\nout vec4 entryPointParam_fs_main_0;\n\n\nin vec4 v_color;\n\n\nin vec2 v_localPos;\n\n\nflat in float v_shape;\n\n\nvoid main()\n{\n\n float coverage_1;\n\n if(v_shape > 2.5)\n {\n\n coverage_1 = 1.0;\n\n }\n else\n {\n\n if(v_shape > 1.5)\n {\n\n float _S1 = v_localPos.y;\n float _S2 = v_localPos.x;\n\n coverage_1 = min(1.0 - _S1, min((2.0 * _S2 + _S1 + 1.0) * 0.44721359014511108, (-2.0 * _S2 + _S1 + 1.0) * 0.44721359014511108));\n\n }\n else\n {\n\n if(v_shape > 0.5)\n {\n\n coverage_1 = 1.0 - (abs(v_localPos.x) + abs(v_localPos.y));\n\n }\n else\n {\n\n coverage_1 = discCoverage_0(v_localPos);\n\n }\n\n }\n\n }\n\n float alpha_0 = glyphEdgeAlpha_0(coverage_1);\n if(alpha_0 <= 0.0)\n {\n\n discard;\n\n }\n\n entryPointParam_fs_main_0 = vec4(v_color.xyz, v_color.w * alpha_0);\n\n return;\n}\n\n";
|
|
6
6
|
export * from './pointMark.iface.generated.js';
|
|
7
7
|
export * from './pointMark.consts.generated.js';
|
|
@@ -14,3 +14,6 @@ function _min(a, b) {
|
|
|
14
14
|
export function valueToYPx(value, domainMin, domainMax, h) {
|
|
15
15
|
return ((1.0 - _clamp(((value - domainMin) / _max((domainMax - domainMin), 9.99999997475242708e-07)), 0.0, 1.0)) * h);
|
|
16
16
|
}
|
|
17
|
+
export function pointDrawsBar(spanPx, radiusPx) {
|
|
18
|
+
return (spanPx > (radiusPx * 2.0));
|
|
19
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/render-core",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "GPU/Canvas2D rendering primitives for JBrowse displays: the HAL, the draw-lifecycle mixin, per-region/global backend bases, and the React backend hooks",
|
|
6
6
|
"keywords": [
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"./marks/colorFill": "./esm/marks/colorFill.js",
|
|
50
50
|
"./marks/drawAgainstHit": "./esm/marks/drawAgainstHit.js",
|
|
51
51
|
"./marks/glyphPaint": "./esm/marks/glyphPaint.js",
|
|
52
|
+
"./marks/hit": "./esm/marks/markHit.js",
|
|
52
53
|
"./namedReactions": "./esm/namedReactions.js",
|
|
53
54
|
"./OverlayCanvas": "./esm/OverlayCanvas.js",
|
|
54
55
|
"./perRegionRenderingBackend": "./esm/perRegionRenderingBackend.js",
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// AUTO-GENERATED by packages/shader-tools/src/shader-codegen from pointMark.slang.
|
|
2
2
|
// Do not edit. Run `pnpm gen:shaders` to regenerate.
|
|
3
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) zero_0 : f32,\n @align(4) viewportWidth_0 : f32,\n @align(16) radiusPx_0 : f32,\n @align(4) devicePixelRatio_0 : f32,\n};\n\n@binding(1) @group(0) var<uniform> u_0 : Uniforms_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_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 valueToYPx_0( value_1 : f32, domainMin_1 : f32, domainMax_1 : f32, h_0 : f32) -> f32\n{\n return (1.0f - clamp((value_1 - domainMin_1) / max(domainMax_1 - domainMin_1, 9.99999997475242708e-07f), 0.0f, 1.0f)) * h_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 clipLenToPx_0( clipLen_0 : f32, size_0 : f32) -> f32\n{\n return clipLen_0 * 0.5f * size_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 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(
|
|
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) zero_0 : f32,\n @align(4) viewportWidth_0 : f32,\n @align(16) radiusPx_0 : f32,\n @align(4) devicePixelRatio_0 : f32,\n};\n\n@binding(1) @group(0) var<uniform> u_0 : Uniforms_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_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 valueToYPx_0( value_1 : f32, domainMin_1 : f32, domainMax_1 : f32, h_0 : f32) -> f32\n{\n return (1.0f - clamp((value_1 - domainMin_1) / max(domainMax_1 - domainMin_1, 9.99999997475242708e-07f), 0.0f, 1.0f)) * h_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 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_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 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_0 : 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};\n\n@vertex\nfn vs_main( _S6 : 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 _S7 : Uniforms_std140_0 = u_0;\n var _S8 : f32 = bpToClipX_0(_S6.x_0, &(_S7));\n var _S9 : f32 = bpToClipX_0(_S6.x2_0, &(_S7));\n var yPx_1 : f32 = valueToYPx_0(_S6.y_0, u_0.domainMin_0, u_0.domainMax_0, u_0.canvasHeight_0);\n var centerClipY_0 : f32 = yPxToClipY_0(yPx_1, u_0.canvasHeight_0);\n var isBar_0 : bool = pointDrawsBar_0(clipLenToPx_0(abs(_S9 - _S8), u_0.viewportWidth_0), u_0.radiusPx_0);\n var o_0 : VsOut_0;\n o_0.color_0 = unpackRGBA_0(_S6.color_1);\n var x_1 : f32;\n if(isBar_0)\n {\n if(xZero_0)\n {\n x_1 = min(_S8, _S9);\n }\n else\n {\n x_1 = max(_S8, _S9);\n }\n o_0.position_0 = vec4<f32>(x_1, 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 _S10 : bool;\n if((_S6.glyph_0) == u32(0))\n {\n _S10 = (u_0.radiusPx_0 * 2.0f) <= 3.0f;\n }\n else\n {\n _S10 = false;\n }\n if(_S10)\n {\n o_0.position_0 = crispSquareCornerClip_0(_S8, 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 _S11 : bool = (_S6.glyph_0) == u32(2);\n if(_S11)\n {\n x_1 = 1.60000002384185791f;\n }\n else\n {\n x_1 = 1.0f;\n }\n var halfPx_0 : f32 = u_0.radiusPx_0 * expand_0 * x_1;\n o_0.position_0 = vec4<f32>(_S8 + 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((_S6.glyph_0) == u32(1))\n {\n x_1 = 2.0f;\n }\n else\n {\n if(_S11)\n {\n x_1 = 1.0f;\n }\n else\n {\n x_1 = 0.0f;\n }\n }\n o_0.shape_0 = x_1;\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( _S12 : pixelInput_0, @builtin(position) position_1 : vec4<f32>) -> pixelOutput_0\n{\n var coverage_1 : f32;\n if((_S12.shape_1) > 2.5f)\n {\n coverage_1 = 1.0f;\n }\n else\n {\n if((_S12.shape_1) > 1.5f)\n {\n var _S13 : f32 = _S12.localPos_2.y;\n var _S14 : f32 = _S12.localPos_2.x;\n coverage_1 = min(1.0f - _S13, min((2.0f * _S14 + _S13 + 1.0f) * 0.44721359014511108f, (-2.0f * _S14 + _S13 + 1.0f) * 0.44721359014511108f));\n }\n else\n {\n if((_S12.shape_1) > 0.5f)\n {\n coverage_1 = 1.0f - (abs(_S12.localPos_2.x) + abs(_S12.localPos_2.y));\n }\n else\n {\n coverage_1 = discCoverage_0(_S12.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 _S15 : pixelOutput_0 = pixelOutput_0( vec4<f32>(_S12.color_2.xyz, _S12.color_2.w * alpha_0) );\n return _S15;\n}\n\n"
|
|
5
5
|
|
|
6
|
-
export const GLSL_VERTEX = "#version 300 es\nprecision highp float;\nprecision highp int;\nstruct Uniforms_0\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float domainMin_0;\n float domainMax_0;\n float zero_0;\n float viewportWidth_0;\n float radiusPx_0;\n float devicePixelRatio_0;\n};\n\n\nlayout(std140) uniform Uniforms\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float domainMin_0;\n float domainMax_0;\n float zero_0;\n float viewportWidth_0;\n float radiusPx_0;\n float devicePixelRatio_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_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 bpToClipX_0(uint bp_0, Uniforms_0 u_1)\n{\n\n return hpToClipX_0(hpSplitUint_0(bp_0), u_1.bpRangeX_0, u_1.zero_0);\n}\n\n\nfloat valueToYPx_0(float value_1, float domainMin_1, float domainMax_1, float h_0)\n{\n\n return (1.0 - clamp((value_1 - domainMin_1) / max(domainMax_1 - domainMin_1, 9.99999997475242708e-07), 0.0, 1.0)) * h_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\nfloat clipLenToPx_0(float clipLen_0, float size_0)\n{\n\n return clipLen_0 * 0.5 * size_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\nfloat pxToClipLen_0(float px_0, float size_1)\n{\n\n return px_0 * 2.0 / size_1;\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 crispSquareTopLeftPx_0(float centerPx_0, float diameterPx_0)\n{\n\n return floor(centerPx_0 - diameterPx_0 * 0.5 + 0.5);\n}\n\n\n\nvec2 crispSquareCornerPx_0(vec2 centerPx_1, float diameterPx_1, vec2 q_0)\n{\n\n\n\n return vec2(crispSquareTopLeftPx_0(centerPx_1.x, diameterPx_1), crispSquareTopLeftPx_0(centerPx_1.y, diameterPx_1)) + q_0 * diameterPx_1;\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\nvec4 crispSquareCornerClip_0(float centerClipX_0, float centerYPx_0, float diameterPx_2, vec2 q_1, float viewportWidth_1, float canvasHeight_2)\n{\n\n\n\n vec2 vPx_0 = crispSquareCornerPx_0(vec2(clipXToPx_0(centerClipX_0, viewportWidth_1), centerYPx_0), diameterPx_2, q_1);\n return vec4(pxToClipX_0(vPx_0.x, viewportWidth_1), yPxToClipY_0(vPx_0.y, canvasHeight_2), 0.0, 1.0);\n}\n\n\nfloat aaPx_0(float dpr_0)\n{\n\n return 1.0 / max(dpr_0, 1.0);\n}\n\n\nfloat aaHalfPx_0(float dpr_1)\n{\n\n return 0.5 * aaPx_0(dpr_1);\n}\n\n\nfloat discExpand_0(float
|
|
6
|
+
export const GLSL_VERTEX = "#version 300 es\nprecision highp float;\nprecision highp int;\nstruct Uniforms_0\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float domainMin_0;\n float domainMax_0;\n float zero_0;\n float viewportWidth_0;\n float radiusPx_0;\n float devicePixelRatio_0;\n};\n\n\nlayout(std140) uniform Uniforms\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float domainMin_0;\n float domainMax_0;\n float zero_0;\n float viewportWidth_0;\n float radiusPx_0;\n float devicePixelRatio_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_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 bpToClipX_0(uint bp_0, Uniforms_0 u_1)\n{\n\n return hpToClipX_0(hpSplitUint_0(bp_0), u_1.bpRangeX_0, u_1.zero_0);\n}\n\n\nfloat valueToYPx_0(float value_1, float domainMin_1, float domainMax_1, float h_0)\n{\n\n return (1.0 - clamp((value_1 - domainMin_1) / max(domainMax_1 - domainMin_1, 9.99999997475242708e-07), 0.0, 1.0)) * h_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\nfloat clipLenToPx_0(float clipLen_0, float size_0)\n{\n\n return clipLen_0 * 0.5 * size_0;\n}\n\n\nbool pointDrawsBar_0(float spanPx_0, float radiusPx_1)\n{\n\n return spanPx_0 > (radiusPx_1 * 2.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\nfloat pxToClipLen_0(float px_0, float size_1)\n{\n\n return px_0 * 2.0 / size_1;\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 crispSquareTopLeftPx_0(float centerPx_0, float diameterPx_0)\n{\n\n return floor(centerPx_0 - diameterPx_0 * 0.5 + 0.5);\n}\n\n\n\nvec2 crispSquareCornerPx_0(vec2 centerPx_1, float diameterPx_1, vec2 q_0)\n{\n\n\n\n return vec2(crispSquareTopLeftPx_0(centerPx_1.x, diameterPx_1), crispSquareTopLeftPx_0(centerPx_1.y, diameterPx_1)) + q_0 * diameterPx_1;\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\nvec4 crispSquareCornerClip_0(float centerClipX_0, float centerYPx_0, float diameterPx_2, vec2 q_1, float viewportWidth_1, float canvasHeight_2)\n{\n\n\n\n vec2 vPx_0 = crispSquareCornerPx_0(vec2(clipXToPx_0(centerClipX_0, viewportWidth_1), centerYPx_0), diameterPx_2, q_1);\n return vec4(pxToClipX_0(vPx_0.x, viewportWidth_1), yPxToClipY_0(vPx_0.y, canvasHeight_2), 0.0, 1.0);\n}\n\n\nfloat aaPx_0(float dpr_0)\n{\n\n return 1.0 / max(dpr_0, 1.0);\n}\n\n\nfloat aaHalfPx_0(float dpr_1)\n{\n\n return 0.5 * aaPx_0(dpr_1);\n}\n\n\nfloat discExpand_0(float radiusPx_2, float dpr_2)\n{\n\n return (radiusPx_2 + aaHalfPx_0(dpr_2)) / max(radiusPx_2, 0.5);\n}\n\n\nout vec4 v_color;\n\n\nout vec2 v_localPos;\n\n\nflat out float v_shape;\n\n\nlayout(location = 0)\nin uint a_x;\n\n\nlayout(location = 1)\nin uint a_x2;\n\n\nlayout(location = 2)\nin float a_y;\n\n\nlayout(location = 3)\nin uint a_color;\n\n\nlayout(location = 4)\nin uint a_glyph;\n\n\nstruct VsOut_0\n{\n vec4 position_0;\n vec4 color_0;\n vec2 localPos_0;\n float shape_0;\n};\n\n\nvoid main()\n{\n\n\n vec2 q_2 = quadLocal_0(uint(gl_VertexID) % 6U);\n vec2 local_0 = q_2 * 2.0 - 1.0;\n bool xZero_0 = (q_2.x) < 0.5;\n\n Uniforms_0 _S6 = Uniforms_0(u_0.bpRangeX_0, u_0.canvasHeight_0, u_0.domainMin_0, u_0.domainMax_0, u_0.zero_0, u_0.viewportWidth_0, u_0.radiusPx_0, u_0.devicePixelRatio_0);\n\n float startClipX_0 = bpToClipX_0(a_x, _S6);\n float endClipX_0 = bpToClipX_0(a_x2, _S6);\n float yPx_1 = valueToYPx_0(a_y, u_0.domainMin_0, u_0.domainMax_0, u_0.canvasHeight_0);\n float centerClipY_0 = yPxToClipY_0(yPx_1, u_0.canvasHeight_0);\n\n bool isBar_0 = pointDrawsBar_0(clipLenToPx_0(abs(endClipX_0 - startClipX_0), u_0.viewportWidth_0), u_0.radiusPx_0);\n\n VsOut_0 o_0;\n o_0.color_0 = unpackRGBA_0(a_color);\n\n float x_0;\n if(isBar_0)\n {\n\n if(xZero_0)\n {\n\n x_0 = min(startClipX_0, endClipX_0);\n\n }\n else\n {\n\n x_0 = max(startClipX_0, endClipX_0);\n\n }\n\n\n o_0.position_0 = vec4(x_0, centerClipY_0 + pxToClipLen_0(local_0.y * u_0.radiusPx_0, u_0.canvasHeight_0), 0.0, 1.0);\n o_0.localPos_0 = local_0;\n o_0.shape_0 = 3.0;\n\n }\n else\n {\n\n bool _S7;\n\n if(a_glyph == 0U)\n {\n\n _S7 = (u_0.radiusPx_0 * 2.0) <= 3.0;\n\n }\n else\n {\n\n _S7 = false;\n\n }\n\n if(_S7)\n {\n\n\n o_0.position_0 = crispSquareCornerClip_0(startClipX_0, yPx_1, u_0.radiusPx_0 * 2.0, q_2, u_0.viewportWidth_0, u_0.canvasHeight_0);\n\n o_0.localPos_0 = local_0;\n o_0.shape_0 = 3.0;\n\n }\n else\n {\n\n float expand_0 = discExpand_0(u_0.radiusPx_0, u_0.devicePixelRatio_0);\n if(a_glyph == 2U)\n {\n\n x_0 = 1.60000002384185791;\n\n }\n else\n {\n\n x_0 = 1.0;\n\n }\n float halfPx_0 = u_0.radiusPx_0 * expand_0 * x_0;\n\n\n o_0.position_0 = vec4(startClipX_0 + 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.0, 1.0);\n o_0.localPos_0 = local_0 * expand_0;\n if(a_glyph == 1U)\n {\n\n x_0 = 2.0;\n\n }\n else\n {\n\n if(a_glyph == 2U)\n {\n\n x_0 = 1.0;\n\n }\n else\n {\n\n x_0 = 0.0;\n\n }\n\n }\n\n o_0.shape_0 = x_0;\n\n }\n\n }\n\n VsOut_0 _S8 = o_0;\n\n gl_Position = o_0.position_0;\n\n v_color = _S8.color_0;\n\n v_localPos = _S8.localPos_0;\n\n v_shape = _S8.shape_0;\n\n return;\n}\n\n"
|
|
7
7
|
|
|
8
8
|
export const GLSL_FRAGMENT = "#version 300 es\nprecision highp float;\nprecision highp int;\nfloat discCoverage_0(vec2 localPos_0)\n{\n\n return 1.0 - length(localPos_0);\n}\n\n\nfloat aaGradient_0(float d_0)\n{\n\n return max(length(vec2(dFdx(d_0), dFdy(d_0))), 0.00000999999974738);\n}\n\n\n\nfloat aaRamp_0(float signedInk_0, float widthPx_0)\n{\n\n return clamp(signedInk_0 / widthPx_0 + 0.5, 0.0, 1.0);\n}\n\n\nfloat glyphEdgeAlpha_0(float coverage_0)\n{\n\n return aaRamp_0(coverage_0, aaGradient_0(coverage_0));\n}\n\n\nlayout(location = 0)\nout vec4 entryPointParam_fs_main_0;\n\n\nin vec4 v_color;\n\n\nin vec2 v_localPos;\n\n\nflat in float v_shape;\n\n\nvoid main()\n{\n\n float coverage_1;\n\n if(v_shape > 2.5)\n {\n\n coverage_1 = 1.0;\n\n }\n else\n {\n\n if(v_shape > 1.5)\n {\n\n float _S1 = v_localPos.y;\n float _S2 = v_localPos.x;\n\n coverage_1 = min(1.0 - _S1, min((2.0 * _S2 + _S1 + 1.0) * 0.44721359014511108, (-2.0 * _S2 + _S1 + 1.0) * 0.44721359014511108));\n\n }\n else\n {\n\n if(v_shape > 0.5)\n {\n\n coverage_1 = 1.0 - (abs(v_localPos.x) + abs(v_localPos.y));\n\n }\n else\n {\n\n coverage_1 = discCoverage_0(v_localPos);\n\n }\n\n }\n\n }\n\n float alpha_0 = glyphEdgeAlpha_0(coverage_1);\n if(alpha_0 <= 0.0)\n {\n\n discard;\n\n }\n\n entryPointParam_fs_main_0 = vec4(v_color.xyz, v_color.w * alpha_0);\n\n return;\n}\n\n"
|
|
9
9
|
|
|
@@ -19,3 +19,7 @@ function _min(a: number, b: number) {
|
|
|
19
19
|
export function valueToYPx(value: number, domainMin: number, domainMax: number, h: number): number {
|
|
20
20
|
return ((1.0 - _clamp(((value - domainMin) / _max((domainMax - domainMin), 9.99999997475242708e-07)), 0.0, 1.0)) * h)
|
|
21
21
|
}
|
|
22
|
+
|
|
23
|
+
export function pointDrawsBar(spanPx: number, radiusPx: number): boolean {
|
|
24
|
+
return (spanPx > (radiusPx * 2.0))
|
|
25
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
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: valueToYPx
|
|
10
|
+
//! js-export: valueToYPx, pointDrawsBar
|
|
11
11
|
|
|
12
12
|
import antialias;
|
|
13
13
|
import hpmath;
|
|
@@ -64,6 +64,19 @@ float valueToYPx(float value, float domainMin, float domainMax, float h) {
|
|
|
64
64
|
return (1.0 - norm) * h;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
// Whether an instance draws as an extent bar rather than a glyph: its span has
|
|
68
|
+
// to beat the glyph it would otherwise be, so a datum wider than its own marker
|
|
69
|
+
// stops pretending to be a point.
|
|
70
|
+
//
|
|
71
|
+
// `//! js-export`ed because this one decision is read in three places — the
|
|
72
|
+
// vertex branch below, the painter's rect-vs-glyph fork and the hit test's
|
|
73
|
+
// rect-vs-centre fork — and a display whose hit test took the other branch from
|
|
74
|
+
// the draw would grab a bar at its midpoint. `rectDrawsOutline` and `arrowDraws`
|
|
75
|
+
// are the same lift for the same reason.
|
|
76
|
+
bool pointDrawsBar(float spanPx, float radiusPx) {
|
|
77
|
+
return spanPx > radiusPx * 2.0;
|
|
78
|
+
}
|
|
79
|
+
|
|
67
80
|
struct VsOut {
|
|
68
81
|
float4 position : SV_Position;
|
|
69
82
|
float4 color : COLOR0;
|
|
@@ -73,10 +86,6 @@ struct VsOut {
|
|
|
73
86
|
nointerpolation float shape : TEXCOORD1;
|
|
74
87
|
};
|
|
75
88
|
|
|
76
|
-
// Solid ink each side of a bar's genomic span, in CSS px, so a run of adjacent
|
|
77
|
-
// bars abuts. SHAPE_BAR's fragment coverage is a constant 1.
|
|
78
|
-
static const float BAR_OVERDRAW_PX = 1.0;
|
|
79
|
-
|
|
80
89
|
// Shape discriminators for the fragment shader. SMALL_POINT_MAX_DIAMETER and
|
|
81
90
|
// the disc SDF come from the shared pointGlyph module so they stay in lockstep
|
|
82
91
|
// with wiggle.slang.
|
|
@@ -119,17 +128,21 @@ VsOut vs_main(PointMarkInstance inst, uint vid : SV_VertexID) {
|
|
|
119
128
|
// abs() because reversal is baked into bpRangeX (negated length), so
|
|
120
129
|
// endClipX < startClipX on reversed regions — matches wiggle.slang.
|
|
121
130
|
float spanPx = clipLenToPx(abs(endClipX - startClipX), u.viewportWidth);
|
|
122
|
-
bool isBar = spanPx
|
|
131
|
+
bool isBar = pointDrawsBar(spanPx, u.radiusPx);
|
|
123
132
|
|
|
124
133
|
VsOut o;
|
|
125
134
|
o.color = unpackRGBA(inst.color);
|
|
126
135
|
if (isBar) {
|
|
127
136
|
// Horizontal bar from x→x2, height 2*radiusPx px, centered on the value.
|
|
128
|
-
|
|
129
|
-
//
|
|
130
|
-
//
|
|
131
|
-
|
|
132
|
-
|
|
137
|
+
//
|
|
138
|
+
// NO SEAM PAD, and this reverses a deliberate one: `c7ff9d459d` kept the
|
|
139
|
+
// 1 px overdraw on the claim that abutting bars leave hairline gaps without
|
|
140
|
+
// it (the claim is that commit's, not the ADR-098 document's).
|
|
141
|
+
// Measured against a fixture built to test that (38 of 39 boundaries on a
|
|
142
|
+
// shared pixel row), padded and unpadded have the same interior gap
|
|
143
|
+
// columns — none opens. A hairline at a fractional `fillRect` edge is a
|
|
144
|
+
// Canvas2D problem and takes a Canvas2D pad; see `spanMark`'s `seamPx`.
|
|
145
|
+
float x = xZero ? min(startClipX, endClipX) : max(startClipX, endClipX);
|
|
133
146
|
float halfBandPx = u.radiusPx;
|
|
134
147
|
float y = centerClipY + pxToClipLen(local.y * halfBandPx, u.canvasHeight);
|
|
135
148
|
o.position = float4(x, y, 0.0, 1.0);
|