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

Author Topic: fragment shader question  (Read 3547 times)

0 Members and 3 Guests are viewing this topic.

orestarh

  • Newbie
  • *
  • Posts: 5
    • View Profile
fragment shader question
« on: December 21, 2015, 01:27:59 pm »
Hello, folks.

Can you help me with the following?

I am trying to utilize the fragment shader which is available here: http://glslsandbox.com/e#4988.0
But I want to use it solely for a single SFML RectangleShape.
Say, I have a green non-textured rectangle with the following coordinates:
up-left corner: (10,10);
bottom-right corner: (200,20);

I know how to apply shader to rectangle shape, during rendering, the problem I have is that
it is unclear how to calculate 'vec2 position' in the shader itself,
because gl_FragCoord.xy gives us window-related coordinates.

Possibly I might pass out vertex positions from a vertex shader and use this data from within a fragment shader?

I attached an image with the result I am trying to achieve.

The shader:
#ifdef GL_ES
precision mediump float;
#endif

//tigrou.ind@gmail.com 2012.11.22 (for gamedevstackexchange)

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

void main( void ) {

    //how to calculate it for my rectangle?
        vec2 position = ( gl_FragCoord.xy / resolution.xy ) - mouse;

        float waves = sin(position.x*10.0)*0.01*sin(time*10.0)   +  sin(position.x*10.0+1.3)*0.01*sin(time*10.0+10.5);
        float color = position.y < waves ?(waves-position.y)*20.0 : 0.0;
        color = min(pow(color,0.5),1.0);
        gl_FragColor = vec4( position.y < waves ? mix(vec3(0.59,0.63,0.86),vec3(0.19,0.24,0.51),color) : vec3(0,0,0), 1.0 );
}
 

Thank you for your time, be glad for any valuable advices.
« Last Edit: December 21, 2015, 02:09:48 pm by orestarh »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: fragment shader question
« Reply #1 on: December 22, 2015, 12:52:01 am »
You could pass the position and size to the shader as uniforms.

Another option is to set a texture rect of the rectangle and the use the texture coords instead of fragment coords.
Then, you'd need to use gl_TexCoord[0].xy instead of gl_FragCoord.xy and make sure it's no longer using the range of the window's pixels.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

orestarh

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: fragment shader question
« Reply #2 on: December 22, 2015, 05:29:48 pm »
thank you, Hapax.

Tried to implement your approach, but all I have is a rectangle filled with one color. Maybe setting texture rect without texture is wrong? I mean, it is still just a simple rectangle without any texture.
« Last Edit: December 22, 2015, 05:36:11 pm by orestarh »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: fragment shader question
« Reply #3 on: December 22, 2015, 10:14:14 pm »
You might be right. Texture coordinates may be discarded by SFML if it doesn't have a texture; I haven't looked. You could try it with a texture though. Just set its texture but don't use that texture in the shader.

Did you try the first option?
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

orestarh

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: fragment shader question
« Reply #4 on: December 23, 2015, 06:33:10 am »
I solved it, using your 2nd option, finally. It works no matter whether the texture is set or not.

Out of curiosity, as for your 1st option:
Quote
gl_FragCoord is an input variable that contains the window relative coordinate (x, y, z, 1/w) values for the fragment.
, therefore I guess it won't work in my scenario, because the rectangle's position uses  absolute world coordinates. These are the two different things. Please correct me if I am wrong.

Anyway, thank you for helping me out!

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: fragment shader question
« Reply #5 on: December 23, 2015, 04:38:40 pm »
I solved it, using your 2nd option, finally. It works no matter whether the texture is set or not.
How? Share it so others can benefit from your discovery!  :)

Out of curiosity, as for your 1st option:
Quote
gl_FragCoord is an input variable that contains the window relative coordinate (x, y, z, 1/w) values for the fragment.
, therefore I guess it won't work in my scenario, because the rectangle's position uses  absolute world coordinates. These are the two different things. Please correct me if I am wrong.
You'd only need to convert the position from world coordinates to screen coordinates before passing to the shader.
SFML can already this for you!  ;)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

orestarh

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: fragment shader question
« Reply #6 on: December 23, 2015, 06:21:43 pm »
I solved it using the following:
_shader.setParameter("width", wh.x); //rectangle's width
_shader.setParameter("height", wh.y); //rectangle's height

_rectShape.setTextureRect(sf::IntRect(sf::Vector2i(0, 0), sf::Vector2i(wh.x, wh.y)));
 
and then in shader  I have:
uniform float width;
uniform float height;

void main(void) {
    vec2 position = gl_TexCoord[0].xy / vec2(width, height);
    //...
}
 

Now back to the 1st option, I am still having troubles with it.
I.e now I pass window coordinates to shader:
Code: [Select]
    auto foo = target.mapCoordsToPixel(_pos);
    _shader.setParameter("posx", foo.x);
    _shader.setParameter("posy", foo.y);
and in shader I use:
Code: [Select]
uniform float width;
uniform float height;
uniform float posx;
uniform float posy;

void main(void) {
    vec2 position = vec2(posx, posy) / vec2(width, height);
    //...
and have unpleasant results.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: fragment shader question
« Reply #7 on: December 23, 2015, 11:00:47 pm »
With regard to your solution, I have a suggestion to simplify it for reusage:
Set the texture rectangle to (0, 0) - (1, 1)
This way, there should not be any need for width and height parameters as all objects would be using the same range. Inside the shader, you can use gl_TexCoord[0].xy directly since there would be no longer a need for the division.

(click to show/hide)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

orestarh

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: fragment shader question
« Reply #8 on: December 24, 2015, 07:32:06 pm »
Hapax, you were right:) it works like a charm, simple and elegant.