amandaghassaei / gpu-io

A GPU-accelerated computing library for running physics simulations and other GPGPU computations in a web browser.

Home Page:https://apps.amandaghassaei.com/gpu-io/examples/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Canvas clear

esperanc opened this issue · comments

I am a little confused about when the canvas is cleared in a multi-step program. How does one disable canvas clearing, for instance?

you can disable clearing by passing in preserveDrawingBuffer: true to the GPUComposer:

const composer = new GPUComposer({ canvas, contextAttributes: { preserveDrawingBuffer: true } });

Here is an example:

const {
	GPUComposer,
	GPULayer,
	GPUProgram,
	setColorProgram,
	FLOAT,
} = GPUIO;

// Init a canvas element.
const canvas = document.createElement('canvas');
document.body.appendChild(canvas);

// Init a composer.
const composer = new GPUComposer({ canvas, contextAttributes: { preserveDrawingBuffer: true } });

// Init a program to draw color.
const colorProgram = setColorProgram(composer, {
	name: 'setColor',
	type: FLOAT,
});

// Draw red background.
colorProgram.setUniform('u_color', [1, 0, 0]);
composer.step({
	program: colorProgram,
});

// Simulation/render loop.
function loop() {
	window.requestAnimationFrame(loop);
	// Draw a circle on top of canvas.
	colorProgram.setUniform('u_color', [Math.random(), Math.random(), Math.random()]);
	composer.stepCircle({
		program: colorProgram,
		position: [Math.random() * canvas.clientWidth, Math.random() * canvas.clientHeight],
		diameter: 10,
	});
}
loop(); // Start animation loop.

the result:
Screen Shot 2023-01-15 at 1 04 16 PM

I'm not going to enable this by default because it looks like it can cause some slowdowns if it's not really needed, but hopefully that fixes your problem.

I really like what you did with the observable notebook by the way! excited to see what else you do with this.

just to add to this - in a multi-step program the canvas is not ever explicitly cleared by gpu-io. But without setting preserveDrawingBuffer: true the canvas may still be cleared by webgl at some point during runtime. I found that when I ran the program above without setting preserveDrawingBuffer: true, I could draw three circles and it would look good, then it would get cleared on the fourth circle draw. So basically setting preserveDrawingBuffer: true guarantees that this clearing won't occur internally.

I have a clear() method on GPULayer, would it be useful to add a clear() method to GPUComposer to trigger a manual clear as well? I would also add a clearValue so you could set what value the canvas clears to.

Thanks a bunch for the enlightenment. I am writing code to plot circle inversion fractals and not clearing the FB is a must. Preserving the drawing buffer did the trick. I is weird, though, that the frame buffer gets cleared unexpectedly. About your question - yes, an explicit composer.clear() would be nice. The confetti demo is cute, by the way!

sounds good. until I get a chance to add a clear() method, here's a workaround: to manually clear the canvas you can just draw a color to the full screen with step() the way that I did in the demo to get the red background. I'll let you know when clear() is added.

The unexpected clearing just has to do with how webgl manages its buffers internally, basically the data just hangs out there in memory until something else gets written over it. I'd imagine that the behavior could be slightly different between different devices too, the preserveDrawingBuffer flag should guarantee that it won't get over-written.

please send me a link when you are done, I'd love to see it!

GPUComposer.clear() has been added to version 0.2.2

here's an example of how to use it:

// Clear canvas to a random rgba color.
window.addEventListener('keypress', (e) => {
	if (e.key === 'c') {
		composer.clearValue = [Math.random(), Math.random(), Math.random(), 1];
		composer.clear();
	}
});

by default, clearValue is set to [0, 0, 0, 0].