Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Rendering via a RenderingTexture  (Read 3915 times)

0 Members and 1 Guest are viewing this topic.

sidewinder

  • Newbie
  • *
  • Posts: 16
    • View Profile
Rendering via a RenderingTexture
« on: April 28, 2019, 10:39:44 am »
Hello!

I have been experimenting a little bit with SFML and so far it seems nice. Ive got a little nice Server-Client setup with moving sprites and so on, and that part works fine.

Then I had a go at drawing some particle effects, that works fine as well, but here I get some concerns about performance. First off, here is my experiment with particles:


Its based of red rectangles that rise and get smaller and more transparent. The yellow comes from a BlendAdd between each rectangle. Its not that slow, but if a make a few of these I can see that fps starts to drop, so I tried to see how I can optimize it.

First step was to use a VertexArray of quads instead of Rectangle shapes, this part works pretty well once I got the hinge of how it worked.

The remaining problem is that in order to get the Blend to look as I want it to I need to exclude the green background, so I did this by  drawing it to a RenderingTexture and then apply that texture to a Sprite which I draw to the window.

So far so good, but I feel that I need some advice here.

First question is short. Is there some better way to get the blending on "only the particles" without using the RenderingTexture?

Second question is a bit longer, if I have to use the RenderingTexture, what is the optimal way of doing that? Let me give you some of my thoughts.

The first naive way is to just add a Rendering Texture just where it is needed

class FireParticle : public sf::Drawable, public sf::Transformable
{
void draw(sf::RenderTarget &target, sf::RenderStates states) const
{
        sf::RenderTexture renderTexture;
        renderTexture.create(100, 100);
        states.transform *= getTransform();

        renderTexture.clear(sf::Color::Transparent);
        /*particles is the VertexArray containing all the rectangles*/
        renderTexture.draw(particles, sf::RenderStates(sf::BlendAdd));
        renderTexture.display();

        sf::Sprite sprite;
        s.setTexture(renderTexture.getTexture());

        target.draw(sprite, states);
}

}

This works and is what I have right now as my PoC, but I see myself that this is not optimal, the constantly new Rendering Textures should be a drag on fps (and it is!)

So I need to reuse the RendeingTexture, and here I wonder how they really are supposed to be used. I can think of a few ways

  • Keep a RenderingTexture of the same size as the effect in each Particle class
  • Keep a single RenderingTexture and let everything recreate this in the size of the effect (is this just as bad as creating new RenderingTextures?)
  • Create a single RenderingTexture next to the RenderingWindow (with the same dimensions) and pass this along to everything that needs separate rendering


The more I think about this it seems like the third option should be the correct one. But since there is a forum I thought I'd ask :) Is there a fourth option that I have not thought of?

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Rendering via a RenderingTexture
« Reply #1 on: April 28, 2019, 10:25:41 pm »
I recently wanted a specific blending for some particles so used a separate render texture for the particles and then drew that texture onto the window afterwards as you have mentioned. I used a single full-window-sized render texture that persisted throughout. That was my go-to idea and seemed okay from my experience.

You could use a smaller render texture if you know the local size (or maximum size) of the particles area. This would just contain the particles and then can be drawn on the correct part of the window. Note that if your particles leave the contained area (render texture) they will be cropped.

I would recommend the full-sized render texture, at least at first. Try it and see. If you have issues, consider other approaches.

Do you want the yellow in your effects? How are you achieving yellow from adding reds together?

Also, you could maybe try to use a custom blend mode that adds more depending on its transparency or something similar for a possibly similar effect.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

sidewinder

  • Newbie
  • *
  • Posts: 16
    • View Profile
Re: Rendering via a RenderingTexture
« Reply #2 on: April 28, 2019, 10:37:21 pm »
I would recommend the full-sized render texture, at least at first. Try it and see. If you have issues, consider other approaches.

Thanks for the answer!
Yeah, that's the one I'm trying now. Seems to work pretty well


Do you want the yellow in your effects? How are you achieving yellow from adding reds together?

Yes, I wanted it to look like fire, it is not completely red, small parts in the other channels produce the yellow when they are put together :)

Here are some other versions of colours:


RBG codes from left to right:
255, 52, 11
11, 55, 255
10, 100, 10

« Last Edit: April 28, 2019, 10:39:00 pm by sidewinder »

Martin Sand

  • Newbie
  • *
  • Posts: 24
    • View Profile
    • Email
Re: Rendering via a RenderingTexture
« Reply #3 on: May 10, 2019, 04:56:47 pm »
Interesting effect! I really like it.

Quote
Yes, I wanted it to look like fire, it is not completely red, small parts in the other channels produce the yellow when they are put together :)

To which other channels do you refer to, G and B? Do you read the R channel and put them on top?

sidewinder

  • Newbie
  • *
  • Posts: 16
    • View Profile
Re: Rendering via a RenderingTexture
« Reply #4 on: May 10, 2019, 08:54:34 pm »
To which other channels do you refer to, G and B? Do you read the R channel and put them on top?

G and B yes, I just draw them all with sf::BlendAdd