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

Author Topic: Shader Problems.  (Read 6648 times)

0 Members and 1 Guest are viewing this topic.

Valleriani

  • Newbie
  • *
  • Posts: 13
    • View Profile
Shader Problems.
« on: July 25, 2015, 10:18:26 pm »
I am pretty new to using shaders, but I am attempting to use a shader from here:
http://www.geeks3d.com/20130705/shader-library-circle-disc-fake-sphere-in-glsl-opengl-glslhacker/4/

It is a 'fake sphere' shader. I want it to make my planet look rather nice. Right now it rotates

I have declared them as so:

const char Vertex[] =
"#version 120\n"

"void main()"
"{"
        "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
        "gl_TexCoord[0] = gl_MultiTexCoord0;"
"}";

const char Fragment[] =
"#version 120\n"

"uniform sampler2D tex0;"
"uniform vec4 bkg_color;"
"uniform float time;"
"void main(void)"
"{"
        "vec2 p = -1.0 + 2.0 * gl_TexCoord[0].xy;"
        "float r = sqrt(dot(p, p));"
        "if (r < 1.0)"
                "{"
                "vec2 uv;"
                "float f = (1.0 - sqrt(1.0 - r)) / (r);"
                "uv.x = p.x*f + time;"
                "uv.y = p.y*f + time;"
                "gl_FragColor = texture2D(tex0, uv);"
                "}"
        "else"
                "{"
                "gl_FragColor = bkg_color;"
                "}"
"}";

I loading it up like this:

sf::CircleShape planet;
sf::Texture texture;
sf::Shader m_planetShader;

m_planetShader.loadFromMemory(Vertex, Fragment);
texture.loadFromFile("assets/textures/environment/earthmap1k.jpg");
texture.setRepeated(true);

planet.setRadius(100);
planet.setOrigin(planet.getRadius(), planet.getRadius());
planet.setPosition(window.getSize().x / 2, window.getSize().y / 2);
planet.setTexture(&texture); //Is this still needed?

m_planetShader.setParameter("tex0", texture);
m_planetShader.setParameter("bkg_color", 1.0f, 0.0f, 0.0f, 1.0f); //Red as a test
m_planetShader.setParameter("time", 1.0f); //Should be able to update this later on to move the map.
 

and display is using

window.draw(planet, &m_planetShader);

Obviously with window.display() and other general uses. When it is loaded, It uses the bkg_color (red), but not the texture. Am I missing or declaring something wrong?

Thanks!

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Shader Problems.
« Reply #1 on: July 26, 2015, 01:55:10 am »
Are you setting the texture parameter before drawing or just once?
You may want to try:
shader.setParameter("tex0", sf::Shader::CurrentTexture);
if you want to set it just once.

EDIT: A minimal and complete example would help further if you're still having trouble.

EDIT2: If you use this method, yes, that line you commented on is necessary (setting the texture of the shape)
« Last Edit: July 26, 2015, 02:00:15 am by Hapax »
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Valleriani

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Shader Problems.
« Reply #2 on: July 26, 2015, 03:08:51 pm »
I wasnt able to get it working, I did change what you said but not sure if it is correct. It works without the shader though.

#include <SFML/Graphics.hpp>

const char Vertex[] =
"#version 120\n"

"void main()"
"{"
"gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
"gl_TexCoord[0] = gl_MultiTexCoord0;"
"}";

const char Fragment[] =
"#version 120\n"

"uniform sampler2D tex0;"
"uniform vec4 bkg_color;"
"uniform float time;"
"void main(void)"
"{"
"vec2 p = -1.0 + 2.0 * gl_TexCoord[0].xy;"
"float r = sqrt(dot(p, p));"
"if (r < 1.0)"
"{"
"vec2 uv;"
"float f = (1.0 - sqrt(1.0 - r)) / (r);"
"uv.x = p.x*f + time;"
"uv.y = p.y*f + time;"
"gl_FragColor = texture2D(tex0, uv);"
"}"
"else"
"{"
"gl_FragColor = bkg_color;"
"}"
"}";


