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

Author Topic: Can't use texture coordinates without a texture  (Read 2934 times)

0 Members and 1 Guest are viewing this topic.

Foaly

  • Sr. Member
  • ****
  • Posts: 453
    • View Profile
Can't use texture coordinates without a texture
« on: July 29, 2015, 12:44:47 pm »
Hello there!

Yesterdy I checked out the radial gradient shader that appeared on the wiki recently, because I wanted to use this effect in a little project of mine. While I was browsing the code I wondered why the code is so complicated. You have to specify a center, a radius and the windows height; all in screen coordinates! So I thought there has to be an easier way using variables that are already defined in the shader, like texture coordinates.

It turns out it's not that easy. I set up a sf::CircleShape with a size, a color, a position and a gradient fragment shader. Something was wrong with the texture coordinates though. When I set the output color to gl_TexCoord[0].xy the output was always black for all fragments. Debbuging into the code of sf::Shape it turns out the texture coordinates are only calculated properly if m_textureRect is set. So I set the texture rect to sf::Int(0, 0, size, size) and the texture coordinates in the shader turned white, meaning there was another problem. I debugged a little further and remembered that SFML uses non-normalized texture coordinates. Since I don't have a texture applyed sf::Texture::bind doesn't get called and the texture coordinates are not being converted. If I devide the coordinates by the shapes size in the shader everything works as expected.

All of that seems quiet hackey to me though. I think we should be able to use the texture coordinates even if the shape has no texture. A lot of effects rely on texture coordinates, especially post processing effects done in the fragment shader, it would be sad if you can't use them with an untextured shape. Or is there a reason that this has been left out?
I'd suggest if m_texture is NULL, set m_textureRect to the shapes dimensions and apply the texture transform matrix in the draw method or simply set the texture coordinates to normalized coordintes when m_texture is NULL. I can write a pull request if this gets agreed on.
« Last Edit: July 29, 2015, 02:24:19 pm by Foaly »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Can't use texture coordinates without a texture
« Reply #1 on: July 29, 2015, 02:04:21 pm »
Quote
I'd suggest if m_texture is NULL, set m_textureRect to the shapes dimensions and apply the texture transform matrix in the draw method
Setting the texture matrix is very expensive.

Quote
or simply set the texture coordinates to normalized coordintes when m_texture is NULL.
This would be really hacky :P
Laurent Gomila - SFML developer

Hapax

  • Hero Member
  • *****
  • Posts: 3339
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Can't use texture coordinates without a texture
« Reply #2 on: July 29, 2015, 02:10:54 pm »
I hit the very same wall!  :P

It doesn't seem to make sense to have texture co-ordinates if there is no texture, though, so any solution seems to be "hacky".
Thing is, even though, at first, the global screen co-ordinates seems like a bit of a chore for some scenarios, it turns out quite useful in others e.g. lighting masks etc.

Anyway, I'm glad you found the shader interesting and I hope you actually find it useful, regardless of its number of parameters   :D
SFML's inversion of the y axis made it even more complicated! ;D (hence the windowHeight parameter)

p.s. Your link to the shader is broken.
« Last Edit: July 29, 2015, 02:31:14 pm by Hapax »
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Foaly

  • Sr. Member
  • ****
  • Posts: 453
    • View Profile
Re: Can't use texture coordinates without a texture
« Reply #3 on: July 29, 2015, 02:53:17 pm »
I agree that screen coorinates can be very useful in shaders, but the standart way is to work with normalized coordinates in the fragment shader.
I know it might seem counter intuitive to have texture coordinats set, when there is no texture, but they are set anyway (to 0,0 right now), so why not set them to something useful that people can work with? There are use cases for it. I mean you had the same problem and I am sure other would benefit from this too. Also as a user there is no way to change the texture coordinates of a shape, because they are encapsulated.

@Laurent: could you explain why the second solution would be more hacky? It could simply be stated in the documentation that if there is no texture set, the texture coordinates correspond normalized local coordinates.

edit:
by the way here is the shader code that I am using in case someone is interested:
void main(void)
{
    vec2 uv = gl_TexCoord[0].xy / 40.0;
    const vec2 center = vec2(0.5, 0.5);

    float distanceFromCenter = distance(uv, center);
    const vec2 radiuses = vec2(0.5, 0.3);

    vec4 vertexColor = gl_Color;
    vec4 opaqueColor = vec4(gl_Color.rgb, 0.0);

    float interpolator = 1.0 - smoothstep(radiuses.x, radiuses.y, distanceFromCenter);

    //gl_FragColor = vec4(uv.x, uv.y, 1.0, 1.0);
    gl_FragColor = mix(vertexColor, opaqueColor, interpolator);
}
« Last Edit: July 29, 2015, 02:55:03 pm by Foaly »

Hapax

  • Hero Member
  • *****
  • Posts: 3339
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Can't use texture coordinates without a texture
« Reply #4 on: July 29, 2015, 03:19:52 pm »
Wouldn't it be semantically more correct to pass interpolated vertex positions to the fragment shader? I'm not sure it's possible, though.
This becomes even more important when you involve a texture as well and the texture co-ordinates are different. This is a consideration for creating a version of that shader for textured objects - when the texture rect doesn't match the object exactly.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Can't use texture coordinates without a texture
« Reply #5 on: July 29, 2015, 03:36:51 pm »
Quote
@Laurent: could you explain why the second solution would be more hacky?
Because it's a special case. The behaviour is different for a very specific condition. I prefer consistent and intuitive behaviours, rather than specific stuff that require to read the doc ;)
Laurent Gomila - SFML developer

Foaly

  • Sr. Member
  • ****
  • Posts: 453
    • View Profile
Re: Can't use texture coordinates without a texture
« Reply #6 on: July 30, 2015, 05:13:48 pm »
But think about it, right now the behaviour is inconsistent. When you have a texture the texture coordinates correspond to their normalized position within the bounds of shape. If you have no texture there is no way to access that position data. Wouldn't it be more consistent to give access to that data in every case?

I know that special behaviour that requires consulting the doc is bad, but the only people who would notice this, would be the people that want to use texture coordinates without a texture anyway. And those people would expect the coords to be set properly.

Foaly

  • Sr. Member
  • ****
  • Posts: 453
    • View Profile
Re: Can't use texture coordinates without a texture
« Reply #7 on: August 05, 2015, 06:19:37 pm »
Has anybody else from the team an opinion about this?