The general idea is to achieve an effect by drawing to an image and then blurring it every frame.
At the moment I have the effect working, but I'm not getting the performance I had hoped for.
The way it works at the moment is to have a cycle of 5 objects that the image goes through:
sf::Image drawImage;
drawImage.create(window.getSize().x, window.getSize().y, sf::Color::Transparent);
sf::Texture drawBufferTexture;
drawBufferTexture.create(drawImage.getSize().x, drawImage.getSize().y);
sf::Sprite drawBufferSprite;
drawBufferSprite.setTexture(drawBufferTexture);
sf::RenderTexture drawRenderTexture;
drawRenderTexture.create(drawImage.getSize().x, drawImage.getSize().y);
sf::Sprite drawSprite;
drawSprite.setTexture(drawRenderTexture.getTexture());
The drawing is done into drawImage, and the image is then rendered to a buffered RenderTexture with a shader to do the blurring, and then the blurred image is fed back from the texture to the original image:
drawBufferTexture.update(drawImage);
drawRenderTexture.clear(sf::Color::Transparent);
drawRenderTexture.draw(drawBufferSprite, &drawBlur);
drawRenderTexture.display();
//Cycle texture back to image:
drawImage = drawRenderTexture.getTexture().copyToImage();
and finally the sprite that now contains the blurred image is rendered:
window.draw(drawSprite);
The slow bit seems to be, as expected, the cycling from the RenderTexture back into the image. I need to cycle the blurred image back so that more can be drawn to it next frame, so this needs to be achieved somehow.
Is there something I'm missing here? Is there a much faster way to do this without the copyToImage() step? Is there some way to do this all within one RenderTexture using a shader?
Typically, I would only expect to be drawing into (significantly) less than 10 percent of the image each frame if that helps.
I'm currently managing to get about 70 fps on a 1080px x 1080px image out of this using a GTX 980, and I had hoped to be able to push it to higher resolutions at higher fps. Without the copyToImage step I can easily maintain 144 fps at 2160x2160.
I managed to do this at 800x800 resolution @60fps in flash on my laptop back in ~2012, so I know in principle this effect must be doable efficiently with full access to the GPU, I'm just not sure how to achieve it.