int main(){
        //create window
        sf::RenderWindow window;
        sf::VideoMode mode;
        mode.height = 600;
        mode.width = 600;
        window.create(mode, "Planet");
        window.setVerticalSyncEnabled(true);
        window.setFramerateLimit(60);

        //create planet
        sf::CircleShape m_planet;
        sf::Texture m_texture;
        sf::Shader m_planetShader;

        m_texture.loadFromFile("assets/textures/environment/earthmap1k.jpg");
        m_texture.setRepeated(true);
        m_planet.setRadius(100);
        m_planet.setOrigin(m_planet.getRadius(), m_planet.getRadius());
        m_planet.setPosition(window.getSize().x / 2, window.getSize().y / 2);
        m_planet.setTexture(&m_texture);

        m_planetShader.loadFromMemory(Vertex, Fragment);
        m_planetShader.setParameter("tex0", sf::Shader::CurrentTexture);
        m_planetShader.setParameter("bkg_color", 0.0f, 0.0f, 0.0f, 1.0f);
        m_planetShader.setParameter("time", 1.0f);

        //main loop
        bool play = true;
        while (play){
                sf::Event event;
                while (window.pollEvent(event)){
                        if (event.type == sf::Event::Closed){
                                play = false;
                        }
                }
                window.clear();

                window.draw(m_planet, &m_planetShader);

                //window.draw(m_planet); //Works
                window.display();
        }

        if (window.isOpen()){
                window.close();
        }
        return 0;
}
 

Use any image to test really, the biggest thing is that the shader would be working rather then what image is used. I know the time should be updated but for now I am just using a static time.

Thanks!
« Last Edit: July 26, 2015, 03:10:51 pm by Valleriani »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Shader Problems.
« Reply #3 on: July 26, 2015, 07:55:49 pm »
Firstly, don't do this:
        window.setVerticalSyncEnabled(true);
        window.setFramerateLimit(60);

Secondly, your problem is with the vertex shader.
Changing it to match the basic one in the tutorial should give you the results you expect. (note the texture matrix)

It also works if you just load the fragment shader and leave the vertex shader thus:
m_planetShader.loadFromMemory(Fragment, sf::Shader::Fragment);
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Valleriani

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Shader Problems.
« Reply #4 on: July 26, 2015, 08:27:57 pm »
Ah! Thank you for the help! It is working good now.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Shader Problems.
« Reply #5 on: July 27, 2015, 01:09:14 pm »
You're welcome  :)

Just as a bonus. Try changing the line:
"gl_FragColor = texture2D(tex0, uv);"
to
"gl_FragColor = mix(texture2D(tex0, uv), bkg_color, r * 0.85);"
;)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Valleriani

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Shader Problems.
« Reply #6 on: July 27, 2015, 11:38:34 pm »
So far so good, I attached an image of what I have so far. Pretty much the planet, with a normal map (for those lovely bumps), and also a cloud layer that moves a little faster then the planet. Overall, it looks very cool, the image doesn't show it justice since the rotation makes it look very neat.

However, another question!

I am trying to make a kind of *glow* from the planet, I.E. a atmosphere glow. I am unsure of the best practice of this. People talk about using a 'bloom' effect but I don't think that is what I want, plus I think that takes a good portion of process time.

I was looking or thinking about a rim glow, something simple around the planet. What could be the best idea for this using shaders? Is there a quick way?

Another idea I had was wrapping the planet in a slightly larger circle, and having it wrap an image around the planet. This is something I am not sure to do because it needs to make a 'shield' like effect, rather then using a full image. I.E. See the atmosphere.png image to see the image I would wrap the planet around.


Thanks!

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 879
    • View Profile
Re: Shader Problems.
« Reply #7 on: July 28, 2015, 10:12:16 am »
The most simplicistic approach: Draw a circle where the center is transparent and the edges being opaque. But considering you're using a shader anyway, I'd say you could just add that to your actual shader, adding "fog" based on the surface normal.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Shader Problems.
« Reply #8 on: July 28, 2015, 02:15:31 pm »
Wow. The bumps look awesome!  :)

If you're going to use that atmosphere texture, you'd need a ring vertex array - something like this:

