SFML community forums

Help => Graphics => Topic started by: Cadisol87 on November 16, 2014, 11:23:37 am

Title: sf::Quad Vertex Array Gradient isn't always 'smooth'
Post by: Cadisol87 on November 16, 2014, 11:23:37 am
Im currently making a Game, where the background should consist of a smooth, color-changing gradient.
In order to achieve that, I have a sf::Quad vertex array, each vertex is positioned in a corner of the window, and the vertices change color. This works pretty well, except that for some reason, sometimes the gradient isn't smooth.
Smooth:
(http://i.imgur.com/GKHBXdq.png)
Not Smooth (Ignore the blue fragment in the bottom right corner, my screen capturing program messed that up, I mean the green line which goes from the top right corner to the bottom left):
(http://i.imgur.com/DT493iu.png)

Why does this happen, and how can I avoid it?
Title: Re: sf::Quad Vertex Array Gradient isn't always 'smooth'
Post by: Gambit on November 16, 2014, 11:34:24 am
What code are you using for this? It sounds like the order of the vertices isnt always the same.
Title: Re: sf::Quad Vertex Array Gradient isn't always 'smooth'
Post by: Nexus on November 16, 2014, 11:44:32 am
This can happen because OpenGL splits quads into triangles. You could use a 2x2 texture with every corner color represented by one pixel, or write a fragment shader that computes a bilinear interpolation. I've used the latter approach in my game Zloxx II (http://en.sfml-dev.org/forums/index.php?topic=8403.0) to blend tiles together.

See also: http://stackoverflow.com/q/5359258
Title: Re: sf::Quad Vertex Array Gradient isn't always 'smooth'
Post by: Cadisol87 on November 16, 2014, 12:45:47 pm
@Gambit
What do you mean with the order of the vertices? The vertices are placed in clockwise order, starting in the bottom left corner, and they also change color in that order.

@Nexus
Since I want to port the game for iOS and Android, shaders aren't an option for me, because SFML doesn't support them on mobile devices.
I would use the texture option, but I guess I can't modify the corner colors in the texture, so that the gradient changes it's color, can I?
Title: Re: sf::Quad Vertex Array Gradient isn't always 'smooth'
Post by: Nexus on November 16, 2014, 01:44:54 pm
I would use the texture option, but I guess I can't modify the corner colors in the texture, so that the gradient changes it's color, can I?
What do you mean? You can provide the texture yourself, so it can have any color.

If you mean to modify the sf::Texture at runtime, also that is possible. Either by rendering to it via sf::RenderTexture, or by modifiying the pixels directly via sf::Image. But you should not do this too often per frame, rather prepare the texture as you like it.
Title: Re: sf::Quad Vertex Array Gradient isn't always 'smooth'
Post by: Cadisol87 on November 16, 2014, 03:55:30 pm
If you mean to modify the sf::Texture at runtime
Yes, thats what I meant.

Maybe it's a little bit too much to ask for, but isn't there any other solution? Because in my opinion it's not the most elegant way to solve the problem. For example, on the API Documentation Page (http://sfml-dev.org/documentation/2.1/classsf_1_1Texture.php) it says that converting from/to sf::Image is a slow operation, and I will have to do that in every frame, after I've changed the colors of the sf::Image. I think that'll be a problem, especially on mobile devices. :-\
Title: Re: sf::Quad Vertex Array Gradient isn't always 'smooth'
Post by: Laurent on November 16, 2014, 04:18:07 pm
It is less a problem for a 2x2 image ;)

Another solution is to subdivide the quad into a grid with more vertices, so that you can have more control on the color interpolation.
Title: Re: sf::Quad Vertex Array Gradient isn't always 'smooth'
Post by: Cadisol87 on November 16, 2014, 05:47:28 pm
How exactly would you divide the quad?
Because if you subdivide the quad into more quads, every one of the quads will have the seam too, won't they?

Title: Re: sf::Quad Vertex Array Gradient isn't always 'smooth'
Post by: Laurent on November 16, 2014, 06:26:15 pm
I don't know, it's just an idea. But if you apply the exact same algorithm as the GPU, then yes the result won't be different ;)
Title: Re: sf::Quad Vertex Array Gradient isn't always 'smooth'
Post by: Hapax on November 16, 2014, 10:11:39 pm
I mean the green line which goes from the top right corner to the bottom left):
(click to show/hide)
Why does this happen
This quad was split into two triangles and it looks like one triangle (assumed first) was top-left/top-right/bottom-left and the other (assumed last) was top-right/bottom-right, bottom-left.
If you consider that each triangle is drawn separately - and without any knowledge of the other - then the first triangle has no idea that it is supposed to be including the colour from the vertex in the last triangle that isn't in the first i.e. the bottom-right: blue.

It will generally look smooth if all of the colours are close to each other but the problem is most apparent when two opposite corners are similar but very different to the other two opposites, as in the second image.

As for how to avoid it...
Using shaders is (I think) the only real way to fix it but you say that not an option,
using a tiny texture fixes it but is probably best suited  for static colours,
using similar (or specially selected) colours helps to reduce the noticability of the effect,
splitting the quad into a grid (as Laurent suggested) also reduces the noticability. This would involve creating more, smaller squares, and interpolating each corner yourself.