@jbrowse/render-core 5.0.0-beta.2 → 5.0.0-beta.3
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/RenderLifecycleMixin.d.ts +20 -1
- package/esm/RenderLifecycleMixin.js +25 -2
- package/esm/canvas2dUtils.d.ts +25 -0
- package/esm/canvas2dUtils.js +27 -0
- package/esm/colorRampLut.d.ts +4 -4
- package/esm/colorRampLut.js +4 -4
- package/esm/computePipeline.d.ts +13 -0
- package/esm/computePipeline.js +55 -0
- package/esm/coverageBand.d.ts +0 -1
- package/esm/coverageBand.js +0 -1
- package/esm/coverageBandBuffers.d.ts +0 -6
- package/esm/coverageBandBuffers.js +1 -13
- package/esm/createRenderingBackend.d.ts +14 -18
- package/esm/createRenderingBackend.js +4 -2
- package/esm/encodeMemo.d.ts +14 -0
- package/esm/encodeMemo.js +48 -0
- package/esm/gpuDevice.d.ts +9 -0
- package/esm/gpuDevice.js +12 -3
- package/esm/graphicsCapabilities.d.ts +18 -15
- package/esm/graphicsCapabilities.js +23 -16
- package/esm/hal/createHal.d.ts +1 -2
- package/esm/hal/createHal.js +14 -4
- package/esm/hal/deviceGpuCache.js +2 -2
- package/esm/hal/gpuHalBase.d.ts +1 -1
- package/esm/hal/gpuHalBase.js +2 -3
- package/esm/hal/mockHal.d.ts +0 -1
- package/esm/hal/mockHal.js +0 -10
- package/esm/hal/regionRegistry.d.ts +0 -1
- package/esm/hal/regionRegistry.js +3 -15
- package/esm/hal/types.d.ts +5 -1
- package/esm/hal/webgl2Hal.d.ts +1 -1
- package/esm/hal/webgl2Hal.js +2 -2
- package/esm/hal/webgpuHal.d.ts +2 -2
- package/esm/hal/webgpuHal.js +13 -10
- package/esm/installUpload.d.ts +4 -1
- package/esm/installUpload.js +7 -39
- package/esm/instanceCache.d.ts +10 -7
- package/esm/instanceCache.js +14 -15
- package/esm/mapUploadSync.d.ts +0 -8
- package/esm/mapUploadSync.js +0 -1
- package/esm/marks/colorFill.d.ts +17 -0
- package/esm/marks/colorFill.js +26 -0
- package/esm/marks/drawAgainstHit.d.ts +47 -0
- package/esm/marks/drawAgainstHit.js +140 -0
- package/esm/marks/glyphPaint.d.ts +16 -0
- package/esm/marks/glyphPaint.js +41 -0
- package/esm/marks/index.d.ts +9 -0
- package/esm/marks/index.js +6 -0
- package/esm/marks/markBackend.d.ts +87 -0
- package/esm/marks/markBackend.js +133 -0
- package/esm/marks/markPaint.d.ts +13 -0
- package/esm/marks/markPaint.js +18 -0
- package/esm/marks/pointMark.d.ts +24 -0
- package/esm/marks/pointMark.js +98 -0
- package/esm/marks/spanMark.d.ts +45 -0
- package/esm/marks/spanMark.js +71 -0
- package/esm/marks/types.d.ts +206 -0
- package/esm/marks/types.js +125 -0
- package/esm/perRegionRenderingBackend.d.ts +15 -3
- package/esm/perRegionRenderingBackend.js +26 -3
- package/esm/regionDataMap.d.ts +2 -2
- package/esm/regionDataMap.js +2 -2
- package/esm/renderingBackendBase.d.ts +11 -14
- package/esm/renderingBackendBase.js +7 -7
- package/esm/shaders/capsule.js.generated.d.ts +1 -0
- package/esm/shaders/capsule.js.generated.js +11 -0
- package/esm/shaders/coverageBar.generated.d.ts +2 -2
- package/esm/shaders/coverageBar.generated.js +2 -2
- package/esm/shaders/coverageMod.generated.d.ts +2 -2
- package/esm/shaders/coverageMod.generated.js +2 -2
- package/esm/shaders/coverageSnp.generated.d.ts +2 -2
- package/esm/shaders/coverageSnp.generated.js +2 -2
- package/esm/shaders/pointMark.consts.generated.d.ts +4 -0
- package/esm/shaders/pointMark.consts.generated.js +6 -0
- package/esm/shaders/pointMark.generated.d.ts +5 -0
- package/esm/shaders/pointMark.generated.js +7 -0
- package/esm/shaders/pointMark.iface.generated.d.ts +55 -0
- package/esm/shaders/pointMark.iface.generated.js +100 -0
- package/esm/shaders/pointMark.js.generated.d.ts +1 -0
- package/esm/shaders/pointMark.js.generated.js +16 -0
- package/esm/shaders/spanMark.generated.d.ts +4 -0
- package/esm/shaders/spanMark.generated.js +6 -0
- package/esm/shaders/spanMark.iface.generated.d.ts +58 -0
- package/esm/shaders/spanMark.iface.generated.js +122 -0
- package/esm/sharedBackendKey.d.ts +18 -0
- package/esm/{keyedRenderingBackend.js → sharedBackendKey.js} +5 -0
- package/esm/slangPass.d.ts +2 -0
- package/esm/slangPass.js +2 -0
- package/package.json +13 -4
- package/src/shaders/capsule.js.generated.ts +14 -0
- package/src/shaders/capsule.slang +12 -4
- package/src/shaders/colorPack.slang +5 -1
- package/src/shaders/coverageBand.slang +38 -15
- package/src/shaders/coverageBar.generated.ts +2 -2
- package/src/shaders/coverageBar.slang +9 -0
- package/src/shaders/coverageMod.generated.ts +2 -2
- package/src/shaders/coverageSnp.generated.ts +2 -2
- package/src/shaders/hpmath.slang +7 -1
- package/src/shaders/pointMark.consts.generated.ts +10 -0
- package/src/shaders/pointMark.generated.ts +12 -0
- package/src/shaders/pointMark.iface.generated.ts +146 -0
- package/src/shaders/pointMark.js.generated.ts +21 -0
- package/src/shaders/pointMark.slang +192 -0
- package/src/shaders/rowRect.slang +7 -8
- package/src/shaders/spanMark.generated.ts +10 -0
- package/src/shaders/spanMark.iface.generated.ts +168 -0
- package/src/shaders/spanMark.slang +22 -0
- package/esm/globalRenderingBackend.d.ts +0 -90
- package/esm/globalRenderingBackend.js +0 -53
- package/esm/keyedRenderingBackend.d.ts +0 -41
package/src/shaders/hpmath.slang
CHANGED
|
@@ -8,6 +8,13 @@
|
|
|
8
8
|
// must make identically to the GPU — which pixel row a glyph centers on, how a
|
|
9
9
|
// sub-pixel span is widened. `pnpm gen:shaders` transliterates them into
|
|
10
10
|
// hpmath.js.generated.ts; nothing downstream re-derives them by hand.
|
|
11
|
+
//
|
|
12
|
+
// `expandToMinWidthPx` is exported too, but by `coverageBar.slang`, into
|
|
13
|
+
// @jbrowse/alignments-core — the twin's consumer (`fillSpanRect`) lives in a
|
|
14
|
+
// package that cannot import render-core, and this file's own redirect would
|
|
15
|
+
// move every export above with it. adr-051 §"a shader may also export a
|
|
16
|
+
// function it only imports" is the mechanism; grep the name before assuming it
|
|
17
|
+
// is unlifted.
|
|
11
18
|
//! js-export: snapBoxHeightPx, snapBoxTopPx, snapBoxCenterYPx, extendToMinWidthPx
|
|
12
19
|
//! js-skip: hpSplitUint — the hi/lo float32 precision split exists because a GPU has no float64; the Canvas2D path just uses a number
|
|
13
20
|
//! js-skip: quadLocal — maps a vertex id to a quad corner — Canvas2D has no vertices, it calls fillRect
|
|
@@ -17,7 +24,6 @@
|
|
|
17
24
|
//! js-skip: pxToClipLen — the length half of the same conversion; a px dimension is already in px on the Canvas2D side, so there is nothing to convert
|
|
18
25
|
//! js-skip: clipLenToPx — the inverse of pxToClipLen, same reason
|
|
19
26
|
//! js-skip: extendToMinWidthX — clip-space wrapper over the exported extendToMinWidthPx, which is the decision
|
|
20
|
-
//! js-skip: expandToMinWidthPx — the midpoint rule has no Canvas2D counterpart: the pileup floors a cell width one-sidedly and adds a seam fudge the shader deliberately omits (rendererTypes.ts pileupCellWidth), and the variant matrix floors in physical px against a canvas the Canvas2D twin sizes itself. A different rule, not a twin
|
|
21
27
|
//! js-skip: expandToMinWidthX — clip-space wrapper over expandToMinWidthPx, same reason as extendToMinWidthX
|
|
22
28
|
//! js-skip: snapToPixelX — clip in, clip out; its px core is `floor(x + 0.5)`, which is Math.round and needs no twin
|
|
23
29
|
//! js-skip: snapBoxCenterY — clip-space wrapper over the exported snapBoxCenterYPx
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// AUTO-GENERATED by packages/shader-tools/src/shader-codegen from pointMark.slang.
|
|
2
|
+
// Do not edit. Run `pnpm gen:shaders` to regenerate.
|
|
3
|
+
|
|
4
|
+
export const DIAMOND_GLYPH_SCALE = 1.6
|
|
5
|
+
|
|
6
|
+
export const GLYPH_DISC = 0
|
|
7
|
+
|
|
8
|
+
export const GLYPH_TRIANGLE = 1
|
|
9
|
+
|
|
10
|
+
export const GLYPH_DIAMOND = 2
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// AUTO-GENERATED by packages/shader-tools/src/shader-codegen from pointMark.slang.
|
|
2
|
+
// Do not edit. Run `pnpm gen:shaders` to regenerate.
|
|
3
|
+
|
|
4
|
+
export const WGSL_SOURCE = "struct Uniforms_std140_0\n{\n @align(16) bpRangeX_0 : vec3<f32>,\n @align(4) canvasHeight_0 : f32,\n @align(16) domainMin_0 : f32,\n @align(4) domainMax_0 : f32,\n @align(8) 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( radiusPx_1 : f32, dpr_2 : f32) -> f32\n{\n return (radiusPx_1 + aaHalfPx_0(dpr_2)) / max(radiusPx_1, 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 = (clipLenToPx_0(abs(_S9 - _S8), u_0.viewportWidth_0)) > (u_0.radiusPx_0 * 2.0f);\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 var overdrawClipX_0 : f32 = pxToClipLen_0(1.0f, u_0.viewportWidth_0);\n if(xZero_0)\n {\n x_1 = min(_S8, _S9) - overdrawClipX_0;\n }\n else\n {\n x_1 = max(_S8, _S9) + overdrawClipX_0;\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
|
+
|
|
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 radiusPx_1, float dpr_2)\n{\n\n return (radiusPx_1 + aaHalfPx_0(dpr_2)) / max(radiusPx_1, 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 = (clipLenToPx_0(abs(endClipX_0 - startClipX_0), u_0.viewportWidth_0)) > (u_0.radiusPx_0 * 2.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 float overdrawClipX_0 = pxToClipLen_0(1.0, u_0.viewportWidth_0);\n\n\n if(xZero_0)\n {\n\n x_0 = min(startClipX_0, endClipX_0) - overdrawClipX_0;\n\n }\n else\n {\n\n x_0 = max(startClipX_0, endClipX_0) + overdrawClipX_0;\n\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
|
+
|
|
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
|
+
|
|
10
|
+
export * from './pointMark.iface.generated.ts'
|
|
11
|
+
|
|
12
|
+
export * from './pointMark.consts.generated.ts'
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// AUTO-GENERATED by packages/shader-tools/src/shader-codegen from pointMark.slang.
|
|
2
|
+
// Do not edit. Run `pnpm gen:shaders` to regenerate.
|
|
3
|
+
|
|
4
|
+
import type { VertexAttributeLayout, ShaderBinding } from '@jbrowse/render-core/hal'
|
|
5
|
+
|
|
6
|
+
export const BINDINGS: readonly ShaderBinding[] = [
|
|
7
|
+
{ index: 1, kind: 'uniform', name: 'u' },
|
|
8
|
+
]
|
|
9
|
+
|
|
10
|
+
export const VERTS_PER_INSTANCE = 6
|
|
11
|
+
|
|
12
|
+
export const UNIFORMS_SIZE_BYTES = 48
|
|
13
|
+
|
|
14
|
+
// Word indices into a Float32Array view over the uniform buffer.
|
|
15
|
+
export const UNIFORM_OFFSET_F32 = {
|
|
16
|
+
bpRangeX: 0,
|
|
17
|
+
canvasHeight: 3,
|
|
18
|
+
domainMin: 4,
|
|
19
|
+
domainMax: 5,
|
|
20
|
+
zero: 6,
|
|
21
|
+
viewportWidth: 7,
|
|
22
|
+
radiusPx: 8,
|
|
23
|
+
devicePixelRatio: 9,
|
|
24
|
+
} as const
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
export interface Uniforms {
|
|
28
|
+
bpRangeX: [number, number, number]
|
|
29
|
+
canvasHeight: number
|
|
30
|
+
domainMin: number
|
|
31
|
+
domainMax: number
|
|
32
|
+
zero: number
|
|
33
|
+
viewportWidth: number
|
|
34
|
+
radiusPx: number
|
|
35
|
+
devicePixelRatio: number
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function writeUniforms(buf: ArrayBuffer, uniforms: Uniforms) {
|
|
39
|
+
const f32 = new Float32Array(buf)
|
|
40
|
+
f32[0] = uniforms.bpRangeX[0]
|
|
41
|
+
f32[1] = uniforms.bpRangeX[1]
|
|
42
|
+
f32[2] = uniforms.bpRangeX[2]
|
|
43
|
+
f32[3] = uniforms.canvasHeight
|
|
44
|
+
f32[4] = uniforms.domainMin
|
|
45
|
+
f32[5] = uniforms.domainMax
|
|
46
|
+
f32[6] = uniforms.zero
|
|
47
|
+
f32[7] = uniforms.viewportWidth
|
|
48
|
+
f32[8] = uniforms.radiusPx
|
|
49
|
+
f32[9] = uniforms.devicePixelRatio
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const INSTANCE_STRIDE_BYTES = 20
|
|
53
|
+
export const INSTANCE_STRIDE_WORDS = 5
|
|
54
|
+
|
|
55
|
+
// Word indices into a Float32Array view over the instance buffer.
|
|
56
|
+
export const INSTANCE_OFFSET_F32 = {
|
|
57
|
+
y: 2,
|
|
58
|
+
} as const
|
|
59
|
+
|
|
60
|
+
// Word indices into a Uint32Array view over the instance buffer.
|
|
61
|
+
export const INSTANCE_OFFSET_U32 = {
|
|
62
|
+
x: 0,
|
|
63
|
+
x2: 1,
|
|
64
|
+
color: 3,
|
|
65
|
+
glyph: 4,
|
|
66
|
+
} as const
|
|
67
|
+
|
|
68
|
+
export const VERTEX_ATTRIBUTES: readonly VertexAttributeLayout[] = [
|
|
69
|
+
{ name: 'a_x', components: 1, type: 'uint', offsetBytes: 0, integer: true },
|
|
70
|
+
{ name: 'a_x2', components: 1, type: 'uint', offsetBytes: 4, integer: true },
|
|
71
|
+
{ name: 'a_y', components: 1, type: 'float', offsetBytes: 8, integer: false },
|
|
72
|
+
{ name: 'a_color', components: 1, type: 'uint', offsetBytes: 12, integer: true },
|
|
73
|
+
{ name: 'a_glyph', components: 1, type: 'uint', offsetBytes: 16, integer: true },
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
export interface InstanceArrays {
|
|
77
|
+
x: ArrayLike<number>
|
|
78
|
+
x2: ArrayLike<number>
|
|
79
|
+
y: ArrayLike<number>
|
|
80
|
+
color: ArrayLike<number>
|
|
81
|
+
glyph: ArrayLike<number>
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function packInstances(
|
|
85
|
+
arrays: InstanceArrays,
|
|
86
|
+
numInstances: number,
|
|
87
|
+
buf: ArrayBuffer = new ArrayBuffer(numInstances * INSTANCE_STRIDE_BYTES),
|
|
88
|
+
) {
|
|
89
|
+
const f32 = new Float32Array(buf)
|
|
90
|
+
const u32 = new Uint32Array(buf)
|
|
91
|
+
const { x, x2, y, color, glyph } = arrays
|
|
92
|
+
for (let i = 0; i < numInstances; i++) {
|
|
93
|
+
const o = i * INSTANCE_STRIDE_WORDS
|
|
94
|
+
u32[o + 0] = x[i]!
|
|
95
|
+
u32[o + 1] = x2[i]!
|
|
96
|
+
f32[o + 2] = y[i]!
|
|
97
|
+
u32[o + 3] = color[i]!
|
|
98
|
+
u32[o + 4] = glyph[i]!
|
|
99
|
+
}
|
|
100
|
+
return buf
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Instance `i`'s `x`.
|
|
104
|
+
export function getInstanceX(u32: Uint32Array, i: number) {
|
|
105
|
+
return u32[i * INSTANCE_STRIDE_WORDS]!
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function setInstanceX(u32: Uint32Array, i: number, v: number) {
|
|
109
|
+
u32[i * INSTANCE_STRIDE_WORDS] = v
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Instance `i`'s `x2`.
|
|
113
|
+
export function getInstanceX2(u32: Uint32Array, i: number) {
|
|
114
|
+
return u32[i * INSTANCE_STRIDE_WORDS + 1]!
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function setInstanceX2(u32: Uint32Array, i: number, v: number) {
|
|
118
|
+
u32[i * INSTANCE_STRIDE_WORDS + 1] = v
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Instance `i`'s `y`.
|
|
122
|
+
export function getInstanceY(f32: Float32Array, i: number) {
|
|
123
|
+
return f32[i * INSTANCE_STRIDE_WORDS + 2]!
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function setInstanceY(f32: Float32Array, i: number, v: number) {
|
|
127
|
+
f32[i * INSTANCE_STRIDE_WORDS + 2] = v
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Instance `i`'s `color`.
|
|
131
|
+
export function getInstanceColor(u32: Uint32Array, i: number) {
|
|
132
|
+
return u32[i * INSTANCE_STRIDE_WORDS + 3]!
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function setInstanceColor(u32: Uint32Array, i: number, v: number) {
|
|
136
|
+
u32[i * INSTANCE_STRIDE_WORDS + 3] = v
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Instance `i`'s `glyph`.
|
|
140
|
+
export function getInstanceGlyph(u32: Uint32Array, i: number) {
|
|
141
|
+
return u32[i * INSTANCE_STRIDE_WORDS + 4]!
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function setInstanceGlyph(u32: Uint32Array, i: number, v: number) {
|
|
145
|
+
u32[i * INSTANCE_STRIDE_WORDS + 4] = v
|
|
146
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// AUTO-GENERATED by packages/shader-tools/src/shader-codegen from pointMark.slang.
|
|
2
|
+
// Do not edit. Run `pnpm gen:shaders` to regenerate.
|
|
3
|
+
|
|
4
|
+
// Scalar twins of pointMark.slang, transliterated from slangc's WGSL so
|
|
5
|
+
// the Canvas2D and SVG paths run the shader's own math. See adr-051.
|
|
6
|
+
|
|
7
|
+
function _clamp(x: number, lo: number, hi: number) {
|
|
8
|
+
return _min(_max(x, lo), hi)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function _max(a: number, b: number) {
|
|
12
|
+
return b > a || Number.isNaN(a) ? b : a
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function _min(a: number, b: number) {
|
|
16
|
+
return b < a || Number.isNaN(a) ? b : a
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function valueToYPx(value: number, domainMin: number, domainMax: number, h: number): number {
|
|
20
|
+
return ((1.0 - _clamp(((value - domainMin) / _max((domainMax - domainMin), 9.99999997475242708e-07)), 0.0, 1.0)) * h)
|
|
21
|
+
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
// The `point` mark shape: one glyph per instance, placed at a genomic x and at
|
|
2
|
+
// a y read off a per-instance value through a linear domain scale. The glyph
|
|
3
|
+
// channel picks between a disc, an inverted triangle and a diamond, and an
|
|
4
|
+
// instance whose x..x2 extent is wider than the glyph draws as a horizontal bar
|
|
5
|
+
// instead — the shape's own answer to "this datum has extent".
|
|
6
|
+
//
|
|
7
|
+
// All four are a 6-vertex quad; the fragment shader carves the shape.
|
|
8
|
+
//! targets: wgsl, glsl
|
|
9
|
+
//! export-consts: DIAMOND_GLYPH_SCALE, GLYPH_DISC, GLYPH_TRIANGLE, GLYPH_DIAMOND
|
|
10
|
+
//! js-export: valueToYPx
|
|
11
|
+
|
|
12
|
+
import antialias;
|
|
13
|
+
import hpmath;
|
|
14
|
+
import colorPack;
|
|
15
|
+
import pointGlyph;
|
|
16
|
+
|
|
17
|
+
public static const uint VERTS_PER_INSTANCE = 6u;
|
|
18
|
+
|
|
19
|
+
struct PointMarkInstance {
|
|
20
|
+
uint x : ATTR0;
|
|
21
|
+
uint x2 : ATTR1;
|
|
22
|
+
float y : ATTR2;
|
|
23
|
+
uint color : ATTR3;
|
|
24
|
+
uint glyph : ATTR4;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
struct Uniforms {
|
|
28
|
+
float3 bpRangeX;
|
|
29
|
+
float canvasHeight;
|
|
30
|
+
float domainMin;
|
|
31
|
+
float domainMax;
|
|
32
|
+
float zero;
|
|
33
|
+
float viewportWidth;
|
|
34
|
+
float radiusPx;
|
|
35
|
+
// Read by the glyph pad alone; every other length in this block is CSS px.
|
|
36
|
+
float devicePixelRatio;
|
|
37
|
+
};
|
|
38
|
+
[[vk::binding(1, 0)]] ConstantBuffer<Uniforms> u;
|
|
39
|
+
|
|
40
|
+
float bpToClipX(uint bp, Uniforms u) {
|
|
41
|
+
return hpToClipX(hpSplitUint(bp), u.bpRangeX, u.zero);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// The shape's y scale: clamp into the domain, invert (a bigger value sits
|
|
45
|
+
// higher), scale to the canvas. Linear only — a consumer that wants log
|
|
46
|
+
// pre-transforms its values, which is what GWAS -log10 p already is.
|
|
47
|
+
//
|
|
48
|
+
// `//! js-export`ed because the Canvas2D painter AND the hit test run the JS
|
|
49
|
+
// twin: a drift would move the grab target off the drawn glyph on the no-GPU
|
|
50
|
+
// path only.
|
|
51
|
+
//
|
|
52
|
+
// max(range, 1e-6) guards a degenerate (min == max) domain from dividing by
|
|
53
|
+
// zero. JS spelled that guard `|| 1`, and the two are NOT the same: `|| 1`
|
|
54
|
+
// invents a phantom unit-wide domain, so with bounds pinned to a single value
|
|
55
|
+
// a value half a unit above it drew half-way up the Canvas2D canvas while the
|
|
56
|
+
// GPU clamped it to the top. Pinning a degenerate domain means everything above
|
|
57
|
+
// it is off the top, which is what this does; the parity test pins the case.
|
|
58
|
+
float valueToYPx(float value, float domainMin, float domainMax, float h) {
|
|
59
|
+
float norm = clamp(
|
|
60
|
+
(value - domainMin) / max(domainMax - domainMin, 1e-6),
|
|
61
|
+
0.0,
|
|
62
|
+
1.0,
|
|
63
|
+
);
|
|
64
|
+
return (1.0 - norm) * h;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
struct VsOut {
|
|
68
|
+
float4 position : SV_Position;
|
|
69
|
+
float4 color : COLOR0;
|
|
70
|
+
float2 localPos : TEXCOORD0;
|
|
71
|
+
// Shape discriminator passed to the fragment shader: 0 = disc, 1 = diamond,
|
|
72
|
+
// 2 = inverted triangle, 3 = solid bar.
|
|
73
|
+
nointerpolation float shape : TEXCOORD1;
|
|
74
|
+
};
|
|
75
|
+
|
|
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
|
+
// Shape discriminators for the fragment shader. SMALL_POINT_MAX_DIAMETER and
|
|
81
|
+
// the disc SDF come from the shared pointGlyph module so they stay in lockstep
|
|
82
|
+
// with wiggle.slang.
|
|
83
|
+
static const float SHAPE_DISC = 0.0;
|
|
84
|
+
static const float SHAPE_DIAMOND = 1.0;
|
|
85
|
+
static const float SHAPE_TRI = 2.0;
|
|
86
|
+
// >2.5 in the fragment shader = flat solid fill (extent bar, or the tiny
|
|
87
|
+
// square below).
|
|
88
|
+
static const float SHAPE_BAR = 3.0;
|
|
89
|
+
// 1/sqrt(5): normalizes the two slanted edges of the inverted triangle so the
|
|
90
|
+
// edge functions read as true perpendicular distances for antialiasing.
|
|
91
|
+
static const float INV_SQRT5 = 0.4472136;
|
|
92
|
+
// The diamond is the shape's "singled out" glyph and draws visibly larger than
|
|
93
|
+
// the others, so it reads as the one that matters at a glance rather than as a
|
|
94
|
+
// colour swap. LocusZoom's lead-SNP convention, generalized.
|
|
95
|
+
static const float DIAMOND_GLYPH_SCALE = 1.6;
|
|
96
|
+
|
|
97
|
+
// The glyph channel's values. The numbering is a contract between whatever
|
|
98
|
+
// packs the channel, the Canvas2D painter and the branches below, so it is
|
|
99
|
+
// authored once here and `//! export-consts`ed.
|
|
100
|
+
static const uint GLYPH_DISC = 0u;
|
|
101
|
+
static const uint GLYPH_TRIANGLE = 1u;
|
|
102
|
+
static const uint GLYPH_DIAMOND = 2u;
|
|
103
|
+
|
|
104
|
+
[shader("vertex")]
|
|
105
|
+
VsOut vs_main(PointMarkInstance inst, uint vid : SV_VertexID) {
|
|
106
|
+
uint v = vid % 6u;
|
|
107
|
+
|
|
108
|
+
// Two-triangle quad corner (0/1 per axis); shared with the whole fleet.
|
|
109
|
+
float2 q = quadLocal(v);
|
|
110
|
+
float2 local = q * 2.0 - 1.0;
|
|
111
|
+
bool xZero = q.x < 0.5;
|
|
112
|
+
|
|
113
|
+
float startClipX = bpToClipX(inst.x, u);
|
|
114
|
+
float endClipX = bpToClipX(inst.x2, u);
|
|
115
|
+
float yPx = valueToYPx(inst.y, u.domainMin, u.domainMax, u.canvasHeight);
|
|
116
|
+
float centerClipY = yPxToClipY(yPx, u.canvasHeight);
|
|
117
|
+
|
|
118
|
+
// Genomic span in CSS px (clip width spans -1..1 across viewportWidth).
|
|
119
|
+
// abs() because reversal is baked into bpRangeX (negated length), so
|
|
120
|
+
// endClipX < startClipX on reversed regions — matches wiggle.slang.
|
|
121
|
+
float spanPx = clipLenToPx(abs(endClipX - startClipX), u.viewportWidth);
|
|
122
|
+
bool isBar = spanPx > u.radiusPx * 2.0;
|
|
123
|
+
|
|
124
|
+
VsOut o;
|
|
125
|
+
o.color = unpackRGBA(inst.color);
|
|
126
|
+
if (isBar) {
|
|
127
|
+
// Horizontal bar from x→x2, height 2*radiusPx px, centered on the value.
|
|
128
|
+
float overdrawClipX = pxToClipLen(BAR_OVERDRAW_PX, u.viewportWidth);
|
|
129
|
+
// min/max so a reversed region (endClipX < startClipX) still spans the full
|
|
130
|
+
// bar extent instead of drawing an inverted quad — matches wiggle.slang.
|
|
131
|
+
float x = xZero ? (min(startClipX, endClipX) - overdrawClipX)
|
|
132
|
+
: (max(startClipX, endClipX) + overdrawClipX);
|
|
133
|
+
float halfBandPx = u.radiusPx;
|
|
134
|
+
float y = centerClipY + pxToClipLen(local.y * halfBandPx, u.canvasHeight);
|
|
135
|
+
o.position = float4(x, y, 0.0, 1.0);
|
|
136
|
+
o.localPos = local;
|
|
137
|
+
o.shape = SHAPE_BAR;
|
|
138
|
+
} else if (inst.glyph == GLYPH_DISC && u.radiusPx * 2.0 <= SMALL_POINT_MAX_DIAMETER) {
|
|
139
|
+
// tiny disc: pixel-snapped crisp filled square (no AA disc). The triangle
|
|
140
|
+
// and the diamond keep their distinct marker even when small.
|
|
141
|
+
float diamPx = u.radiusPx * 2.0;
|
|
142
|
+
o.position = crispSquareCornerClip(startClipX, yPx, diamPx, q,
|
|
143
|
+
u.viewportWidth, u.canvasHeight);
|
|
144
|
+
o.localPos = local;
|
|
145
|
+
o.shape = SHAPE_BAR;
|
|
146
|
+
} else {
|
|
147
|
+
float expand = discExpand(u.radiusPx, u.devicePixelRatio);
|
|
148
|
+
float glyphScale = inst.glyph == GLYPH_DIAMOND ? DIAMOND_GLYPH_SCALE : 1.0;
|
|
149
|
+
float halfPx = u.radiusPx * expand * glyphScale;
|
|
150
|
+
float dx = pxToClipLen(local.x * halfPx, u.viewportWidth);
|
|
151
|
+
float dy = pxToClipLen(local.y * halfPx, u.canvasHeight);
|
|
152
|
+
o.position = float4(startClipX + dx, centerClipY + dy, 0.0, 1.0);
|
|
153
|
+
o.localPos = local * expand;
|
|
154
|
+
o.shape = inst.glyph == GLYPH_TRIANGLE ? SHAPE_TRI
|
|
155
|
+
: (inst.glyph == GLYPH_DIAMOND ? SHAPE_DIAMOND : SHAPE_DISC);
|
|
156
|
+
}
|
|
157
|
+
return o;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
[shader("fragment")]
|
|
161
|
+
float4 fs_main(VsOut fragIn) : SV_Target {
|
|
162
|
+
// Each glyph only picks its SDF here; the AA derivative is taken once after
|
|
163
|
+
// the branch, because WGSL rejects a derivative under a branch on a varying
|
|
164
|
+
// ("must only be called from uniform control flow"). shape is constant per
|
|
165
|
+
// primitive, so the shared ramp is exact.
|
|
166
|
+
float2 p = fragIn.localPos;
|
|
167
|
+
float coverage;
|
|
168
|
+
if (fragIn.shape > 2.5) {
|
|
169
|
+
// Extent bar: solid fill, no marker AA. A constant SDF has zero gradient,
|
|
170
|
+
// so the ramp below saturates to alpha 1.
|
|
171
|
+
coverage = 1.0;
|
|
172
|
+
} else if (fragIn.shape > 1.5) {
|
|
173
|
+
// Inverted triangle: top edge (-1,1)-(1,1), apex (0,-1). Each edge's signed
|
|
174
|
+
// distance is positive inside; the min is the SDF used for the AA fade.
|
|
175
|
+
float dTop = 1.0 - p.y;
|
|
176
|
+
float dLeft = (2.0 * p.x + p.y + 1.0) * INV_SQRT5;
|
|
177
|
+
float dRight = (-2.0 * p.x + p.y + 1.0) * INV_SQRT5;
|
|
178
|
+
coverage = min(dTop, min(dLeft, dRight));
|
|
179
|
+
} else if (fragIn.shape > 0.5) {
|
|
180
|
+
// Diamond (rhombus): L1-norm distance from center, positive inside, zero at
|
|
181
|
+
// the four edges.
|
|
182
|
+
coverage = 1.0 - (abs(p.x) + abs(p.y));
|
|
183
|
+
} else {
|
|
184
|
+
coverage = discCoverage(p);
|
|
185
|
+
}
|
|
186
|
+
// One output pixel of ramp, from the SDF's own gradient — which is what lets
|
|
187
|
+
// the four shapes above share a single line despite the diamond's L1 norm
|
|
188
|
+
// carrying a sqrt(2) the others don't. See antialias.slang's glyphEdgeAlpha.
|
|
189
|
+
float alpha = glyphEdgeAlpha(coverage);
|
|
190
|
+
if (alpha <= 0.0) discard;
|
|
191
|
+
return float4(fragIn.color.rgb, fragIn.color.a * alpha);
|
|
192
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Shared "row of colored rects" primitive: one instance is a rectangle
|
|
2
|
-
// spanning [
|
|
3
|
-
//
|
|
2
|
+
// spanning [x, x2) in absolute genomic coords, drawn on the row given by
|
|
3
|
+
// `row` and filled with a per-instance packed ABGR color.
|
|
4
4
|
//
|
|
5
5
|
// Two renderers draw exactly this: the MAF alignment renderer (run-merged
|
|
6
6
|
// per-base cells) and the multi-row feature painter / "chromosome painting"
|
|
@@ -26,10 +26,10 @@ import colorPack;
|
|
|
26
26
|
import hpmath;
|
|
27
27
|
|
|
28
28
|
public struct RowRectInstance {
|
|
29
|
-
public uint
|
|
30
|
-
public uint
|
|
31
|
-
public uint
|
|
32
|
-
public uint color
|
|
29
|
+
public uint x : ATTR0;
|
|
30
|
+
public uint x2 : ATTR1;
|
|
31
|
+
public uint row : ATTR2;
|
|
32
|
+
public uint color : ATTR3; // packed ABGR
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
public struct RowRectUniforms {
|
|
@@ -143,8 +143,7 @@ public RowRectVsOut rowRectVertex(
|
|
|
143
143
|
RowRectInstance inst, uint vid, RowRectUniforms u
|
|
144
144
|
) {
|
|
145
145
|
RowRectVsOut o;
|
|
146
|
-
o.position = rowRectClipPos(
|
|
147
|
-
inst.startBp, inst.endBp, float(inst.rowIndex), vid, u);
|
|
146
|
+
o.position = rowRectClipPos(inst.x, inst.x2, float(inst.row), vid, u);
|
|
148
147
|
o.color = unpackRGBA(inst.color);
|
|
149
148
|
return o;
|
|
150
149
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// AUTO-GENERATED by packages/shader-tools/src/shader-codegen from spanMark.slang.
|
|
2
|
+
// Do not edit. Run `pnpm gen:shaders` to regenerate.
|
|
3
|
+
|
|
4
|
+
export const WGSL_SOURCE = "struct RowRectUniforms_std140_0\n{\n @align(16) bpRangeX_0 : vec3<f32>,\n @align(4) canvasHeight_0 : f32,\n @align(16) minCellDenomPx_0 : f32,\n @align(4) minCellPx_0 : f32,\n @align(8) zero_0 : f32,\n @align(4) rowHeight_0 : f32,\n @align(16) rowProportion_0 : f32,\n @align(4) scrollTop_0 : f32,\n};\n\n@binding(1) @group(0) var<uniform> u_0 : RowRectUniforms_std140_0;\nfn quadLocal_0( vid_0 : u32) -> vec2<f32>\n{\n var v_0 : u32 = vid_0 % u32(6);\n var _S1 : bool = v_0 == u32(0);\n var _S2 : bool;\n if(_S1)\n {\n _S2 = true;\n }\n else\n {\n _S2 = v_0 == u32(2);\n }\n if(_S2)\n {\n _S2 = true;\n }\n else\n {\n _S2 = v_0 == u32(3);\n }\n var _S3 : f32;\n if(_S2)\n {\n _S3 = 0.0f;\n }\n else\n {\n _S3 = 1.0f;\n }\n if(_S1)\n {\n _S2 = true;\n }\n else\n {\n _S2 = v_0 == u32(1);\n }\n if(_S2)\n {\n _S2 = true;\n }\n else\n {\n _S2 = v_0 == u32(4);\n }\n var _S4 : f32;\n if(_S2)\n {\n _S4 = 0.0f;\n }\n else\n {\n _S4 = 1.0f;\n }\n return vec2<f32>(_S3, _S4);\n}\n\nfn drawnRowHeightPx_0( rowHeight_1 : f32, rowProportion_1 : f32) -> f32\n{\n return max(rowHeight_1 * rowProportion_1, 1.0f);\n}\n\nfn rowBandOffsetPx_0( rowHeight_2 : f32, rowProportion_2 : f32) -> f32\n{\n return (rowHeight_2 - drawnRowHeightPx_0(rowHeight_2, rowProportion_2)) * 0.5f;\n}\n\nstruct RowBand_0\n{\n height_0 : f32,\n offset_0 : f32,\n};\n\nfn rowBandPx_0( rowHeight_3 : f32, rowProportion_3 : f32) -> RowBand_0\n{\n var band_0 : RowBand_0;\n band_0.height_0 = drawnRowHeightPx_0(rowHeight_3, rowProportion_3);\n band_0.offset_0 = rowBandOffsetPx_0(rowHeight_3, rowProportion_3);\n return band_0;\n}\n\nfn hpSplitUint_0( value_0 : u32) -> vec2<f32>\n{\n var lo_0 : u32 = (value_0 & (u32(4095)));\n return vec2<f32>(f32(value_0 - lo_0), f32(lo_0));\n}\n\nfn hpToClipX_0( splitPos_0 : vec2<f32>, bpRange_0 : vec3<f32>, hpZero_0 : f32) -> f32\n{\n var step_0 : f32 = 2.0f / bpRange_0.z;\n var _S5 : f32 = - (1.0f / hpZero_0);\n return dot(vec3<f32>(-1.0f, max(splitPos_0.x - bpRange_0.x, _S5), max(splitPos_0.y - bpRange_0.y, _S5)), vec3<f32>(1.0f, step_0, step_0));\n}\n\nfn extendToMinWidthPx_0( x1_0 : f32, x2_0 : f32, minWidth_0 : f32) -> f32\n{\n var dx_0 : f32 = x2_0 - x1_0;\n var _S6 : f32;\n if((abs(dx_0)) < minWidth_0)\n {\n if(dx_0 < 0.0f)\n {\n _S6 = - minWidth_0;\n }\n else\n {\n _S6 = minWidth_0;\n }\n _S6 = x1_0 + _S6;\n }\n else\n {\n _S6 = x2_0;\n }\n return _S6;\n}\n\nfn extendToMinWidthX_0( x1_1 : f32, x2_1 : f32, minWidthPx_0 : f32, canvasWidth_0 : f32) -> f32\n{\n return extendToMinWidthPx_0(x1_1, x2_1, minWidthPx_0 * 2.0f / canvasWidth_0);\n}\n\nfn yPxToClipY_0( yPx_0 : f32, canvasHeight_1 : f32) -> f32\n{\n return 1.0f - yPx_0 / canvasHeight_1 * 2.0f;\n}\n\nfn rowRectClipPos_0( startBp_0 : u32, endBp_0 : u32, rowIndex_0 : f32, vid_1 : u32, u_1 : ptr<function, RowRectUniforms_std140_0>) -> vec4<f32>\n{\n var local_0 : vec2<f32> = quadLocal_0(vid_1);\n var band_1 : RowBand_0 = rowBandPx_0((*u_1).rowHeight_0, (*u_1).rowProportion_0);\n var rowY_0 : f32 = band_1.offset_0 + (*u_1).rowHeight_0 * rowIndex_0 - (*u_1).scrollTop_0;\n var sx1_0 : f32 = hpToClipX_0(hpSplitUint_0(startBp_0), (*u_1).bpRangeX_0, (*u_1).zero_0);\n return vec4<f32>(mix(sx1_0, extendToMinWidthX_0(sx1_0, hpToClipX_0(hpSplitUint_0(endBp_0), (*u_1).bpRangeX_0, (*u_1).zero_0), (*u_1).minCellPx_0, (*u_1).minCellDenomPx_0), local_0.x), yPxToClipY_0(mix(rowY_0, rowY_0 + band_1.height_0, local_0.y), (*u_1).canvasHeight_0), 0.0f, 1.0f);\n}\n\nfn unpackRGBA_0( c_0 : u32) -> vec4<f32>\n{\n return vec4<f32>(f32((((c_0 >> (u32(0)))) & (u32(255)))), f32((((c_0 >> (u32(8)))) & (u32(255)))), f32((((c_0 >> (u32(16)))) & (u32(255)))), f32((((c_0 >> (u32(24)))) & (u32(255))))) / vec4<f32>(255.0f);\n}\n\nstruct RowRectVsOut_0\n{\n @builtin(position) position_0 : vec4<f32>,\n @location(0) color_0 : vec4<f32>,\n};\n\nstruct RowRectInstance_0\n{\n x_0 : u32,\n x2_2 : u32,\n row_0 : u32,\n color_1 : u32,\n};\n\nfn rowRectVertex_0( inst_0 : RowRectInstance_0, vid_2 : u32, u_2 : ptr<function, RowRectUniforms_std140_0>) -> RowRectVsOut_0\n{\n var o_0 : RowRectVsOut_0;\n var _S7 : vec4<f32> = rowRectClipPos_0(inst_0.x_0, inst_0.x2_2, f32(inst_0.row_0), vid_2, &((*u_2)));\n o_0.position_0 = _S7;\n o_0.color_0 = unpackRGBA_0(inst_0.color_1);\n return o_0;\n}\n\nstruct vertexInput_0\n{\n @location(0) x_1 : u32,\n @location(1) x2_3 : u32,\n @location(2) row_1 : u32,\n @location(3) color_2 : u32,\n};\n\n@vertex\nfn vs_main( _S8 : vertexInput_0, @builtin(vertex_index) vid_3 : u32) -> RowRectVsOut_0\n{\n var _S9 : RowRectInstance_0 = RowRectInstance_0( _S8.x_1, _S8.x2_3, _S8.row_1, _S8.color_2 );\n var _S10 : RowRectUniforms_std140_0 = u_0;\n var _S11 : RowRectVsOut_0 = rowRectVertex_0(_S9, vid_3, &(_S10));\n return _S11;\n}\n\nstruct pixelOutput_0\n{\n @location(0) output_0 : vec4<f32>,\n};\n\nstruct pixelInput_0\n{\n @location(0) color_3 : vec4<f32>,\n};\n\n@fragment\nfn fs_main( _S12 : pixelInput_0, @builtin(position) position_1 : vec4<f32>) -> pixelOutput_0\n{\n var _S13 : pixelOutput_0 = pixelOutput_0( _S12.color_3 );\n return _S13;\n}\n\n"
|
|
5
|
+
|
|
6
|
+
export const GLSL_VERTEX = "#version 300 es\nprecision highp float;\nprecision highp int;\nstruct RowRectUniforms_0\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float minCellDenomPx_0;\n float minCellPx_0;\n float zero_0;\n float rowHeight_0;\n float rowProportion_0;\n float scrollTop_0;\n};\n\n\nlayout(std140) uniform Uniforms\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float minCellDenomPx_0;\n float minCellPx_0;\n float zero_0;\n float rowHeight_0;\n float rowProportion_0;\n float scrollTop_0;\n}u_0;\n\nvec2 quadLocal_0(uint vid_0)\n{\n\n uint v_0 = vid_0 % 6U;\n\n bool _S1 = v_0 == 0U;\n\n bool _S2;\n\n if(_S1)\n {\n\n _S2 = true;\n\n }\n else\n {\n\n _S2 = v_0 == 2U;\n\n }\n\n if(_S2)\n {\n\n _S2 = true;\n\n }\n else\n {\n\n _S2 = v_0 == 3U;\n\n }\n\n float _S3;\n\n if(_S2)\n {\n\n _S3 = 0.0;\n\n }\n else\n {\n\n _S3 = 1.0;\n\n }\n if(_S1)\n {\n\n _S2 = true;\n\n }\n else\n {\n\n _S2 = v_0 == 1U;\n\n }\n\n if(_S2)\n {\n\n _S2 = true;\n\n }\n else\n {\n\n _S2 = v_0 == 4U;\n\n }\n\n float _S4;\n\n if(_S2)\n {\n\n _S4 = 0.0;\n\n }\n else\n {\n\n _S4 = 1.0;\n\n }\n\n return vec2(_S3, _S4);\n}\n\n\nfloat drawnRowHeightPx_0(float rowHeight_1, float rowProportion_1)\n{\n\n return max(rowHeight_1 * rowProportion_1, 1.0);\n}\n\nfloat rowBandOffsetPx_0(float rowHeight_2, float rowProportion_2)\n{\n\n return (rowHeight_2 - drawnRowHeightPx_0(rowHeight_2, rowProportion_2)) * 0.5;\n}\n\n\nstruct RowBand_0\n{\n float height_0;\n float offset_0;\n};\n\n\nRowBand_0 rowBandPx_0(float rowHeight_3, float rowProportion_3)\n{\n\n RowBand_0 band_0;\n band_0.height_0 = drawnRowHeightPx_0(rowHeight_3, rowProportion_3);\n band_0.offset_0 = rowBandOffsetPx_0(rowHeight_3, rowProportion_3);\n return band_0;\n}\n\n\nvec2 hpSplitUint_0(uint value_0)\n{\n\n uint lo_0 = value_0 & 4095U;\n\n return vec2(float(value_0 - lo_0), float(lo_0));\n}\n\n\nfloat hpToClipX_0(vec2 splitPos_0, vec3 bpRange_0, float hpZero_0)\n{\n float step_0 = 2.0 / bpRange_0.z;\n float _S5 = - (1.0 / hpZero_0);\n\n return dot(vec3(-1.0, max(splitPos_0.x - bpRange_0.x, _S5), max(splitPos_0.y - bpRange_0.y, _S5)), vec3(1.0, step_0, step_0));\n}\n\n\nfloat extendToMinWidthPx_0(float x1_0, float x2_0, float minWidth_0)\n{\n\n float dx_0 = x2_0 - x1_0;\n\n float _S6;\n if((abs(dx_0)) < minWidth_0)\n {\n\n if(dx_0 < 0.0)\n {\n\n _S6 = - minWidth_0;\n\n }\n else\n {\n\n _S6 = minWidth_0;\n\n }\n\n _S6 = x1_0 + _S6;\n\n }\n else\n {\n\n _S6 = x2_0;\n\n }\n\n return _S6;\n}\n\nfloat extendToMinWidthX_0(float x1_1, float x2_1, float minWidthPx_0, float canvasWidth_0)\n{\n\n return extendToMinWidthPx_0(x1_1, x2_1, minWidthPx_0 * 2.0 / canvasWidth_0);\n}\n\n\nfloat yPxToClipY_0(float yPx_0, float canvasHeight_1)\n{\n\n return 1.0 - yPx_0 / canvasHeight_1 * 2.0;\n}\n\n\nvec4 rowRectClipPos_0(uint startBp_0, uint endBp_0, float rowIndex_0, uint vid_1, RowRectUniforms_0 u_1)\n{\n\n vec2 local_0 = quadLocal_0(vid_1);\n\n RowBand_0 band_1 = rowBandPx_0(u_1.rowHeight_0, u_1.rowProportion_0);\n float rowY_0 = band_1.offset_0 + u_1.rowHeight_0 * rowIndex_0 - u_1.scrollTop_0;\n\n float sx1_0 = hpToClipX_0(hpSplitUint_0(startBp_0), u_1.bpRangeX_0, u_1.zero_0);\n\n return vec4(mix(sx1_0, extendToMinWidthX_0(sx1_0, hpToClipX_0(hpSplitUint_0(endBp_0), u_1.bpRangeX_0, u_1.zero_0), u_1.minCellPx_0, u_1.minCellDenomPx_0), local_0.x), yPxToClipY_0(mix(rowY_0, rowY_0 + band_1.height_0, local_0.y), u_1.canvasHeight_0), 0.0, 1.0);\n}\n\n\nvec4 unpackRGBA_0(uint c_0)\n{\n\n return vec4(float((c_0 >> 0U) & 255U), float((c_0 >> 8U) & 255U), float((c_0 >> 16U) & 255U), float((c_0 >> 24U) & 255U)) / 255.0;\n}\n\n\nstruct RowRectVsOut_0\n{\n vec4 position_0;\n vec4 color_0;\n};\n\n\nstruct RowRectInstance_0\n{\n uint x_0;\n uint x2_2;\n uint row_0;\n uint color_1;\n};\n\n\nRowRectVsOut_0 rowRectVertex_0(RowRectInstance_0 inst_0, uint vid_2, RowRectUniforms_0 u_2)\n{\n\n RowRectVsOut_0 o_0;\n o_0.position_0 = rowRectClipPos_0(inst_0.x_0, inst_0.x2_2, float(inst_0.row_0), vid_2, u_2);\n o_0.color_0 = unpackRGBA_0(inst_0.color_1);\n return o_0;\n}\n\n\nout vec4 v_color;\n\n\nlayout(location = 0)\nin uint a_x;\n\n\nlayout(location = 1)\nin uint a_x2;\n\n\nlayout(location = 2)\nin uint a_row;\n\n\nlayout(location = 3)\nin uint a_color;\n\n\nvoid main()\n{\n\n RowRectUniforms_0 _S7 = RowRectUniforms_0(u_0.bpRangeX_0, u_0.canvasHeight_0, u_0.minCellDenomPx_0, u_0.minCellPx_0, u_0.zero_0, u_0.rowHeight_0, u_0.rowProportion_0, u_0.scrollTop_0);\n\n RowRectInstance_0 _S8 = RowRectInstance_0(a_x, a_x2, a_row, a_color);\n RowRectVsOut_0 _S9 = rowRectVertex_0(_S8, uint(gl_VertexID), _S7);\n\n gl_Position = _S9.position_0;\n\n v_color = _S9.color_0;\n\n return;\n}\n\n"
|
|
7
|
+
|
|
8
|
+
export const GLSL_FRAGMENT = "#version 300 es\nprecision highp float;\nprecision highp int;\nlayout(location = 0)\nout vec4 entryPointParam_fs_main_0;\n\n\nin vec4 v_color;\n\n\nvoid main()\n{\n\n entryPointParam_fs_main_0 = v_color;\n\n return;\n}\n\n"
|
|
9
|
+
|
|
10
|
+
export * from './spanMark.iface.generated.ts'
|