Shader_offset_help

Discussion in 'Programming' started by Gun_Goose, Jul 15, 2019.

  1. Gun_Goose

    Gun_Goose Member

    Joined:
    May 25, 2018
    Posts:
    14
    Hi, I am trying to implement a 3D fog of war shader (i have been struggling with this for a while). I have tried to build one from scratch as well as implement on I got off the market place and each time, I have run into a similar problem. I am able to create the proper effect, however the the light is not center on the position of the character I pass it (it even follows the character, expect seems to move a different ). I think it might be a problem with the fact that I am drawing everything with a matrix, and the positions would not line up, but I am not sure anymore. Any ideas?
    miss_aligned_shader.JPG
    The current shader I am testing is one I found on the market place:
    vertex:

    Code:
    //
    // Simple passthrough vertex shader
    //
    attribute vec4 in_Position;
    //attribute vec3 in_Normal;
    attribute vec4 in_Colour;
    attribute vec2 in_TextureCoord;
    varying vec2 v_vTexcoord;
    varying vec4 v_vColour;
    varying vec4 WorldPos;
    void main()
    {
        gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * in_Position;
        WorldPos = gm_Matrices[MATRIX_WORLD] * in_Position;
        v_vColour = in_Colour;
        v_vTexcoord = in_TextureCoord;
    }
    Fragment:
    Code:
    //
    // Simple passthrough fragment shader
    //
    varying vec2 v_vTexcoord;
    varying vec4 v_vColour;
    varying vec4 WorldPos;
    uniform vec3 u_fog_colour; //Red, Green, Blue
    uniform vec3 u_fog_height; //Z near, Z height, Falloff
    uniform vec3 u_camera_position; //Cameras X, Y, Z
    void main()
      {
        vec4 base = texture2D(gm_BaseTexture, v_vTexcoord);
      
        float dist = length(WorldPos.xyz - u_camera_position);   
        float fog = u_fog_height.z * smoothstep(u_fog_colour.z, u_fog_height.x, u_fog_height.y - WorldPos.z);
      
        float ext = exp2(-dist * fog);
        vec3 finalColor = base.rgb * vec3(ext,ext,ext) + u_fog_colour.rgb * (1.0 - ext);
      
        gl_FragColor = /*v_vColour * */vec4(finalColor, 1.0);
    }
    Here is also how I am calling the shader in the post draw event:
    Code:
    shader_set(sh_fog_try);
    shader_color = shader_get_uniform(sh_fog_try, "u_fog_colour")
    shader_height = shader_get_uniform(sh_fog_try, "u_fog_height")
    shader_pos = shader_get_uniform(sh_fog_try, "u_camera_position")
    
    
    
    shader_set_uniform_f(shader_color, 0, 0, 0);
    shader_set_uniform_f(shader_height, 100, 25, 0.04);
    shader_set_uniform_f(shader_pos, p_x, p_y, p_z);
    
    
    draw_surface(application_surface,0,0)
    shader_reset()
    
    p_x, p_y, p_z are the characters coordinate. I have also tried switching them for the coordinates of my camera object but ended up with the same result.
     
  2. flyingsaucerinvasion

    flyingsaucerinvasion Member

    Joined:
    Jun 20, 2016
    Posts:
    2,240
    I notice sometihng strange. You've got a vec4 in_Position attribute. Usually they are vec3. Have you wrote a w component to your vertex position attributes in your vertex buffer? If so, it must have a value of 1 to work with this shader. But why does the in_Position attribute have 4 components in the first place?

    The arguments in the smoothstep function don't make sense to me.

    Did you pay money for that shader?
     
  3. Gun_Goose

    Gun_Goose Member

    Joined:
    May 25, 2018
    Posts:
    14
    I did not pay money for the shader, it was free on the asset store. I was using it to test to see if the problem was that I was passing it coordinates wrong. I have a simpler shader that I better understand which is supposed to accomplish a similar foggy effect. (i think it might be easier to troubleshoot) (I posted it below). It has a similar problem where it is off center. other_shader.JPG

    However, after playing with it for a while. I think the problem might be with the fact I am using a surface and that it would be utilizing GUI coordinates. For instance, when currently drawing it like:


    Code:
    shader_set(sh_spooky)
    
    
    shader_pos = shader_get_uniform(sh_spooky, "pos")
    shader_rad = shader_get_uniform(sh_spooky, "rad")
     
    shader_set_uniform_f(shader_pos, p_x, p_y, p_z)
    shader_set_uniform_f(shader_rad, rad)
    
    
    draw_surface(application_surface,0,0)
    
    shader_reset()
    

    in the post draw event after disabling application surface in the create event. However, when I change p_x and p_y to display_get_gui_width()/2 and display_get_gui_height()/2 respectively, the shader looks like:
    centered_shader.JPG

    It looks much closer to how I want it. Although I am not sure how I would change 3d coordinates into GUI coordinates. Aren't GUI coordinates 2d?

    Shader:
    Vertex:

    Code:
    //
    // Simple passthrough vertex shader
    //
    attribute vec3 in_Position;                  // (x,y,z)
    //attribute vec3 in_Normal;                  // (x,y,z)     unused in this shader.
    attribute vec4 in_Colour;                    // (r,g,b,a)
    attribute vec2 in_TextureCoord;              // (u,v)
    
    varying vec2 v_vTexcoord;
    varying vec4 v_vColour;
    varying vec3 v_vPosition;
    varying vec3 v_vWorld;
    
    
    uniform vec3 pos;
    uniform float rad;
    
    void main()
    {
          
        vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0);
        gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos;
       
        
        v_vColour = in_Colour;
        v_vTexcoord = in_TextureCoord;
        v_vPosition = in_Position;
        
        
        v_vWorld = (gm_Matrices[MATRIX_WORLD] * object_space_pos).xyz;
    }
    
    
    Fragment:
    Code:
    //
    // Simple passthrough fragment shader
    //
    varying vec2 v_vTexcoord;
    varying vec4 v_vColour;
    varying vec3 v_vPosition;
    varying vec3 v_vWorld;
    
    
    uniform vec3 pos;
    uniform float rad;
    
    
    
    void main()
    {
    
        vec4 base_col = v_vColour * texture2D(gm_BaseTexture, v_vTexcoord);
        gl_FragColor = vec4(base_col.rgb, base_col.a*(100.0/(distance(pos,v_vWorld))));
    }
    
    
     
  4. flyingsaucerinvasion

    flyingsaucerinvasion Member

    Joined:
    Jun 20, 2016
    Posts:
    2,240
    If you want the effect to be 3d, you'll want to apply the shader as you draw everything in your world.
     
  5. Gun_Goose

    Gun_Goose Member

    Joined:
    May 25, 2018
    Posts:
    14
    You are right! It worked! I am using the SMF 3d model system I got off the asset store. Once I found out where it was drawing the models, I applied the shader. I tried both shaders and they were properly centered. Thanks!

    working shader.JPG
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice