Skip to content

Commit 3b3f28e

Browse files
authored
feat: add renderPointsAsSquares and disableAlphaBlending (#210)
1 parent 1420cf5 commit 3b3f28e

5 files changed

Lines changed: 86 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 1.13.0
2+
3+
- Feat: expose `renderPointsAsSquares` and `disableAlphaBlending` to allow finer control over performance increasing settings ([#206](https://github.com/flekschas/regl-scatterplot/issues/206))
4+
15
## 1.12.1
26

37
- Fix: prevent drawing points if all are filtered out ([#201](https://github.com/flekschas/regl-scatterplot/issues/201))

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,8 @@ can be read and written via [`scatterplot.get()`](#scatterplot.get) and [`scatte
823823
| annotationHVLineLimit | number | `1000` | the extent of horizontal or vertical lines | `true` | `false` |
824824
| antiAliasing | number | `0.5` | higher values result in more blurry points | `true` | `false` |
825825
| pixelAligned | number | `false` | if true, points are aligned with the pixel grid | `true` | `false` |
826+
| renderPointsAsSquares | boolean | `false` | true of `performanceMode` is true. can only be set on init! | `true` | `false` |
827+
| disableAlphaBlending | boolean | `false` | true of `performanceMode` is true. can only be set on init! | `true` | `false` |
826828

827829
<a name="property-notes" href="#property-notes">#</a> <b>Notes:</b>
828830

@@ -863,10 +865,12 @@ can be read and written via [`scatterplot.get()`](#scatterplot.get) and [`scatte
863865
- If you need to draw more than 2 million points, you might want to set
864866
`performanceMode` to `true` during the initialization to boost the
865867
performance. In performance mode, points will be drawn as simple squares and
866-
color blending is disabled. This should allow you to draw up to 20 million
868+
alpha blending is disabled. This should allow you to draw up to 20 million
867869
points (or more depending on your hardware). Make sure to reduce the
868870
`pointSize` as you render more and more points (e.g., `0.25` for 20 million
869-
works for me) to ensure good performance.
871+
works for me) to ensure good performance. You can also enable squared points
872+
and disable alpha blending individually via `renderPointsAsSquares` and
873+
`disableAlphaBlending` respectively.
870874

871875
<a name="property-by" href="#property-by">#</a> <b>colorBy, opacityBy, sizeBy:</b>
872876

src/index.js

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,13 @@ const createScatterplot = (
310310
spatialIndexUseWorker = DEFAULT_SPATIAL_INDEX_USE_WORKER,
311311
} = initialProperties;
312312

313+
const renderPointsAsSquares = Boolean(
314+
initialProperties.renderPointsAsSquares || performanceMode,
315+
);
316+
const disableAlphaBlending = Boolean(
317+
initialProperties.disableAlphaBlending || performanceMode,
318+
);
319+
313320
mouseMode = limit(MOUSE_MODES, MOUSE_MODE_PANZOOM)(mouseMode);
314321

315322
if (!renderer) {
@@ -1596,9 +1603,9 @@ const createScatterplot = (
15961603
let alpha =
15971604
((opacityByDensityFill * W * H) / (numPointsInView * p * p)) * min(1, s);
15981605

1599-
// In performanceMode we use squares, otherwise we use circles, which only
1600-
// take up (pi r^2) of the unit square
1601-
alpha *= performanceMode ? 1 : 1 / (0.25 * Math.PI);
1606+
// Unless `renderPointsAsSquares` is true, we use circles, which only take
1607+
// up (pi r^2) of the unit square
1608+
alpha *= renderPointsAsSquares ? 1 : 1 / (0.25 * Math.PI);
16021609

16031610
// If the pixels shrink below the minimum permitted size, then we adjust the opacity instead
16041611
// and apply clamping of the point size in the vertex shader. Note that we add 0.5 since we
@@ -1641,11 +1648,11 @@ const createScatterplot = (
16411648
getPointOpacityScale = getPointOpacityScaleBase,
16421649
) =>
16431650
renderer.regl({
1644-
frag: performanceMode ? POINT_SIMPLE_FS : POINT_FS,
1651+
frag: renderPointsAsSquares ? POINT_SIMPLE_FS : POINT_FS,
16451652
vert: createVertexShader(globalState),
16461653

16471654
blend: {
1648-
enable: !performanceMode,
1655+
enable: !disableAlphaBlending,
16491656
func: {
16501657
// biome-ignore lint/style/useNamingConvention: Regl specific
16511658
srcRGB: 'src alpha',
@@ -3611,6 +3618,14 @@ const createScatterplot = (
36113618
return performanceMode;
36123619
}
36133620

3621+
if (property === 'renderPointsAsSquares') {
3622+
return renderPointsAsSquares;
3623+
}
3624+
3625+
if (property === 'disableAlphaBlending') {
3626+
return disableAlphaBlending;
3627+
}
3628+
36143629
if (property === 'gamma') {
36153630
return renderer.gamma;
36163631
}

src/types.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@ export type Properties = {
210210
lassoLongPressIndicatorParentElement: HTMLElement;
211211
camera: Camera2D;
212212
performanceMode: boolean;
213+
renderPointsAsSquares: boolean;
214+
disableAlphaBlending: boolean;
213215
opacityByDensityDebounceTime: number;
214216
spatialIndex: ArrayBuffer;
215217
spatialIndexUseWorker: undefined | boolean;

tests/get-set.test.js

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,6 @@ test('get("isDrawing")', async () => {
728728
scatterplot.destroy();
729729
});
730730

731-
732731
test('set() after destroy', async () => {
733732
const scatterplot = createScatterplot({ canvas: createCanvas() });
734733

@@ -738,3 +737,57 @@ test('set() after destroy', async () => {
738737

739738
await expect(whenSet).rejects.toThrow(ERROR_INSTANCE_IS_DESTROYED);
740739
});
740+
741+
742+
test('get() and set() performance properties', async () => {
743+
const scatterplotA = createScatterplot({ canvas: createCanvas() });
744+
745+
expect(scatterplotA.get('performanceMode')).toBe(false);
746+
expect(scatterplotA.get('renderPointsAsSquares')).toBe(false);
747+
expect(scatterplotA.get('disableAlphaBlending')).toBe(false);
748+
749+
scatterplotA.set({
750+
'performanceMode': true,
751+
'renderPointsAsSquares': true,
752+
'disableAlphaBlending': true,
753+
});
754+
755+
expect(scatterplotA.get('performanceMode')).toBe(false);
756+
expect(scatterplotA.get('renderPointsAsSquares')).toBe(false);
757+
expect(scatterplotA.get('disableAlphaBlending')).toBe(false);
758+
759+
scatterplotA.destroy();
760+
761+
const scatterplotB = createScatterplot({
762+
canvas: createCanvas(),
763+
performanceMode: true,
764+
});
765+
766+
expect(scatterplotB.get('performanceMode')).toBe(true);
767+
expect(scatterplotB.get('renderPointsAsSquares')).toBe(true);
768+
expect(scatterplotB.get('disableAlphaBlending')).toBe(true);
769+
770+
scatterplotB.destroy();
771+
772+
const scatterplotC = createScatterplot({
773+
canvas: createCanvas(),
774+
renderPointsAsSquares: true,
775+
});
776+
777+
expect(scatterplotC.get('performanceMode')).toBe(false);
778+
expect(scatterplotC.get('renderPointsAsSquares')).toBe(true);
779+
expect(scatterplotC.get('disableAlphaBlending')).toBe(false);
780+
781+
scatterplotC.destroy();
782+
783+
const scatterplotD = createScatterplot({
784+
canvas: createCanvas(),
785+
disableAlphaBlending: true,
786+
});
787+
788+
expect(scatterplotD.get('performanceMode')).toBe(false);
789+
expect(scatterplotD.get('renderPointsAsSquares')).toBe(false);
790+
expect(scatterplotD.get('disableAlphaBlending')).toBe(true);
791+
792+
scatterplotD.destroy();
793+
});

0 commit comments

Comments
 (0)