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

Author Topic: Drawing a vertex array with a variable alpha level? .NET  (Read 3755 times)

0 Members and 1 Guest are viewing this topic.

XGLSuper

  • Newbie
  • *
  • Posts: 4
    • View Profile
Drawing a vertex array with a variable alpha level? .NET
« on: May 24, 2015, 12:00:32 am »
I am drawing my map with mutliple vertex arrays. The ground is drawn before the player, then the player, then anything that should be rendered on top of a player, such as tree leaves, or an archway or something.

I want to make it so that when you walk under the tree leaves it makes them slightly transparent so you can see your player and what you are walking on. I have read a lot about having to use shaders but I don't know a single thing about them. I don't feel like I can change the color of every vertex because I only want the layer to be transparent if you are underneath something. Can someone explain how this could be done?

It would be optimal if I could make it so like within a radius the layer becomes transparent, but the whole layer would be fine as well if it comes to it.

I am using C# so it's hard to make sense of the documentation, when I have no clue as to what shaders are to begin with. So please explain very thoroughly if you can.

dabbertorres

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • website/blog
Re: Drawing a vertex array with a variable alpha level? .NET
« Reply #1 on: May 24, 2015, 01:29:57 am »
Forgive me if I'm oversimplifying the problem, but couldn't you just make the color value of the vertices in your VertexArray that are close to your player semi-transparent? I don't think you'd need a shader for this.

XGLSuper

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Drawing a vertex array with a variable alpha level? .NET
« Reply #2 on: May 24, 2015, 05:30:08 am »
The only problem with that is that it will end up like a minecraft circle, made of blocks and not smooth. Even if it gets smooth corner transitions it will be blocky. I also want to use shaders other times, and figured this would be a very simple tutorial for them, and possibly the best looking method of what I want

Sub

  • Full Member
  • ***
  • Posts: 159
    • View Profile
Re: Drawing a vertex array with a variable alpha level? .NET
« Reply #3 on: May 24, 2015, 06:19:58 am »
This might not look that great, but you could calculate a radius around the player, and make any vertices which fall in that radius semi-transparent while keeping those outside non-transparent.  You should get a smooth gradient between verts of different colors, check out the triangle on this page.

http://www.sfml-dev.org/tutorials/2.1/graphics-vertex-array.php

I'm not sure where there's a good / comprehensive shader tutorial
« Last Edit: May 24, 2015, 06:23:32 am by Sub »

XGLSuper

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Drawing a vertex array with a variable alpha level? .NET
« Reply #4 on: May 24, 2015, 06:53:11 am »
It would be smooth while standing still, but if you walked over to the next block it would make it just jump over, instead of following the player, which I have heard can be done with shaders.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Drawing a vertex array with a variable alpha level? .NET
« Reply #5 on: May 24, 2015, 11:38:54 pm »
You can do this with render textures and blend modes but it could get a bit complicated.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Lee R

  • Jr. Member
  • **
  • Posts: 86
    • View Profile
Re: Drawing a vertex array with a variable alpha level? .NET
« Reply #6 on: May 25, 2015, 03:04:26 am »
Nobody is going to teach you how to program shaders in a forum post :P Don't mind whipping one up though:

bool CreateCutoutEffect(sf::Shader& InShader, float InRadius, float InSharpness)
{
    // Vertex shader.
    const char* Vs = R"(
        varying vec2 v_Position;
        void main()
        {
            v_Position = (gl_ModelViewMatrix * gl_Vertex).xy;
            gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
        })"
;

    // Fragment shader.
    const char* Fs = R"(
        uniform sampler2D u_Texture;
        uniform float     u_Radius;
        uniform float     u_Sharpness;
        uniform vec2      u_Origin;
        varying vec2      v_Position;
        void main()
        {
            vec2 To = v_Position - u_Origin;
            float Percent = dot(To, To) / (u_Radius * u_Radius);
            float Modulation = smoothstep(u_Sharpness, 1.0, Percent);
            vec4 Color = texture2D(u_Texture, gl_TexCoord[0].st);
            gl_FragColor = vec4(Color.rgb, Color.a * Modulation);
        })"
;

    bool Result = InShader.loadFromMemory(Vs, Fs);

    if (Result)
    {
        InShader.setParameter("u_Texture", sf::Shader::CurrentTexture);
        InShader.setParameter("u_Radius", InRadius);
        InShader.setParameter("u_Sharpness", InSharpness);
    }

    return Result;
}
 

Only thing you have to do is update the view-space uniform u_Origin whenever your player moves (e.g. shader.setParameter("u_Origin", PlayerPosition). Being in view space means that you'll need to transform the parameter (i.e. PlayerPosition) by the render target's view. The sharpness parameter is in the range [0.0, 1.0] and defines how sharply the circle fades out at the edge.

Doing it with a RenderTexture would be equally simple. You'd just need to clear the render texture with an alpha of 0, render all the to-be-faded elements, then, with alpha blending turned off, render something that has an alpha of (for example) 0 over the area you want faded out, and finally render said RenderTexture over the screen.

EDIT: Totally forgot the whole .NET thing. It should be pretty much identical though.
« Last Edit: May 25, 2015, 03:18:02 am by Lee R »