diff --git a/client/src/components/graph/drawPointsRegl.js b/client/src/components/graph/drawPointsRegl.js index 11df03ea..1bc44ad2 100644 --- a/client/src/components/graph/drawPointsRegl.js +++ b/client/src/components/graph/drawPointsRegl.js @@ -1,4 +1,4 @@ -import { glPointFlags } from "../../util/glHelpers"; +import { glPointFlags, glPointSize } from "../../util/glHelpers"; export default function(regl) { return regl({ @@ -23,12 +23,15 @@ export default function(regl) { // import getFlags() ${glPointFlags} + // get pointSize() + ${glPointSize} + void main() { bool isNaN, isSelected, isHighlight; getFlags(flag, isNaN, isSelected, isHighlight); - float size = isHighlight ? 8. : isSelected ? 4. : 1.; - gl_PointSize = (0.5 * pow(distance, 2.5)) + size; + float size = pointSize(nPoints, minViewportDimension, isSelected, isHighlight); + gl_PointSize = size * pow(distance, 1.2); float z = isNaN ? zBottom : (isHighlight ? zTop : zMiddle); vec3 xy = projView * vec3(position, 1.); diff --git a/client/src/components/scatterplot/drawPointsRegl.js b/client/src/components/scatterplot/drawPointsRegl.js index 4f1d01df..7e098a12 100644 --- a/client/src/components/scatterplot/drawPointsRegl.js +++ b/client/src/components/scatterplot/drawPointsRegl.js @@ -1,4 +1,4 @@ -import { glPointFlags } from "../../util/glHelpers"; +import { glPointFlags, glPointSize } from "../../util/glHelpers"; export default function(regl) { return regl({ @@ -22,11 +22,14 @@ export default function(regl) { // import getFlags() ${glPointFlags} + // get pointSize() + ${glPointSize} + void main() { bool isNaN, isSelected, isHighlight; getFlags(flag, isNaN, isSelected, isHighlight); - gl_PointSize = isHighlight ? 8. : isSelected ? 4. : 1.; + gl_PointSize = pointSize(nPoints, minViewportDimension, isSelected, isHighlight); float z = isNaN ? zBottom : (isHighlight ? zTop : zMiddle); vec3 xy = projection * vec3(position, 1.); diff --git a/client/src/util/glHelpers.js b/client/src/util/glHelpers.js index c6dc6e41..21cecc44 100644 --- a/client/src/util/glHelpers.js +++ b/client/src/util/glHelpers.js @@ -1,12 +1,13 @@ /* -Utility code for our WebGL shaders +Utility code for WebGL shaders */ /* -Point flags - used in graph & scatter plots +PointFlags: + Point flags are used in graph & scatter plots. -We want a bitmask-like flag structure, but due to webgl limitations -must emulate it with floats. + We want a bitmask-like flag structure, but due to webgl limitations + must emulate it with floats. */ // for JS @@ -42,3 +43,39 @@ export const glPointFlags = ` } `; + +/* +Point Size: + Calculate point size for scatter plot based upon pseudo density. + + Current approach: linear scaling of point size, clamped to [1,10], + between two points that are based on empirical testing. + + - 1M points on a 500x500 canvas: 1M/(500*500) -> 0.5 + - 1000 points on a 1440x1440 canvas: 1000/(1440*1440) -> 5 + + The domain is pseudo density (numPoints / minViewportDimension^2) + The range is web gl point size. +*/ + +// configuration +const domain = [1000000 / (500 * 500), 1000 / (1440 * 1440)]; +const range = [0.5, 5]; + +// derived from configuration +const scale = (range[1] - range[0]) / (domain[1] - domain[0]); +const offset = scale * -domain[0] + range[0]; + +export const glPointSize = ` + float pointSize(float nPoints, float minViewportDimension, bool isSelected, bool isHighlight) { + float density = nPoints / (minViewportDimension * minViewportDimension); + float pointSize = (${scale.toFixed(4)}*density) + ${offset.toFixed(4)}; + pointSize = clamp(pointSize, + ${range[0].toFixed(4)}, + ${range[1].toFixed(4)}); + + if (isHighlight) return 2. * pointSize; + if (isSelected) return pointSize; + return pointSize / 3.; + } +`;