1
\$\begingroup\$

I'm having trouble getting my sf::Shader to work on an sf::Texture that I've drawn myself. The vertex shader is pretty standard (I think it's just a copy of the example from SFML's page). The fragment shader is from somewhere in their forums, I'm new to glsl, but my understanding is it takes in a vec3 for the light position (I'm using the mouse position) and then figures the distance to/from the fragment (which comes from the other shader?) and then uses that to determine how light/dark things should be.

It works really well for the rectangle shape I had drawn, but when I try to use the sf::Texture, it shows up regardless of where it is. However -- it does get lighter as the light moves toward it (just not darker/disapear when the light gets farther).

Here is the texture being shown when it shouldn't: View post on imgur.com

Here is the texture being light really bright when the light gets near it: View post on imgur.com

Here is my vertex shader:

uniform sampler2D texture;

void main()
{
  // transform the vertex position
  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

  // transform the texture coordinates
  gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;

  // forward the vertex color
  gl_FrontColor = gl_Color;
}

And here is my fragment shader:

uniform sampler2D texture;
uniform vec3 light;

void main() {
     float distance = sqrt(pow(gl_FragCoord.x - light.x, 2) +
               pow(gl_FragCoord.y - light.y, 2));

     if(floor(light.x) == floor(gl_FragCoord.x) &&
        floor(light.y) == floor(gl_FragCoord.y))
       distance = 0.1;

     if(distance>light.z)
         distance = light.z;

     vec2 pos = gl_TexCoord[0].xy;

     gl_FragColor = mix(texture2D(texture,pos),
            gl_Color,
            1.0 - (distance/light.z));

}

As for loading/rendering, the shader loads with no error using loadFromFile() and then I create a sf::RenderStates, attaching my shader and setting the parameter "texture" to sf::Shader::CurrentTexture.

The cyan square is just a sf::RectangleShape and the poorly drawn bricks are a png file, loaded to a sf::Texture attached to a sf::Sprite.

The rendering code isn't much:

window.clear();
window.draw(rect, renderState);
window.draw(sprite, renderState);
window.display();

Any help would be much appreciated! If you need any more code / info, let me know.

Thanks!

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

The normal color of a pixel in an SFML fragment shader is supposed to be:

gl_FragColor = gl_Color * texture2D(texture, gl_TexCoord[0].xy);

In your code you're mixing color from the texture (when it's dark) to the color of the sprite (when it's lit), that's why it shows the texture when it's dark and it shows white when it's lit (white is the default sprite color).

I think mixing from black (or whatever color you want the darkness to be) to gl_Color * texture2D(texture, pos) should do what you want:

 gl_FragColor = mix(vec4(0, 0, 0, 0),
        gl_Color * texture2D(texture, pos),
        1.0 - (distance/light.z));
\$\endgroup\$
1
  • \$\begingroup\$ Thanks!! That was the trick. Occasionally, I get a note that it isn't responding, but I'm sure that is something unrelated. \$\endgroup\$
    – Andy M
    Commented Nov 8, 2015 at 20:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .