@jbrowse/render-core 4.3.0 → 5.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/RenderCanvas.d.ts +2 -2
- package/esm/RenderLifecycleMixin.d.ts +52 -20
- package/esm/RenderLifecycleMixin.js +89 -23
- package/esm/canvas2dUtils.d.ts +90 -23
- package/esm/canvas2dUtils.js +119 -36
- package/esm/colorRampLut.d.ts +5 -5
- package/esm/colorRampLut.js +6 -6
- package/esm/computePipeline.d.ts +14 -0
- package/esm/computePipeline.js +62 -0
- package/esm/contractReports.d.ts +54 -0
- package/esm/contractReports.js +112 -0
- package/esm/coverageBand.d.ts +13 -8
- package/esm/coverageBand.js +15 -5
- package/esm/coverageBandBuffers.d.ts +2 -9
- package/esm/coverageBandBuffers.js +1 -13
- package/esm/createRenderingBackend.d.ts +14 -18
- package/esm/createRenderingBackend.js +4 -2
- package/esm/displayPhase.d.ts +83 -104
- package/esm/displayPhase.js +42 -82
- package/esm/encodeMemo.d.ts +14 -0
- package/esm/encodeMemo.js +48 -0
- package/esm/gpuContextLostError.d.ts +30 -0
- package/esm/gpuContextLostError.js +40 -0
- package/esm/gpuDevice.d.ts +29 -10
- package/esm/gpuDevice.js +35 -16
- package/esm/graphicsCapabilities.d.ts +27 -19
- package/esm/graphicsCapabilities.js +40 -18
- package/esm/hal/createHal.d.ts +4 -5
- package/esm/hal/createHal.js +14 -4
- package/esm/hal/deviceGpuCache.d.ts +25 -30
- package/esm/hal/deviceGpuCache.js +88 -97
- package/esm/hal/gpuHalBase.d.ts +5 -4
- package/esm/hal/gpuHalBase.js +25 -14
- package/esm/hal/index.d.ts +2 -2
- package/esm/hal/index.js +1 -1
- package/esm/hal/mockHal.d.ts +15 -10
- package/esm/hal/mockHal.js +31 -18
- package/esm/hal/oomReporter.d.ts +7 -0
- package/esm/hal/oomReporter.js +10 -0
- package/esm/hal/passIds.d.ts +8 -7
- package/esm/hal/passIds.js +11 -10
- package/esm/hal/regionRegistry.d.ts +0 -1
- package/esm/hal/regionRegistry.js +3 -15
- package/esm/hal/types.d.ts +55 -18
- package/esm/hal/webgl2Hal.d.ts +23 -6
- package/esm/hal/webgl2Hal.js +161 -155
- package/esm/hal/webgpuHal.d.ts +29 -13
- package/esm/hal/webgpuHal.js +221 -153
- package/esm/installUpload.d.ts +16 -3
- package/esm/installUpload.js +13 -41
- package/esm/instanceCache.d.ts +10 -7
- package/esm/instanceCache.js +14 -15
- package/esm/instancePass.d.ts +2 -1
- package/esm/mapUploadSync.d.ts +2 -10
- package/esm/mapUploadSync.js +2 -3
- package/esm/marks/barMark.d.ts +30 -0
- package/esm/marks/barMark.js +149 -0
- package/esm/marks/colorFill.d.ts +17 -0
- package/esm/marks/colorFill.js +26 -0
- package/esm/marks/drawAgainstHit.d.ts +113 -0
- package/esm/marks/drawAgainstHit.js +407 -0
- package/esm/marks/ellipseDistance.d.ts +10 -0
- package/esm/marks/ellipseDistance.js +136 -0
- package/esm/marks/glyphPaint.d.ts +36 -0
- package/esm/marks/glyphPaint.js +77 -0
- package/esm/marks/index.d.ts +33 -0
- package/esm/marks/index.js +20 -0
- package/esm/marks/lineMark.d.ts +37 -0
- package/esm/marks/lineMark.js +416 -0
- package/esm/marks/linkMark.d.ts +76 -0
- package/esm/marks/linkMark.js +585 -0
- package/esm/marks/markBackend.d.ts +118 -0
- package/esm/marks/markBackend.js +196 -0
- package/esm/marks/markHit.d.ts +32 -0
- package/esm/marks/markHit.js +61 -0
- package/esm/marks/markInk.d.ts +18 -0
- package/esm/marks/markInk.js +71 -0
- package/esm/marks/markPaint.d.ts +14 -0
- package/esm/marks/markPaint.js +32 -0
- package/esm/marks/markPlan.d.ts +25 -0
- package/esm/marks/markPlan.js +20 -0
- package/esm/marks/markRamp.d.ts +72 -0
- package/esm/marks/markRamp.js +197 -0
- package/esm/marks/nearestMarkHit.d.ts +55 -0
- package/esm/marks/nearestMarkHit.js +158 -0
- package/esm/marks/pathRecorder.d.ts +14 -0
- package/esm/marks/pathRecorder.js +80 -0
- package/esm/marks/pointMark.d.ts +42 -0
- package/esm/marks/pointMark.js +125 -0
- package/esm/marks/rowLane.d.ts +39 -0
- package/esm/marks/rowLane.js +41 -0
- package/esm/marks/rowSpanIndex.d.ts +29 -0
- package/esm/marks/rowSpanIndex.js +141 -0
- package/esm/marks/rowTable.d.ts +41 -0
- package/esm/marks/rowTable.js +75 -0
- package/esm/marks/ruleMark.d.ts +21 -0
- package/esm/marks/ruleMark.js +91 -0
- package/esm/marks/spanMark.d.ts +42 -0
- package/esm/marks/spanMark.js +81 -0
- package/esm/marks/types.d.ts +261 -0
- package/esm/marks/types.js +175 -0
- package/esm/marks/valueScale.d.ts +23 -0
- package/esm/marks/valueScale.js +11 -0
- package/esm/namedReactions.d.ts +3 -4
- package/esm/namedReactions.js +3 -4
- package/esm/perRegionRenderingBackend.d.ts +21 -3
- package/esm/perRegionRenderingBackend.js +37 -3
- package/esm/regionDataMap.d.ts +2 -2
- package/esm/regionDataMap.js +25 -23
- package/esm/renderBlock.d.ts +14 -0
- package/esm/renderBlock.js +25 -0
- package/esm/renderingBackendBase.d.ts +20 -14
- package/esm/renderingBackendBase.js +12 -7
- package/esm/scoreScale.d.ts +27 -0
- package/esm/scoreScale.js +88 -0
- package/esm/shaders/barMark.generated.d.ts +3 -0
- package/esm/shaders/barMark.generated.js +7 -0
- package/esm/shaders/barMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/barMark.glsl.generated.js +4 -0
- package/esm/shaders/barMark.iface.generated.d.ts +90 -0
- package/esm/shaders/barMark.iface.generated.js +205 -0
- package/esm/shaders/barMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/barMark.wgsl.generated.js +3 -0
- package/esm/shaders/capsule.js.generated.d.ts +1 -0
- package/esm/shaders/capsule.js.generated.js +11 -0
- package/esm/shaders/clipStrip.generated.d.ts +2 -0
- package/esm/shaders/clipStrip.generated.js +4 -0
- package/esm/shaders/clipStrip.js.generated.d.ts +1 -0
- package/esm/shaders/clipStrip.js.generated.js +21 -0
- package/esm/shaders/colorRampLut.js.generated.d.ts +1 -0
- package/esm/shaders/colorRampLut.js.generated.js +17 -0
- package/esm/shaders/coverageBar.generated.d.ts +2 -3
- package/esm/shaders/coverageBar.generated.js +4 -3
- package/esm/shaders/coverageBar.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageBar.glsl.generated.js +4 -0
- package/esm/shaders/coverageBar.iface.generated.js +1 -1
- package/esm/shaders/coverageBar.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageBar.wgsl.generated.js +3 -0
- package/esm/shaders/coverageClip.generated.d.ts +3 -0
- package/esm/shaders/coverageClip.generated.js +7 -0
- package/esm/shaders/coverageClip.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageClip.glsl.generated.js +4 -0
- package/esm/shaders/coverageClip.iface.generated.d.ts +85 -0
- package/esm/shaders/coverageClip.iface.generated.js +114 -0
- package/esm/shaders/coverageClip.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageClip.wgsl.generated.js +3 -0
- package/esm/shaders/coverageIndicator.generated.d.ts +2 -3
- package/esm/shaders/coverageIndicator.generated.js +4 -3
- package/esm/shaders/coverageIndicator.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageIndicator.glsl.generated.js +4 -0
- package/esm/shaders/coverageIndicator.iface.generated.js +1 -1
- package/esm/shaders/coverageIndicator.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageIndicator.wgsl.generated.js +3 -0
- package/esm/shaders/coverageInterbase.generated.d.ts +2 -3
- package/esm/shaders/coverageInterbase.generated.js +4 -3
- package/esm/shaders/coverageInterbase.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageInterbase.glsl.generated.js +4 -0
- package/esm/shaders/coverageInterbase.iface.generated.js +1 -1
- package/esm/shaders/coverageInterbase.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageInterbase.wgsl.generated.js +3 -0
- package/esm/shaders/coverageMod.generated.d.ts +2 -3
- package/esm/shaders/coverageMod.generated.js +4 -3
- package/esm/shaders/coverageMod.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageMod.glsl.generated.js +4 -0
- package/esm/shaders/coverageMod.iface.generated.js +1 -1
- package/esm/shaders/coverageMod.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageMod.wgsl.generated.js +3 -0
- package/esm/shaders/coverageSnp.generated.d.ts +2 -3
- package/esm/shaders/coverageSnp.generated.js +4 -3
- package/esm/shaders/coverageSnp.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageSnp.glsl.generated.js +4 -0
- package/esm/shaders/coverageSnp.iface.generated.js +1 -1
- package/esm/shaders/coverageSnp.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageSnp.wgsl.generated.js +3 -0
- package/esm/shaders/curveDistance.js.generated.d.ts +5 -0
- package/esm/shaders/curveDistance.js.generated.js +87 -0
- package/esm/shaders/hpmath.js.generated.d.ts +2 -1
- package/esm/shaders/hpmath.js.generated.js +5 -2
- package/esm/shaders/lineCenterMark.generated.d.ts +3 -0
- package/esm/shaders/lineCenterMark.generated.js +7 -0
- package/esm/shaders/lineCenterMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/lineCenterMark.glsl.generated.js +4 -0
- package/esm/shaders/lineCenterMark.iface.generated.d.ts +104 -0
- package/esm/shaders/lineCenterMark.iface.generated.js +237 -0
- package/esm/shaders/lineCenterMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/lineCenterMark.wgsl.generated.js +3 -0
- package/esm/shaders/lineCommon.generated.d.ts +2 -0
- package/esm/shaders/lineCommon.generated.js +4 -0
- package/esm/shaders/lineStepMark.generated.d.ts +3 -0
- package/esm/shaders/lineStepMark.generated.js +7 -0
- package/esm/shaders/lineStepMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/lineStepMark.glsl.generated.js +4 -0
- package/esm/shaders/lineStepMark.iface.generated.d.ts +98 -0
- package/esm/shaders/lineStepMark.iface.generated.js +225 -0
- package/esm/shaders/lineStepMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/lineStepMark.wgsl.generated.js +3 -0
- package/esm/shaders/linkMark.consts.generated.d.ts +14 -0
- package/esm/shaders/linkMark.consts.generated.js +16 -0
- package/esm/shaders/linkMark.generated.d.ts +4 -0
- package/esm/shaders/linkMark.generated.js +8 -0
- package/esm/shaders/linkMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/linkMark.glsl.generated.js +4 -0
- package/esm/shaders/linkMark.iface.generated.d.ts +142 -0
- package/esm/shaders/linkMark.iface.generated.js +1829 -0
- package/esm/shaders/linkMark.js.generated.d.ts +7 -0
- package/esm/shaders/linkMark.js.generated.js +159 -0
- package/esm/shaders/linkMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/linkMark.wgsl.generated.js +3 -0
- package/esm/shaders/markColor.generated.d.ts +9 -0
- package/esm/shaders/markColor.generated.js +11 -0
- package/esm/shaders/pointGlyph.js.generated.d.ts +2 -0
- package/esm/shaders/pointGlyph.js.generated.js +15 -0
- package/esm/shaders/pointMark.consts.generated.d.ts +7 -0
- package/esm/shaders/pointMark.consts.generated.js +9 -0
- package/esm/shaders/pointMark.generated.d.ts +4 -0
- package/esm/shaders/pointMark.generated.js +8 -0
- package/esm/shaders/pointMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/pointMark.glsl.generated.js +4 -0
- package/esm/shaders/pointMark.iface.generated.d.ts +98 -0
- package/esm/shaders/pointMark.iface.generated.js +219 -0
- package/esm/shaders/pointMark.js.generated.d.ts +3 -0
- package/esm/shaders/pointMark.js.generated.js +93 -0
- package/esm/shaders/pointMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/pointMark.wgsl.generated.js +3 -0
- package/esm/shaders/rowRect.generated.d.ts +0 -1
- package/esm/shaders/rowRect.generated.js +0 -1
- package/esm/shaders/rowTable.generated.d.ts +1 -0
- package/esm/shaders/rowTable.generated.js +3 -0
- package/esm/shaders/rowTable.js.generated.d.ts +5 -0
- package/esm/shaders/rowTable.js.generated.js +29 -0
- package/esm/shaders/scoreScale.generated.d.ts +2 -0
- package/esm/shaders/scoreScale.generated.js +4 -0
- package/esm/shaders/scoreScale.js.generated.d.ts +1 -0
- package/esm/shaders/scoreScale.js.generated.js +50 -23
- package/esm/shaders/spanMark.generated.d.ts +3 -0
- package/esm/shaders/spanMark.generated.js +7 -0
- package/esm/shaders/spanMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/spanMark.glsl.generated.js +4 -0
- package/esm/shaders/spanMark.iface.generated.d.ts +81 -0
- package/esm/shaders/spanMark.iface.generated.js +215 -0
- package/esm/shaders/spanMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/spanMark.wgsl.generated.js +3 -0
- package/esm/sharedBackendKey.d.ts +18 -0
- package/esm/{keyedRenderingBackend.js → sharedBackendKey.js} +5 -0
- package/esm/slangPass.d.ts +18 -11
- package/esm/slangPass.js +12 -4
- package/esm/useGraphicsCapabilities.d.ts +1 -1
- package/esm/useGraphicsCapabilities.js +1 -1
- package/esm/useRenderingBackend.d.ts +13 -13
- package/esm/useRenderingBackend.js +58 -20
- package/esm/webgpuUtils.d.ts +3 -11
- package/esm/webgpuUtils.js +12 -33
- package/package.json +32 -7
- package/src/shaders/antialias.slang +46 -0
- package/src/shaders/arcHull.test.ts +267 -0
- package/src/shaders/barMark.generated.ts +11 -0
- package/src/shaders/barMark.glsl.generated.ts +6 -0
- package/src/shaders/barMark.iface.generated.ts +285 -0
- package/src/shaders/barMark.slang +167 -0
- package/src/shaders/barMark.wgsl.generated.ts +4 -0
- package/src/shaders/capsule.js.generated.ts +14 -0
- package/src/shaders/capsule.slang +12 -4
- package/src/shaders/clipStrip.generated.ts +6 -0
- package/src/shaders/clipStrip.js.generated.ts +22 -0
- package/src/shaders/clipStrip.slang +34 -0
- package/src/shaders/clipStrip.test.ts +39 -0
- package/src/shaders/colorPack.slang +5 -1
- package/src/shaders/colorRampLut.js.generated.ts +22 -0
- package/src/shaders/colorRampLut.slang +15 -1
- package/src/shaders/coverageBand.slang +64 -32
- package/src/shaders/coverageBar.generated.ts +6 -5
- package/src/shaders/coverageBar.glsl.generated.ts +6 -0
- package/src/shaders/coverageBar.iface.generated.ts +1 -1
- package/src/shaders/coverageBar.slang +10 -10
- package/src/shaders/coverageBar.wgsl.generated.ts +4 -0
- package/src/shaders/coverageClip.generated.ts +11 -0
- package/src/shaders/coverageClip.glsl.generated.ts +6 -0
- package/src/shaders/coverageClip.iface.generated.ts +172 -0
- package/src/shaders/coverageClip.slang +38 -0
- package/src/shaders/coverageClip.wgsl.generated.ts +4 -0
- package/src/shaders/coverageIndicator.generated.ts +6 -5
- package/src/shaders/coverageIndicator.glsl.generated.ts +6 -0
- package/src/shaders/coverageIndicator.iface.generated.ts +1 -1
- package/src/shaders/coverageIndicator.wgsl.generated.ts +4 -0
- package/src/shaders/coverageInterbase.generated.ts +6 -5
- package/src/shaders/coverageInterbase.glsl.generated.ts +6 -0
- package/src/shaders/coverageInterbase.iface.generated.ts +1 -1
- package/src/shaders/coverageInterbase.wgsl.generated.ts +4 -0
- package/src/shaders/coverageMod.generated.ts +6 -5
- package/src/shaders/coverageMod.glsl.generated.ts +6 -0
- package/src/shaders/coverageMod.iface.generated.ts +1 -1
- package/src/shaders/coverageMod.wgsl.generated.ts +4 -0
- package/src/shaders/coverageSnp.generated.ts +6 -5
- package/src/shaders/coverageSnp.glsl.generated.ts +6 -0
- package/src/shaders/coverageSnp.iface.generated.ts +1 -1
- package/src/shaders/coverageSnp.wgsl.generated.ts +4 -0
- package/src/shaders/curveDistance.js.generated.ts +91 -0
- package/src/shaders/curveDistance.slang +265 -0
- package/src/shaders/hpClampFloor.test.ts +87 -0
- package/src/shaders/hpmath.js.generated.ts +6 -2
- package/src/shaders/hpmath.slang +100 -48
- package/src/shaders/insetValueScale.test.ts +67 -0
- package/src/shaders/lineCenterMark.generated.ts +11 -0
- package/src/shaders/lineCenterMark.glsl.generated.ts +6 -0
- package/src/shaders/lineCenterMark.iface.generated.ts +328 -0
- package/src/shaders/lineCenterMark.slang +127 -0
- package/src/shaders/lineCenterMark.wgsl.generated.ts +4 -0
- package/src/shaders/lineCommon.generated.ts +6 -0
- package/src/shaders/lineCommon.slang +102 -0
- package/src/shaders/lineStepMark.generated.ts +11 -0
- package/src/shaders/lineStepMark.glsl.generated.ts +6 -0
- package/src/shaders/lineStepMark.iface.generated.ts +311 -0
- package/src/shaders/lineStepMark.slang +125 -0
- package/src/shaders/lineStepMark.wgsl.generated.ts +4 -0
- package/src/shaders/linkMark.consts.generated.ts +30 -0
- package/src/shaders/linkMark.generated.ts +12 -0
- package/src/shaders/linkMark.glsl.generated.ts +6 -0
- package/src/shaders/linkMark.iface.generated.ts +1954 -0
- package/src/shaders/linkMark.js.generated.ts +167 -0
- package/src/shaders/linkMark.slang +439 -0
- package/src/shaders/linkMark.wgsl.generated.ts +4 -0
- package/src/shaders/markColor.generated.ts +20 -0
- package/src/shaders/markColor.slang +128 -0
- package/src/shaders/pointGlyph.js.generated.ts +20 -0
- package/src/shaders/pointGlyph.slang +23 -7
- package/src/shaders/pointGlyphPad.test.ts +242 -0
- package/src/shaders/pointMark.consts.generated.ts +16 -0
- package/src/shaders/pointMark.generated.ts +12 -0
- package/src/shaders/pointMark.glsl.generated.ts +6 -0
- package/src/shaders/pointMark.iface.generated.ts +304 -0
- package/src/shaders/pointMark.js.generated.ts +99 -0
- package/src/shaders/pointMark.slang +227 -0
- package/src/shaders/pointMark.wgsl.generated.ts +4 -0
- package/src/shaders/rowRect.generated.ts +0 -2
- package/src/shaders/rowRect.slang +39 -58
- package/src/shaders/rowTable.generated.ts +4 -0
- package/src/shaders/rowTable.js.generated.ts +37 -0
- package/src/shaders/rowTable.slang +98 -0
- package/src/shaders/scoreScale.generated.ts +6 -0
- package/src/shaders/scoreScale.js.generated.ts +48 -23
- package/src/shaders/scoreScale.slang +49 -55
- package/src/shaders/sdEllipse.test.ts +211 -0
- package/src/shaders/spanMark.generated.ts +11 -0
- package/src/shaders/spanMark.glsl.generated.ts +6 -0
- package/src/shaders/spanMark.iface.generated.ts +289 -0
- package/src/shaders/spanMark.slang +77 -0
- package/src/shaders/spanMark.wgsl.generated.ts +4 -0
- package/src/shaders/valueScale.slang +26 -0
- package/src/shaders/wideCircleLeg.test.ts +85 -0
- package/esm/globalRenderingBackend.d.ts +0 -90
- package/esm/globalRenderingBackend.js +0 -53
- package/esm/keyedRenderingBackend.d.ts +0 -41
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
// AUTO-GENERATED by packages/shader-tools/src/shader-codegen from linkMark.slang.
|
|
2
|
+
// Do not edit. Run `pnpm gen:shaders` to regenerate.
|
|
3
|
+
|
|
4
|
+
// Scalar twins of linkMark.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
|
+
function log1pf(x: number): number {
|
|
20
|
+
let u = (1.0 + x)
|
|
21
|
+
let _t0: number
|
|
22
|
+
if ((u == 1.0)) {
|
|
23
|
+
_t0 = x
|
|
24
|
+
} else {
|
|
25
|
+
_t0 = (Math.log(u) * (x / (u - 1.0)))
|
|
26
|
+
}
|
|
27
|
+
return _t0
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function symlogTransform(x: number, c: number): number {
|
|
31
|
+
return ((((Math.sign(x)) | 0)) * log1pf(Math.abs((x / c))))
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function normalizeScoreUnclamped(score: number, domainMin: number, domainMax: number, scaleType: number, symlogConstant: number): number {
|
|
35
|
+
let tMax: number
|
|
36
|
+
let tMin: number
|
|
37
|
+
let t: number
|
|
38
|
+
if ((scaleType == 2)) {
|
|
39
|
+
let _t0 = symlogTransform(score, symlogConstant)
|
|
40
|
+
let _t1 = symlogTransform(domainMin, symlogConstant)
|
|
41
|
+
tMax = symlogTransform(domainMax, symlogConstant)
|
|
42
|
+
tMin = _t1
|
|
43
|
+
t = _t0
|
|
44
|
+
} else {
|
|
45
|
+
if ((scaleType == 1)) {
|
|
46
|
+
if ((domainMin > 0.0)) {
|
|
47
|
+
tMax = domainMin
|
|
48
|
+
} else {
|
|
49
|
+
tMax = 1.0
|
|
50
|
+
}
|
|
51
|
+
let _t2 = Math.log2(_max(score, tMax))
|
|
52
|
+
let _t3 = Math.log2(tMax)
|
|
53
|
+
tMax = Math.log2(_max(domainMax, tMax))
|
|
54
|
+
tMin = _t3
|
|
55
|
+
t = _t2
|
|
56
|
+
} else {
|
|
57
|
+
tMax = domainMax
|
|
58
|
+
tMin = domainMin
|
|
59
|
+
t = score
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
let tRange = (tMax - tMin)
|
|
63
|
+
if ((tRange <= 0.0)) {
|
|
64
|
+
if ((t > tMin)) {
|
|
65
|
+
tMax = 1.0
|
|
66
|
+
} else {
|
|
67
|
+
tMax = 0.0
|
|
68
|
+
}
|
|
69
|
+
return tMax
|
|
70
|
+
}
|
|
71
|
+
return ((t - tMin) / tRange)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function normalizeScore(score: number, domainMin: number, domainMax: number, scaleType: number, symlogConstant: number): number {
|
|
75
|
+
return _clamp(normalizeScoreUnclamped(score, domainMin, domainMax, scaleType, symlogConstant), 0.0, 1.0)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function linkStrokeWidthPx(raw: number, sizeMode: number, constantPx: number, domainMin: number, domainMax: number, scaleType: number, rangeMin: number, rangeMax: number, dpr: number): number {
|
|
79
|
+
let w: number
|
|
80
|
+
if ((sizeMode == 1)) {
|
|
81
|
+
if ((raw > -1.00000001504746622e+29)) {
|
|
82
|
+
w = (rangeMin + (normalizeScore(raw, domainMin, domainMax, scaleType, 1.0) * (rangeMax - rangeMin)))
|
|
83
|
+
} else {
|
|
84
|
+
w = rangeMin
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
w = constantPx
|
|
88
|
+
}
|
|
89
|
+
return _max(w, (1.5 / dpr))
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function rowBandTopPx(rowOffsetPx: number, rowHeight: number, slot: number): number {
|
|
93
|
+
return (rowOffsetPx + (rowHeight * (slot)))
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function linkBaseYPx(rowOffsetPx: number, rowHeight: number, row: number, reverse: number): number {
|
|
97
|
+
let _t0 = rowBandTopPx(rowOffsetPx, rowHeight, row)
|
|
98
|
+
let _t1: number
|
|
99
|
+
if ((reverse != 0)) {
|
|
100
|
+
_t1 = 0.0
|
|
101
|
+
} else {
|
|
102
|
+
_t1 = rowHeight
|
|
103
|
+
}
|
|
104
|
+
return (_t0 + _t1)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function valueToYPxScaled(value: number, domainMin: number, domainMax: number, h: number, scaleType: number, symlogConstant: number): number {
|
|
108
|
+
return ((1.0 - normalizeScore(value, domainMin, domainMax, scaleType, symlogConstant)) * h)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function insetValueYPx(value: number, domainMin: number, domainMax: number, h: number, scaleType: number, insetPx: number, symlogConstant: number): number {
|
|
112
|
+
let _t0 = _min(insetPx, (h * 0.5))
|
|
113
|
+
return (_t0 + valueToYPxScaled(value, domainMin, domainMax, (h - (2.0 * _t0)), scaleType, symlogConstant))
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function linkValuePx(value: number, domainMin: number, domainMax: number, h: number, scaleType: number, insetPx: number, symlogConstant: number): number {
|
|
117
|
+
return (h - insetValueYPx(value, domainMin, domainMax, h, scaleType, insetPx, symlogConstant))
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function linkApexPx(halfWidthPx: number, reachPx: number, linkShape: number, valued: number, valuePx: number): number {
|
|
121
|
+
if ((valued != 0)) {
|
|
122
|
+
return valuePx
|
|
123
|
+
}
|
|
124
|
+
if ((linkShape == 2)) {
|
|
125
|
+
return 0.0
|
|
126
|
+
}
|
|
127
|
+
if ((linkShape == 1)) {
|
|
128
|
+
return halfWidthPx
|
|
129
|
+
}
|
|
130
|
+
return _min(halfWidthPx, reachPx)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function linkIsFar(halfWidthPx: number, screenWidthPx: number): boolean {
|
|
134
|
+
return ((2.0 * halfWidthPx) > (3.0 * screenWidthPx))
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function linkRadiiPx(halfWidthPx: number, apexPx: number, screenWidthPx: number): [number, number] {
|
|
138
|
+
if (linkIsFar(halfWidthPx, screenWidthPx)) {
|
|
139
|
+
return [halfWidthPx, halfWidthPx]
|
|
140
|
+
}
|
|
141
|
+
return [halfWidthPx, apexPx]
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function linkFootDir(feet: number, shift: number): number {
|
|
145
|
+
let d = (((feet >>> shift) & 3) >>> 0)
|
|
146
|
+
let _t0: number
|
|
147
|
+
if ((d == 1)) {
|
|
148
|
+
_t0 = 1.0
|
|
149
|
+
} else {
|
|
150
|
+
if ((d == 2)) {
|
|
151
|
+
_t0 = -1.0
|
|
152
|
+
} else {
|
|
153
|
+
_t0 = 0.0
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return _t0
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function linkFootLenPx(x: number, dir: number, leftPx: number, rightPx: number, footPx: number): number {
|
|
160
|
+
let _t0: number
|
|
161
|
+
if ((dir > 0.0)) {
|
|
162
|
+
_t0 = (rightPx - x)
|
|
163
|
+
} else {
|
|
164
|
+
_t0 = (x - leftPx)
|
|
165
|
+
}
|
|
166
|
+
return _max(0.0, _min(footPx, _t0))
|
|
167
|
+
}
|
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
// The `link` mark shape: one instance is a stroked curve between two genomic
|
|
2
|
+
// positions — `x` on the displayed region whose payload holds the instance and
|
|
3
|
+
// `x2` on whichever displayed region the instance names, the same one,
|
|
4
|
+
// another, or none. The mark draws over the whole canvas rather than inside a
|
|
5
|
+
// block's column, so a curve crosses regions holding neither foot. Both feet
|
|
6
|
+
// place through a uniform table of the view's displayed regions, so a pan or
|
|
7
|
+
// zoom writes the table and no buffer.
|
|
8
|
+
//
|
|
9
|
+
// The curve is a half-ellipse whose hull is a triangle strip inflated by the
|
|
10
|
+
// half stroke plus one antialiasing ramp, and a fragment that measures the
|
|
11
|
+
// true distance to the analytic curve, so the hull's facets never reach the
|
|
12
|
+
// picture. A pair wider than LINK_FAR_SCREEN_WIDTHS view widths degenerates to
|
|
13
|
+
// a circle whose legs rise from each real foot, built endpoint-relative so a
|
|
14
|
+
// radius in the millions of px cancels nothing. A foot the table cannot place
|
|
15
|
+
// draws a stem at the placed one, so an off-view mate still says it exists. A
|
|
16
|
+
// foot may carry a breakend tick along the baseline, pointing along the arm
|
|
17
|
+
// its junction keeps. Under `line` the pair is a straight segment at the apex
|
|
18
|
+
// height instead, GenomeSpy's fourth link shape.
|
|
19
|
+
//
|
|
20
|
+
// The apex is a value on the display's y scale where the mark names one, else
|
|
21
|
+
// the pair's own half-width, clamped to the band under `dome` and left to
|
|
22
|
+
// leave it under `arc`. A reversed scale puts the baseline at the band's top
|
|
23
|
+
// and the curve below it.
|
|
24
|
+
//! targets: wgsl, glsl
|
|
25
|
+
//! topology: triangle-strip
|
|
26
|
+
//! coverage: analytic
|
|
27
|
+
//! export-consts: LINK_SHAPE_DOME, LINK_SHAPE_ARC, LINK_SHAPE_LINE, LINK_LINE_MIN_PX, LINK_NO_REGION, LINK_ELSEWHERE, LINK_MAX_REGIONS, LINK_STEM_PX, LINK_FOOT_PX, LINK_FAR_SCREEN_WIDTHS, LINK_SIZE_CONSTANT, LINK_SIZE_SCALED, LINK_NO_SIZE, LINK_CURVE_SEGMENTS
|
|
28
|
+
//! js-export: linkApexPx, linkRadiiPx, linkStrokeWidthPx, linkValuePx, linkBaseYPx, linkFootLenPx, linkFootDir
|
|
29
|
+
//! js-skip: linkIsFar — reached as a private helper inside the generated linkRadiiPx, so the far decision is shared without a second way to ask it
|
|
30
|
+
|
|
31
|
+
import antialias;
|
|
32
|
+
import colorPack;
|
|
33
|
+
import curveDistance;
|
|
34
|
+
import hpmath;
|
|
35
|
+
import markColor;
|
|
36
|
+
import rowTable;
|
|
37
|
+
import scoreScale;
|
|
38
|
+
import valueScale;
|
|
39
|
+
|
|
40
|
+
public static const uint LINK_CURVE_SEGMENTS = 64u;
|
|
41
|
+
static const uint CURVE_VERTS = (LINK_CURVE_SEGMENTS + 1u) * 2u;
|
|
42
|
+
// Each foot's block of the strip: the join's repeated vertex, then its quad
|
|
43
|
+
// with the first corner doubled, so both joins are degenerate triangles.
|
|
44
|
+
static const uint FOOT_VERTS = 6u;
|
|
45
|
+
public static const uint VERTS_PER_INSTANCE = CURVE_VERTS + 2u * FOOT_VERTS;
|
|
46
|
+
static const float PI = 3.14159265359;
|
|
47
|
+
|
|
48
|
+
public static const int LINK_SHAPE_DOME = 0;
|
|
49
|
+
public static const int LINK_SHAPE_ARC = 1;
|
|
50
|
+
public static const int LINK_SHAPE_LINE = 2;
|
|
51
|
+
// The shortest segment a `line` draws, widened about its midpoint, so a pair
|
|
52
|
+
// under a pixel apart still paints.
|
|
53
|
+
public static const float LINK_LINE_MIN_PX = 2.5;
|
|
54
|
+
// An `x2Region` the table has no entry for: the mate lies on no displayed
|
|
55
|
+
// region, so the instance draws its stem.
|
|
56
|
+
public static const uint LINK_NO_REGION = 0xFFFFFFFFu;
|
|
57
|
+
// An `x2Region` for an instance another region's payload draws: the far half
|
|
58
|
+
// of a pair both of whose ends have records, or a record fetched twice.
|
|
59
|
+
public static const uint LINK_ELSEWHERE = 0xFFFFFFFEu;
|
|
60
|
+
public static const uint LINK_MAX_REGIONS = 256u;
|
|
61
|
+
public static const float LINK_STEM_PX = 12.0;
|
|
62
|
+
// How long a breakend foot is where its region has the room: a tick along
|
|
63
|
+
// the baseline over the arm its junction keeps, BreakpointSplitView's length.
|
|
64
|
+
public static const float LINK_FOOT_PX = 20.0;
|
|
65
|
+
// How many view widths a pair may span before its ellipse becomes a true
|
|
66
|
+
// circle, which the band clips down to near-vertical legs at each real foot.
|
|
67
|
+
// Not 1, because a circle throws the pair's direction away, and the limit is
|
|
68
|
+
// tessellation: reference/ARC_BAND.md.
|
|
69
|
+
public static const float LINK_FAR_SCREEN_WIDTHS = 3.0;
|
|
70
|
+
public static const int LINK_SIZE_CONSTANT = 0;
|
|
71
|
+
public static const int LINK_SIZE_SCALED = 1;
|
|
72
|
+
// The `size` lane's value for an instance holding no number, which takes the
|
|
73
|
+
// range's first px. A sentinel rather than NaN, which a vertex attribute may
|
|
74
|
+
// not carry through every driver's fast math.
|
|
75
|
+
public static const float LINK_NO_SIZE = -1.0e30;
|
|
76
|
+
|
|
77
|
+
static const float KIND_ELLIPSE = 0.0;
|
|
78
|
+
static const float KIND_CIRCLE = 1.0;
|
|
79
|
+
static const float KIND_STEM = 2.0;
|
|
80
|
+
static const float KIND_LINE = 3.0;
|
|
81
|
+
static const float KIND_FOOT = 4.0;
|
|
82
|
+
|
|
83
|
+
struct LinkInstance {
|
|
84
|
+
uint x : ATTR0;
|
|
85
|
+
uint x2 : ATTR1;
|
|
86
|
+
uint x2Region : ATTR2;
|
|
87
|
+
float y : ATTR3;
|
|
88
|
+
float size : ATTR4;
|
|
89
|
+
uint color : ATTR5;
|
|
90
|
+
uint row : ATTR6;
|
|
91
|
+
uint feet : ATTR7;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
struct Uniforms {
|
|
95
|
+
float canvasHeight;
|
|
96
|
+
float devicePixelRatio;
|
|
97
|
+
float rowHeight;
|
|
98
|
+
float rowOffsetPx;
|
|
99
|
+
int reverse;
|
|
100
|
+
float stemPx;
|
|
101
|
+
float dashPx;
|
|
102
|
+
float gapPx;
|
|
103
|
+
float footPx;
|
|
104
|
+
// The segments the curve's strip takes this draw: LINK_CURVE_SEGMENTS, or
|
|
105
|
+
// one for a straight `line`, so a read cloud's bars shade 16 vertices each.
|
|
106
|
+
uint curveSegments;
|
|
107
|
+
float insetPx;
|
|
108
|
+
float domainMin;
|
|
109
|
+
float domainMax;
|
|
110
|
+
int valueScaleType;
|
|
111
|
+
float valueSymlogConstant;
|
|
112
|
+
int rampMode;
|
|
113
|
+
float rampMin;
|
|
114
|
+
float rampMax;
|
|
115
|
+
float rampMidNorm;
|
|
116
|
+
// `markColor`'s threshold: how many cuts are in use, the cuts four to a
|
|
117
|
+
// vector, and the colour of each interval between them.
|
|
118
|
+
int colorCutCount;
|
|
119
|
+
float4 colorCuts[2];
|
|
120
|
+
float4 colorBands[MAX_COLOR_BANDS];
|
|
121
|
+
// Whether the mark names a `y`: the apex is then the value's height.
|
|
122
|
+
int valued;
|
|
123
|
+
int linkShape;
|
|
124
|
+
int sizeMode;
|
|
125
|
+
float sizeConstantPx;
|
|
126
|
+
float sizeDomainMin;
|
|
127
|
+
float sizeDomainMax;
|
|
128
|
+
int sizeScaleType;
|
|
129
|
+
float sizeRangeMin;
|
|
130
|
+
float sizeRangeMax;
|
|
131
|
+
float canvasWidth;
|
|
132
|
+
uint regionCount;
|
|
133
|
+
float zero;
|
|
134
|
+
// The table entry of the region whose payload is drawing, which every
|
|
135
|
+
// instance's `x` is on; carried apart from the table so a region past its
|
|
136
|
+
// end places.
|
|
137
|
+
float4 ownEntry;
|
|
138
|
+
// The own region's screen extent, (leftPx, rightPx), which bounds its foot.
|
|
139
|
+
float4 ownSpan;
|
|
140
|
+
// One entry per displayed region: (anchorPx, anchorBpHi, anchorBpLo,
|
|
141
|
+
// signedPxPerBp), the anchor a bp of the region near the view so a foot's
|
|
142
|
+
// offset from it stays inside float32.
|
|
143
|
+
float4 regionTable[LINK_MAX_REGIONS];
|
|
144
|
+
// Each region's screen extent, two to an element: (left, right) of region
|
|
145
|
+
// 2i in xy and of region 2i + 1 in zw.
|
|
146
|
+
float4 regionSpan[LINK_MAX_REGIONS / 2u];
|
|
147
|
+
// The keys the bound row table holds, −1 where `row` is the band itself.
|
|
148
|
+
int rowTableKeys;
|
|
149
|
+
};
|
|
150
|
+
[[vk::binding(1, 0)]] ConstantBuffer<Uniforms> u;
|
|
151
|
+
[[vk::binding(2, 0)]] Sampler2D<float4> colorRamp;
|
|
152
|
+
[[vk::binding(4, 0)]] Sampler2D<float4> rowTable;
|
|
153
|
+
|
|
154
|
+
struct VsOut {
|
|
155
|
+
float4 position : SV_Position;
|
|
156
|
+
float4 color : COLOR0;
|
|
157
|
+
// Fragment position in the frame its curve is measured in, y negative away
|
|
158
|
+
// from the baseline: the ellipse's centre, a far circle's leg foot, a
|
|
159
|
+
// stem's foot, or a line's left end; along and across a breakend foot.
|
|
160
|
+
float2 local : COLOR1;
|
|
161
|
+
nointerpolation float2 radii : COLOR2;
|
|
162
|
+
nointerpolation float kind : COLOR3;
|
|
163
|
+
// The resolved half stroke width, carried so the hull the vertex stage
|
|
164
|
+
// inflated and the ink the fragment measures are one width.
|
|
165
|
+
nointerpolation float halfWidthPx : COLOR4;
|
|
166
|
+
// Which leg of a far circle a vertex belongs to, ±1, and +1 throughout for
|
|
167
|
+
// one connected curve. The strip has no break in it, so the quad between
|
|
168
|
+
// the two legs' tips rasterizes; both tips carry the same `local`, so its
|
|
169
|
+
// distance comes out ~0 and it inks a bar. The fragment discards where this
|
|
170
|
+
// ramps between the legs.
|
|
171
|
+
float legSide : COLOR5;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
float entryPx(uint bp, float4 r, float hpZero) {
|
|
175
|
+
return r.x - hpViewportOffsetBp(hpSplitUint(bp), float3(r.y, r.z, 0.0), hpZero) * r.w;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
bool linkIsFar(float halfWidthPx, float screenWidthPx) {
|
|
179
|
+
return 2.0 * halfWidthPx > LINK_FAR_SCREEN_WIDTHS * screenWidthPx;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// The height above the baseline a mark's `y` value stands at: `valueScale`'s
|
|
183
|
+
// inset range, anchored at the band's bottom rather than a point's top.
|
|
184
|
+
public float linkValuePx(float value, float domainMin, float domainMax, float h, int scaleType, float insetPx, float symlogConstant) {
|
|
185
|
+
return h - insetValueYPx(value, domainMin, domainMax, h, scaleType, insetPx, symlogConstant);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// The apex height of a pair, in CSS px above the baseline.
|
|
189
|
+
public float linkApexPx(float halfWidthPx, float reachPx, int linkShape, int valued, float valuePx) {
|
|
190
|
+
if (valued != 0) { return valuePx; }
|
|
191
|
+
if (linkShape == LINK_SHAPE_LINE) { return 0.0; }
|
|
192
|
+
if (linkShape == LINK_SHAPE_ARC) { return halfWidthPx; }
|
|
193
|
+
return min(halfWidthPx, reachPx);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// The baseline of a row's band, in canvas px: its bottom, or its top under a
|
|
197
|
+
// reversed scale.
|
|
198
|
+
public float linkBaseYPx(float rowOffsetPx, float rowHeight, uint row, int reverse) {
|
|
199
|
+
return rowBandTopPx(rowOffsetPx, rowHeight, row) + (reverse != 0 ? 0.0 : rowHeight);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// The two radii of the half-ellipse a pair draws, or a true circle's once the
|
|
203
|
+
// pair is far. `//! js-export`ed as a pair because the decision IS the pair,
|
|
204
|
+
// and it is what the painter, the ink and the hit test read.
|
|
205
|
+
public float2 linkRadiiPx(float halfWidthPx, float apexPx, float screenWidthPx) {
|
|
206
|
+
if (linkIsFar(halfWidthPx, screenWidthPx)) {
|
|
207
|
+
return float2(halfWidthPx, halfWidthPx);
|
|
208
|
+
}
|
|
209
|
+
return float2(halfWidthPx, apexPx);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// An instance's stroke width: the constant, or its raw `size` value through
|
|
213
|
+
// the size scale into the px range, floored at 1.5 device px so the single
|
|
214
|
+
// antialiasing ramp always has room (arc-antialiasing-without-msaa.md).
|
|
215
|
+
public float linkStrokeWidthPx(float raw, int sizeMode, float constantPx, float domainMin, float domainMax, int scaleType, float rangeMin, float rangeMax, float dpr) {
|
|
216
|
+
float w = constantPx;
|
|
217
|
+
if (sizeMode == LINK_SIZE_SCALED) {
|
|
218
|
+
w = raw > -1.0e29
|
|
219
|
+
? rangeMin + normalizeScore(raw, domainMin, domainMax, scaleType, 1.0) * (rangeMax - rangeMin)
|
|
220
|
+
: rangeMin;
|
|
221
|
+
}
|
|
222
|
+
return max(w, 1.5 / dpr);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// A foot's genomic direction off the `feet` lane: two bits per foot, 1 for
|
|
226
|
+
// forward and 2 for reverse, the `x` foot in the low pair.
|
|
227
|
+
public float linkFootDir(uint feet, uint shift) {
|
|
228
|
+
uint d = (feet >> shift) & 3u;
|
|
229
|
+
return d == 1u ? 1.0 : (d == 2u ? -1.0 : 0.0);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
float2 regionSpanPx(uint region) {
|
|
233
|
+
float4 s = u.regionSpan[region / 2u];
|
|
234
|
+
return (region % 2u) == 0u ? s.xy : s.zw;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// How far a foot at `x` runs in screen direction `dir`, up to `footPx` and
|
|
238
|
+
// no further than its own region's edge, so it stops at a seam.
|
|
239
|
+
public float linkFootLenPx(float x, float dir, float leftPx, float rightPx, float footPx) {
|
|
240
|
+
return max(0.0, min(footPx, dir > 0.0 ? rightPx - x : x - leftPx));
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// What every vertex of one instance shares.
|
|
244
|
+
struct LinkEnv {
|
|
245
|
+
float strokeHalf;
|
|
246
|
+
float hw;
|
|
247
|
+
float baseY;
|
|
248
|
+
float ySign;
|
|
249
|
+
float reach;
|
|
250
|
+
float xPx;
|
|
251
|
+
float x2Px;
|
|
252
|
+
bool placed;
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
struct LinkVertex {
|
|
256
|
+
float2 screen;
|
|
257
|
+
float2 local;
|
|
258
|
+
float2 radii;
|
|
259
|
+
float kind;
|
|
260
|
+
float legSide;
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
LinkVertex curveVertex(LinkInstance inst, LinkEnv e, uint seg, float side) {
|
|
264
|
+
float t = float(seg) / float(u.curveSegments);
|
|
265
|
+
// Positive on the outer flank; the frame's y is negative upward.
|
|
266
|
+
float pad = side * e.hw;
|
|
267
|
+
float2 origin;
|
|
268
|
+
float legDir = 1.0;
|
|
269
|
+
LinkVertex v;
|
|
270
|
+
v.legSide = 1.0;
|
|
271
|
+
if (!e.placed) {
|
|
272
|
+
v.kind = KIND_STEM;
|
|
273
|
+
v.radii = float2(0.0, u.stemPx);
|
|
274
|
+
// The stem's tip is a round cap, so the quad runs one pad past it. Its foot
|
|
275
|
+
// stops at the baseline, where every dome's feet stop.
|
|
276
|
+
v.local = float2(pad, -t * (u.stemPx + e.hw));
|
|
277
|
+
origin = float2(e.xPx, e.baseY);
|
|
278
|
+
} else {
|
|
279
|
+
float pairHalf = abs(e.x2Px - e.xPx) * 0.5;
|
|
280
|
+
float valuePx = linkValuePx(inst.y, u.domainMin, u.domainMax, u.rowHeight,
|
|
281
|
+
u.valueScaleType, u.insetPx, u.valueSymlogConstant);
|
|
282
|
+
float apex = linkApexPx(pairHalf, e.reach, u.linkShape, u.valued, valuePx);
|
|
283
|
+
v.radii = linkRadiiPx(pairHalf, apex, u.canvasWidth);
|
|
284
|
+
float2 ends = float2(min(e.xPx, e.x2Px), max(e.xPx, e.x2Px));
|
|
285
|
+
if (u.linkShape == LINK_SHAPE_LINE) {
|
|
286
|
+
v.kind = KIND_LINE;
|
|
287
|
+
float len = max(2.0 * pairHalf, LINK_LINE_MIN_PX);
|
|
288
|
+
v.radii = float2(len, 0.0);
|
|
289
|
+
v.local = float2(t * len, pad);
|
|
290
|
+
origin = float2((e.xPx + e.x2Px) * 0.5 - len * 0.5, e.baseY - apex * e.ySign);
|
|
291
|
+
} else if (linkIsFar(pairHalf, u.canvasWidth)) {
|
|
292
|
+
v.kind = KIND_CIRCLE;
|
|
293
|
+
float legSweep = legSweepAngle(v.radii.x, e.reach + e.hw);
|
|
294
|
+
// Two legs, each built from ITS OWN foot outward with the half-angle
|
|
295
|
+
// identity, so a radius past 1e6 px cancels nothing.
|
|
296
|
+
float2 leg = wideCircleLeg(seg, u.curveSegments, legSweep);
|
|
297
|
+
float b = leg.y;
|
|
298
|
+
float halfStep =
|
|
299
|
+
0.5 * wideCircleLegStep(seg, u.curveSegments, legSweep);
|
|
300
|
+
v.local = wideCircleHullPoint(sin(b), sin(b * 0.5), cos(halfStep),
|
|
301
|
+
v.radii.x, pad);
|
|
302
|
+
v.local.y = -v.local.y;
|
|
303
|
+
origin = float2(leg.x > 0.0 ? ends.y : ends.x, e.baseY);
|
|
304
|
+
legDir = leg.x;
|
|
305
|
+
v.legSide = legDir;
|
|
306
|
+
} else {
|
|
307
|
+
v.kind = KIND_ELLIPSE;
|
|
308
|
+
float a = t * PI;
|
|
309
|
+
float halfStep = PI / (2.0 * float(u.curveSegments));
|
|
310
|
+
v.local = ellipseHullPoint(cos(a), sin(a), cos(halfStep), sin(halfStep),
|
|
311
|
+
v.radii.x, v.radii.y, pad);
|
|
312
|
+
v.local.y = -v.local.y;
|
|
313
|
+
origin = float2((e.xPx + e.x2Px) * 0.5, e.baseY);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
v.screen = origin + float2(legDir * v.local.x, v.local.y * e.ySign);
|
|
317
|
+
return v;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Corner `c` (0-3, strip order) of foot `f`'s quad, or undefined where the
|
|
321
|
+
// foot draws nothing, reported through `present`.
|
|
322
|
+
LinkVertex footCorner(LinkInstance inst, LinkEnv e, uint f, uint c, out bool present) {
|
|
323
|
+
float x = f == 0u ? e.xPx : e.x2Px;
|
|
324
|
+
uint far = min(inst.x2Region, LINK_MAX_REGIONS - 1u);
|
|
325
|
+
float4 entry = f == 0u ? u.ownEntry : u.regionTable[far];
|
|
326
|
+
float2 span = f == 0u ? u.ownSpan.xy : regionSpanPx(far);
|
|
327
|
+
float dir = linkFootDir(inst.feet, f * 2u) * sign(entry.w);
|
|
328
|
+
float len = linkFootLenPx(x, dir, span.x, span.y, u.footPx);
|
|
329
|
+
present = dir != 0.0 && len > 0.0 && (f == 0u || e.placed);
|
|
330
|
+
float along = (c >= 2u) ? len : 0.0;
|
|
331
|
+
float across = (c % 2u == 0u) ? -e.hw : e.hw;
|
|
332
|
+
LinkVertex v;
|
|
333
|
+
v.kind = KIND_FOOT;
|
|
334
|
+
v.radii = float2(len, 0.0);
|
|
335
|
+
v.legSide = 1.0;
|
|
336
|
+
v.local = float2(along, across);
|
|
337
|
+
v.screen = float2(x + dir * along, e.baseY - e.ySign * e.strokeHalf + across);
|
|
338
|
+
return v;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// The vertex a foot's block of the strip starts from: the one before it, so
|
|
342
|
+
// the join is two degenerate triangles.
|
|
343
|
+
LinkVertex footBlockStart(LinkInstance inst, LinkEnv e, uint f) {
|
|
344
|
+
LinkVertex tail = curveVertex(inst, e, u.curveSegments, 1.0);
|
|
345
|
+
if (f == 0u) { return tail; }
|
|
346
|
+
bool first;
|
|
347
|
+
LinkVertex last = footCorner(inst, e, 0u, 3u, first);
|
|
348
|
+
return first ? last : tail;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Vertex `k` of foot `f`'s six: the block's start repeated, then the quad
|
|
352
|
+
// with its first corner doubled. A foot that draws nothing repeats the start.
|
|
353
|
+
LinkVertex footVertex(LinkInstance inst, LinkEnv e, uint f, uint k) {
|
|
354
|
+
LinkVertex start = footBlockStart(inst, e, f);
|
|
355
|
+
if (k == 0u) { return start; }
|
|
356
|
+
bool present;
|
|
357
|
+
LinkVertex v = footCorner(inst, e, f, k <= 2u ? 0u : k - 2u, present);
|
|
358
|
+
return present ? v : start;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
[shader("vertex")]
|
|
362
|
+
VsOut vs_main(LinkInstance inst, uint vid : SV_VertexID) {
|
|
363
|
+
RowPlacement place = rowTableLookup(rowTable, inst.row, u.rowTableKeys,
|
|
364
|
+
markScaleColor(colorRamp, inst.color, u.rampMode, u.rampMin, u.rampMax, u.rampMidNorm, u.colorCutCount, u.colorCuts[0], u.colorCuts[1], u.colorBands));
|
|
365
|
+
LinkEnv e;
|
|
366
|
+
e.strokeHalf = 0.5 * linkStrokeWidthPx(
|
|
367
|
+
inst.size, u.sizeMode, u.sizeConstantPx, u.sizeDomainMin, u.sizeDomainMax,
|
|
368
|
+
u.sizeScaleType, u.sizeRangeMin, u.sizeRangeMax, u.devicePixelRatio);
|
|
369
|
+
e.hw = e.strokeHalf + aaHalfPx(u.devicePixelRatio);
|
|
370
|
+
e.baseY = linkBaseYPx(u.rowOffsetPx, u.rowHeight, place.slot, u.reverse);
|
|
371
|
+
e.ySign = u.reverse != 0 ? -1.0 : 1.0;
|
|
372
|
+
e.reach = max(u.rowHeight - u.insetPx, 0.0);
|
|
373
|
+
e.xPx = entryPx(inst.x, u.ownEntry, u.zero);
|
|
374
|
+
e.placed = inst.x2Region < u.regionCount;
|
|
375
|
+
e.x2Px = e.placed ? entryPx(inst.x2, u.regionTable[inst.x2Region], u.zero) : e.xPx;
|
|
376
|
+
|
|
377
|
+
uint curveVerts = (u.curveSegments + 1u) * 2u;
|
|
378
|
+
LinkVertex v;
|
|
379
|
+
if (vid < curveVerts) {
|
|
380
|
+
v = curveVertex(inst, e, vid / 2u, (vid % 2u == 0u) ? -1.0 : 1.0);
|
|
381
|
+
} else {
|
|
382
|
+
uint j = vid - curveVerts;
|
|
383
|
+
v = footVertex(inst, e, j / FOOT_VERTS, j % FOOT_VERTS);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
VsOut o;
|
|
387
|
+
o.position = inst.x2Region == LINK_ELSEWHERE || place.hidden
|
|
388
|
+
? float4(-2.0, -2.0, 0.0, 1.0)
|
|
389
|
+
: float4(
|
|
390
|
+
v.screen.x / u.canvasWidth * 2.0 - 1.0,
|
|
391
|
+
yPxToClipY(v.screen.y, u.canvasHeight),
|
|
392
|
+
0.0, 1.0);
|
|
393
|
+
o.color = place.color;
|
|
394
|
+
o.local = v.local;
|
|
395
|
+
o.radii = v.radii;
|
|
396
|
+
o.kind = v.kind;
|
|
397
|
+
o.halfWidthPx = e.strokeHalf;
|
|
398
|
+
o.legSide = v.legSide;
|
|
399
|
+
return o;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Perpendicular distance in CSS px from this fragment to its analytic curve.
|
|
403
|
+
float linkDistance(VsOut i) {
|
|
404
|
+
if (i.kind >= 2.5) {
|
|
405
|
+
float x = clamp(i.local.x, 0.0, i.radii.x);
|
|
406
|
+
return length(float2(i.local.x - x, i.local.y));
|
|
407
|
+
}
|
|
408
|
+
if (i.kind >= 1.5) {
|
|
409
|
+
float y = clamp(i.local.y, -i.radii.y, 0.0);
|
|
410
|
+
return length(float2(i.local.x, i.local.y - y));
|
|
411
|
+
}
|
|
412
|
+
if (i.kind >= 0.5) { return distToWideCircle(i.local, i.radii.x); }
|
|
413
|
+
return sdEllipse(i.local, i.radii);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// How far along a straight segment's axis the fragment is, from the end the
|
|
417
|
+
// dash pattern starts at; a curve carries no dash.
|
|
418
|
+
float linkDashAlong(VsOut i) {
|
|
419
|
+
if (i.kind >= 3.5) { return -1.0; }
|
|
420
|
+
if (i.kind >= 2.5) { return i.local.x; }
|
|
421
|
+
if (i.kind >= 1.5) { return -i.local.y; }
|
|
422
|
+
return -1.0;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
float linkDash(VsOut i) {
|
|
426
|
+
float along = linkDashAlong(i);
|
|
427
|
+
return u.dashPx > 0.0 && along >= 0.0
|
|
428
|
+
? dashCoverage(along, u.dashPx, u.gapPx, u.devicePixelRatio)
|
|
429
|
+
: 1.0;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
[shader("fragment")]
|
|
433
|
+
float4 fs_main(VsOut fragIn) : SV_Target {
|
|
434
|
+
if (abs(fragIn.legSide) < 0.999) { discard; }
|
|
435
|
+
// |∇d| is 1 per CSS px, so the ramp is a constant number of device pixels.
|
|
436
|
+
float alpha = edgeCoverage(fragIn.halfWidthPx - linkDistance(fragIn), u.devicePixelRatio)
|
|
437
|
+
* linkDash(fragIn);
|
|
438
|
+
return float4(fragIn.color.rgb, fragIn.color.a * alpha);
|
|
439
|
+
}
|