I'm trying to render a particle simulation. I want each particle to leave a trace. To achieve this I'm using a framebuffer and two textures. On each frame the algorithm goes like this:
- Render to a framebuffer previously rendered screen texture with
opacity * 0.9
; - Render current particles at updated positions;
- Switch to main display and render current content of the framebuffer;
This works fine, and I get nice looking particle trails:
Problem
I want to allow users to pan and zoom canvas with these particles, similar to a map interface. This is achieved by applying a transformation matrix to each particle.
I want to keep particle's state, but I don't want the pan/zoom to leave a particle trace:
Bad
Here I'm dragging canvas up and down with mouse cursor. See how particles leave a trace?
Good
Here I'm also dragging the canvas up and down, but particles remain on their trajectory, without leaving a pan trace:
I'm wondering what is a proper way of achieving this? I got a basic solution working by applying a transformation to a previous frame's texture, so that it approximately matches what will be rendered in the current frame, but I there still a few artifacts:
- When zooming in, the updated texture "explodes":
I assume this is because I'm using fixed point size for a particle (regardless of the zoom level), but when we scale texture, we scale rasterized image, and thus all particles rendered on it also get bigger.
- When a particle enters the scene (crosses the border of visible area), it is also very likely to leave a trail:
I'm not sure why this one happens. My screen/back textures are the same size, I'm just translating back texture. I thought it might be related to clamp_to_edge setting, but I don't know how to prove or validate this. I've got a workaround by extending canvas beyond visible area (say by 2%) and in the fragment shader I check that if particle is closer than 2% to the border - I give it transparent color. This kind of "fixes" the problem, but I feel uncomfortable not knowing why it's happening.
- Finally, if transformation is very-very small (think kinetic movement), I also observe artifacts:
I'd appreciate if you could explain some of these artifacts, suggest possible solutions, or general practices used to solve this problem.