regl-scatterplot
regl-scatterplot copied to clipboard
Displaying colors instead of dots after hiding and showing points multiple times.
Hello!
We encountered a bug using the latest version of the regl-scatterplot package, which breaks the displaying of dots when we try to hide/show the drawn points.
The bug could be seen and reproduced in the Codepen https://codepen.io/Sagva/pen/bGZKyBb
It was tested in different browsers with the same result: Chrom, Firefox, Edge (all on OS Windows 11).
Steps to reproduce:
- Create a scatterplot
- Draw points using the method:
scatterplot.draw([
[0.2, -0.1, 0, 0.1337],
[0.3, 0.1, 1, 0.3371],
[-0.9, 0.8, 2, 0.3713],
]);
- Press the “Hide/show points” button which uses
scatterplot.draw([])orscatterplot.clear()for hiding and
scatterplot.draw([
[0.2, -0.1, 0, 0.1337],
[0.3, 0.1, 1, 0.3371],
[-0.9, 0.8, 2, 0.3713],
]);
for showing points again.
After around 30 showings/hidings the scatter plot displays the colors in a mesh instead of the dots.
The console shows warnings:
WebGL: INVALID_ENUM: activeTexture: texture unit out of range
[.WebGL-000045A00AE21B00] GL_INVALID_OPERATION: Feedback loop formed between Framebuffer and active Texture.
[.WebGL-000045A00AE21B00] GL_INVALID_VALUE: Sampler uniform value out of range.
Best regards, Elena.
Oh nooo! That's an odd one. I'll take a look what might causes this error to be thrown. You mentioned "in the latest version". Does that mean this used to work before?
As a quick work around, if you really only want to hide and show points, scatterplot.filter([]) and scatterplot.unfilter() should be more performant.
Oh nooo! That's an odd one. I'll take a look what might causes this error to be thrown. You mentioned "in the latest version". Does that mean this used to work before?
We haven't tested it in the versions that are earlier than v1.8.4 and v1.8.5. This bug occurs in both versions.
As a quick work around, if you really only want to hide and show points, scatterplot.filter([]) and scatterplot.unfilter() should be more performant.
Thank you, will try to use that instead.
Looks like repeatedly setting params causes the bug:
scatterplot.set({
pointColor: ['#FF0000', '#0000FF', '#008000'],
pointSize: 10,
opacity: 1,
colorBy: "valueA"
});
In the Codepen https://codepen.io/Sagva/pen/wvOxvdg that uses scaterplot.filter([]) and calls scatterplot.set({...}) each time when the button is clicked, also has the same result with broken dot displaying.
Yeah, I suspect it has to do with repeated uploads of a new texture to the GPU, which happens in both scenarios that you describe.
I think the issue is that you're calling draw() prematurely before the previous draw call was finished. When I change your demo as follows, I cannot reproduce the error anymore:
import createScatterplot from "https://esm.sh/regl-scatterplot";
let isHidden = false;
const canvas = document.querySelector('#canvas');
const { width, height } = canvas.getBoundingClientRect();
const scatterplot = createScatterplot({
canvas,
width,
height,
pointColor: ['#FF0000', '#0000FF', '#008000'],
pointSize: 10,
opacity: 1,
colorBy: "valueA"
});
const points = [
[0.2, -0.1, 0, 0.1337],
[0.3, 0.1, 1, 0.3371],
[-0.9, 0.8, 2, 0.3713],
]
function drawPoints() {
scatterplot.draw([
[0.2, -0.1, 0, 0.1337],
[0.3, 0.1, 1, 0.3371],
[-0.9, 0.8, 2, 0.3713],
]);
scatterplot.set({
pointColor: ['#FF0000', '#0000FF', '#008000'],
pointSize: 10,
opacity: 1,
colorBy: "valueA"
});
}
drawPoints()
const btn = document.querySelector('#button');
btn.addEventListener("click", async () => {
btn.disabled = true;
if (!isHidden) {
await scatterplot.draw([])
} else {
await scatterplot.draw(points);
}
isHidden = !isHidden
btn.disabled = false;
});
The key difference here is that the click handler is async and awaits the finishing of the draw call before accepting a new draw call by disabling the button in between.
There should be a way for regl-scatterplot to handle this internally by ignoring premature draw() calls but the easier solution is to embrace that draw() is an asynchronous call.
Thank you for your time and answer! It was helpful.