3
\$\begingroup\$

I've been testing out fragment shaders in SFML, trying to learn how to write and use them and I've run into a recurring problem. Every shader distorts the texture. Top left is the distorted test texture, top right and bot left are there for comparison along the axis Top left is the distorted test texture, top right and bot left are there for comparison along the axis.

The texture is 512x512 pixels in size and the sprite has the same dimensions. I've narrowed down the problem to this line.

vec2 texCoord = (gl_FragCoord.xy / sourceSize.xy);

Where sourceSize is the resolution. The value I'm passing in being (512,512). I've tested around with different values, the closest to the correct output is when I pass in the values (512, 1086) giving this.

Top Left is the distorted Texture, Top right and bottom left are there to show the distortion Top left is the distorted texture. The X axis is correct but the Y axis is stretched enough to hide the numbers and enlarge the border.

Currently the shader does nothing for testing purposes.

uniform sampler2D       source;
uniform vec2            sourceSize;
uniform float           time;


void main( void )
{
        vec2 texCoord = (gl_FragCoord.xy / sourceSize.xy); //Value between 0.0 and 1.0
        texCoord = vec2 (texCoord.x,1.0-texCoord.y);    //Inverts the y component. GLSL treats bot left corner as the origin, sfml treats top left as it.
        vec4 Color = texture2D(source, texCoord);

        gl_FragColor = Color;
}

I'm not sure how to fix this. What I'm trying to achieve is a shader that doesn't distort the base texture so I can build on from there. Thanks for any help you can give.

\$\endgroup\$
  • \$\begingroup\$ What are you using gl_FragCoord for? Don't you want texture co-ordinates coming from your vertices? \$\endgroup\$ – Jack Aidley Jun 5 at 12:01
  • \$\begingroup\$ I don't know much about shaders (doing this to learn), so I don't exactly understand what you're saying there. It's a fragment shader and you need to pass the location of the pixel to be shaded? \$\endgroup\$ – Sean Jun 5 at 12:18
  • 2
    \$\begingroup\$ Fragcoord is the pixel of the screen you are working on, not the point on the sprite's texture. If for instance you draw a sprite that covers the top left quarter of the screen, then the x and y coordinates of texCoord in your shader would go from 0 to 0.5. I don't know how you would do it in SFML, but you need to ask for the UV coordinates \$\endgroup\$ – Bálint Jun 5 at 13:34
1
\$\begingroup\$

When you're writing a fragment shader, you aren't doing anything in a holistic manner. You don't care about the forest. All you care about is the tree you're looking at right now.

In that sense, if you're doing anything that involves the resolution of a texture or a screen, the relevant calculations (usually) happen outside of the fragment shader. The shader (usually) doesn't care how many pixels a screen has, or how many texels a texture has. It only cares about whatever coordinates it has been provided to render things at this exact pixel on the screen, right now.

I am not well acquainted with SFML, and I don't know how you've set up your scene here, but if you're displaying a quad you've created, then when you create the mesh for it, you typically set "UVs" or "texcoords" for each of the vertices. Texture coordinates are a suggestion to the engine about how it should position a texture over the surface of a mesh. These are not the only way to communicate to a fragment shader where to put a texture, but they are by far the most common way to accomplish this.

In SFML shaders, you would normally find the texture coordinate being rendered at the current position with gl_TexCoord[0].xy (as noted here: https://www.sfml-dev.org/tutorials/2.5/graphics-shader.php).

My recommendation is that you:

  1. Make sure that you're setting proper texture coordinates on any geometry that you're rendering.

  2. Use gl_TexCoord[0].xy to do your texture coordinate lookup.

\$\endgroup\$
  • \$\begingroup\$ Thanks a bunch, changing vec4 Color = texture2D(source, texCoord); to vec4 Color = texture2D(source, gl_TexCoord[0].xy); Fixed the distortion, I'm trying to figure out why but the other shaders I've been messing with are functioning properly now. Thanks again. \$\endgroup\$ – Sean Jun 6 at 10:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.