but obviously with more segments.
It's probably better to use a triangle strip than quads.
However, texturing this ring is not simple. The texture aren't guaranteed to be aligned with the outer/inner edges - they could be aligned with the side edges. Texturing this reliably would require involvement of shaders. I'm very new to shaders myself and this is one of the (most simple) problems I still haven't found a solution to: texturing a distorted quad.

People talk about using a 'bloom' effect but I don't think that is what I want
It isn't. Bloom is a way of making bright things look brighter (to simplify the idea). You don't want it to look brighter; you want to create a new object - an atmosphere haze.

Mario's shader solution sounds promising although I don't know enough about shaders to know where to begin with that. However, since the glow would expand beyond the fragments in the circle you are shading, you'd need to either apply the fog shader to the final render, or have another - larger - circle behind it and use a shader on that (to give it the gradient from the centre - similarly to the 'bonus' thing I posted earlier).
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Valleriani

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Shader Problems.
« Reply #9 on: July 28, 2015, 04:41:24 pm »
Thanks both for the advice!

I understand about the quads and how it would work. I was using a couple quads to make some engine thrust (In which it fades out) rather then using a texture like I talked about in another post. It actually came out pretty good, so I understand the concept of that (or using the tri-fan).

The shader idea seems good, but what do you mean by final render? Do you mean the last lines of the actual render? I assume its post-rendering. But I don't fully understand where I would add that if for example, it has to be added afterwards in the coding (A second shader pass?)

Yes, the atmosphere idea actually was due to your bonus, I got the idea from it :P

I will do some research on the fog and hopefully find some sort of solution, otherwise I can most likely do the second sphere in the background relatively easy. I too don't 100% know where to start on that yet.
« Last Edit: July 28, 2015, 04:42:55 pm by Valleriani »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Shader Problems.
« Reply #10 on: July 28, 2015, 04:54:23 pm »
Applying a shader to a final render would be a post-processing effect applied to the entire after it has all been drawn.
This is unlikely what you want here. In fact, I've just created a generic radial gradient shader that will do atmosphere job for you. I'm going to add it to the Wiki shortly  :)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Valleriani

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Shader Problems.
« Reply #11 on: July 28, 2015, 05:22:13 pm »
Applying a shader to a final render would be a post-processing effect applied to the entire after it has all been drawn.
This is unlikely what you want here. In fact, I've just created a generic radial gradient shader that will do atmosphere job for you. I'm going to add it to the Wiki shortly  :)

Ah okay, so that would be more like if you want glow effects on the entire scene for example. Got it.

Oh neat! I am looking forward to it!

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Shader Problems.
« Reply #12 on: July 28, 2015, 06:19:23 pm »
RadialGradient Shader

Just put a circle behind your planet and push up the 'expand' parameter to near 1 (approx 0.9f).
As in the example, use a transparent circle and set the 'color' parameter to whatever colour you'd like the atmosphere to be  :)

Hope this helps!
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Valleriani

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Shader Problems.
« Reply #13 on: July 28, 2015, 08:11:46 pm »
It's so beautiful ;) It works really well!

My final question, is about camera angle and lighting. My goal is to have a dark portion of the planet depending on where the sun is. Is it as simple as for example, having my light in the shader rotate around the planet rather then being right in front

I.E. "vec3 light_pos = normalize(vec3(0.5, 0.2, 1.0));"

I would assume when the light is off to the side or behind the planet, it will give a darkness on a certain amount of the planet. I think the biggest thing is adjusting the camera so its not static and can take some proper x/y values?

I.E. What I mean is shown in the second image.
« Last Edit: July 28, 2015, 08:20:58 pm by Valleriani »

Valleriani

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Shader Problems.
« Reply #14 on: July 28, 2015, 10:49:03 pm »
I think I got it, or at least I am pretty happy with it and going to continue with the next thing.

I ended up using a normal map with dark and light areas and pasting that over it. It can be adjusted to adjust where the sun vs where the shade is going to be, and less values typically mean more shadow.

Maybe can upload a video of it, the image doesn't serve justice when it's rotating. I made the bumps a bit more realistic now due to the way the light works on it now.

Thanks much for the help!