diff --git a/client/src/components/graph/drawPointsRegl.js b/client/src/components/graph/drawPointsRegl.js index 47c665a3..01ecc99f 100644 --- a/client/src/components/graph/drawPointsRegl.js +++ b/client/src/components/graph/drawPointsRegl.js @@ -14,7 +14,7 @@ export default function drawPointsRegl(regl) { uniform float nPoints; uniform float minViewportDimension; - varying vec4 fragColor; + varying lowp vec4 fragColor; const float zBottom = 0.99; const float zMiddle = 0.; @@ -27,23 +27,23 @@ export default function drawPointsRegl(regl) { ${glPointSize} void main() { - bool isNaN, isSelected, isHighlight; - getFlags(flag, isNaN, isSelected, isHighlight); + bool isBackground, isSelected, isHighlight; + getFlags(flag, isBackground, isSelected, isHighlight); float size = pointSize(nPoints, minViewportDimension, isSelected, isHighlight); gl_PointSize = size * pow(distance, 0.5); - float z = isNaN ? zBottom : (isHighlight ? zTop : zMiddle); + float z = isBackground ? zBottom : (isHighlight ? zTop : zMiddle); vec3 xy = projView * vec3(position, 1.); gl_Position = vec4(xy.xy, z, 1.); - float alpha = isNaN ? 0.9 : 1.0; + float alpha = isBackground ? 0.9 : 1.0; fragColor = vec4(color, alpha); }`, frag: ` precision mediump float; - varying vec4 fragColor; + varying lowp vec4 fragColor; void main() { if (length(gl_PointCoord.xy - 0.5) > 0.5) { discard; @@ -67,5 +67,15 @@ export default function drawPointsRegl(regl) { count: regl.prop("count"), primitive: "points", + + blend: { + enable: true, + func: { + srcRGB: "src alpha", + srcAlpha: 1, + dstRGB: 0, + dstAlpha: "zero", + }, + }, }); } diff --git a/client/src/components/graph/graph.js b/client/src/components/graph/graph.js index 473f8c27..ceaf31c7 100644 --- a/client/src/components/graph/graph.js +++ b/client/src/components/graph/graph.js @@ -22,6 +22,12 @@ import CentroidLabels from "./overlays/centroidLabels"; import actions from "../../actions"; import renderThrottle from "../../util/renderThrottle"; +import { + flagBackground, + flagSelected, + flagHighlight, +} from "../../util/glHelpers"; + /* Simple 2D transforms control all point painting. There are three: * model - convert from underlying per-point coordinate to a layout. @@ -62,10 +68,6 @@ function createModelTF() { return m; } -const flagSelected = 1; -const flagNaN = 2; -const flagHighlight = 4; - @connect((state) => ({ annoMatrix: state.annoMatrix, crossfilter: state.obsCrossfilter, @@ -159,8 +161,9 @@ class Graph extends React.Component { const flags = new Float32Array(nObs); if (colorByData) { for (let i = 0, len = flags.length; i < len; i += 1) { - if (!Number.isFinite(colorByData[i])) { - flags[i] = flagNaN; + const val = colorByData[i]; + if (typeof val === "number" && !Number.isFinite(val)) { + flags[i] = flagBackground; } } } diff --git a/client/src/components/scatterplot/drawPointsRegl.js b/client/src/components/scatterplot/drawPointsRegl.js index 4f70e9ed..38dfdbd2 100644 --- a/client/src/components/scatterplot/drawPointsRegl.js +++ b/client/src/components/scatterplot/drawPointsRegl.js @@ -13,7 +13,7 @@ export default function drawPointsRegl(regl) { uniform float nPoints; uniform float minViewportDimension; - varying vec4 fragColor; + varying lowp vec4 fragColor; const float zBottom = 0.99; const float zMiddle = 0.; @@ -26,22 +26,22 @@ export default function drawPointsRegl(regl) { ${glPointSize} void main() { - bool isNaN, isSelected, isHighlight; - getFlags(flag, isNaN, isSelected, isHighlight); + bool isBackground, isSelected, isHighlight; + getFlags(flag, isBackground, isSelected, isHighlight); gl_PointSize = pointSize(nPoints, minViewportDimension, isSelected, isHighlight); - float z = isNaN ? zBottom : (isHighlight ? zTop : zMiddle); + float z = isBackground ? zBottom : (isHighlight ? zTop : zMiddle); vec3 xy = projection * vec3(position, 1.); gl_Position = vec4(xy.xy, z, 1.); - float alpha = isNaN ? 0.9 : 1.0; + float alpha = isBackground ? 0.9 : 1.0; fragColor = vec4(color, alpha); }`, frag: ` precision mediump float; - varying vec4 fragColor; + varying lowp vec4 fragColor; void main() { if (length(gl_PointCoord.xy - 0.5) > 0.5) { discard; @@ -64,5 +64,15 @@ export default function drawPointsRegl(regl) { count: regl.prop("count"), primitive: "points", + + blend: { + enable: true, + func: { + srcRGB: "src alpha", + srcAlpha: 1, + dstRGB: 0, + dstAlpha: "zero", + }, + }, }); } diff --git a/client/src/components/scatterplot/scatterplot.js b/client/src/components/scatterplot/scatterplot.js index fa9aa6cb..d68de428 100644 --- a/client/src/components/scatterplot/scatterplot.js +++ b/client/src/components/scatterplot/scatterplot.js @@ -16,10 +16,11 @@ import { createColorQuery, } from "../../util/stateManager/colorHelpers"; import renderThrottle from "../../util/renderThrottle"; - -const flagSelected = 1; -const flagNaN = 2; -const flagHighlight = 4; +import { + flagBackground, + flagSelected, + flagHighlight, +} from "../../util/glHelpers"; function createProjectionTF(viewportWidth, viewportHeight) { /* @@ -135,8 +136,9 @@ class Scatterplot extends React.PureComponent { const flags = new Float32Array(nObs); if (colorByData) { for (let i = 0, len = flags.length; i < len; i += 1) { - if (!Number.isFinite(colorByData[i])) { - flags[i] = flagNaN; + const val = colorByData[i]; + if (typeof val === "number" && !Number.isFinite(val)) { + flags[i] = flagBackground; } } } diff --git a/client/src/util/glHelpers.js b/client/src/util/glHelpers.js index 21cecc44..96631434 100644 --- a/client/src/util/glHelpers.js +++ b/client/src/util/glHelpers.js @@ -8,18 +8,24 @@ PointFlags: We want a bitmask-like flag structure, but due to webgl limitations must emulate it with floats. + + Supported flags are: + + selected: the point is currently selected + highlight: the point is currently highlighted + background: the point is background information */ // for JS export const flagSelected = 1; -export const flagNaN = 2; +export const flagBackground = 2; export const flagHighlight = 4; // for GLSL export const glPointFlags = ` const float flagSelected = 1.; - const float flagNaN = 2.; + const float flagBackground = 2.; const float flagHighlight = 4.; bool isLowBitSet(float f) { @@ -32,12 +38,12 @@ export const glPointFlags = ` } void getFlags(in float flag, - out bool isNaN, + out bool isBackground, out bool isSelected, out bool isHighlight) { isSelected = isLowBitSet(flag); flag = shiftRightOne(flag); - isNaN = isLowBitSet(flag); + isBackground = isLowBitSet(flag); flag = shiftRightOne(flag); isHighlight = isLowBitSet(flag); }