I need some help as I am still learning shaders. I am attempting to convert a canvas_item shader to a spatial shader specifically a screen spatial shader like in Advanced Post Processing where you use a Quad and in the vertex() you move it to stay always in front of the camera. The one part I can not solve exactly is trying to get the normalized coordinates as the shader states. I am also using Compatibility renderer GLES3.
This is the shader: https://www.shadertoy.com/view/Ms2SWW
In an attempt to get the normalized coordinates I tried:
vec2 pixel_coords = (2.0 * FRAGCOORD.xy - VIEWPORT_SIZE.xy) / VIEWPORT_SIZE.y;
I also tried using:
vec3 ndc = vec3(SCREEN_UV, depth) * 2.0 - 1.0;
and extracting the x and y to be the pixel coords but that did not work.
I also tried using:

vec4 view = INV_PROJECTION_MATRIX * vec4(ndc, 1.0);
view.xyz /= view.w;

But the x and y also did not work.
Further I tried:
vec4 world = INV_VIEW_MATRIX * INV_PROJECTION_MATRIX * vec4(ndc, 1.0);
and
vec3 world_position = world.xyz / world.w;
But none of these will allign the image correctly.
If you have the time for help I would really appreciate it, and further if you might describe what it is that I am missing in the conversion here.

Shader Malfunction is As Follows:

shader_type spatial;
#define SHAPE 0
uniform sampler2D tunnel_tex;
void vertex() {
    POSITION = vec4(VERTEX.xy, 1.0, 1.0);
}

void fragment() {
    // normalized coordinates
    vec2 pixel_coords = (2.0 * FRAGCOORD.xy - VIEWPORT_SIZE.xy) / VIEWPORT_SIZE.y;
    
    float angle_of_pixel_to_center = atan(pixel_coords.x, pixel_coords.y);
    #if SHAPE==0
    float radius_to_pixel = length(angle_of_pixel_to_center);
    #else  
    vec2 squared_coordinates = angle_of_pixel_to_center * angle_of_pixel_to_center;
    vec2 coordinates_to_the_4th = squared_coordinates * squared_coordinates;
    vec2 coordinates_to_the_8th = coordinates_to_the_4th * coordinates_to_the_4th;
    float radius_to_pixel = pow(coordinates_to_the_8th.x + coordinates_to_the_8th.y, 1.0/8.0);
    #endif
    // index texture by radious and angle
    vec2 tex_uv = vec2(0.3 / radius_to_pixel + 0.01 * TIME, angle_of_pixel_to_center / PI);
    // fetch color with correct texture gradients to prevent discontinutity
    vec2 corrected_tex_uv = vec2(tex_uv.x, atan(pixel_coords.y, abs(pixel_coords.x)) / PI);
    vec3 base_color = textureGrad(tunnel_tex, tex_uv, dFdx(corrected_tex_uv), 
        dFdy(corrected_tex_uv)).xyz;
    // darken at the center
    vec3 final_color = base_color * radius_to_pixel;
    ALBEDO = final_color;
}

Also I failed to even make it into a canvas_item shader, so that is likely the underlying problem with my understanding.

shader_type canvas_item;
//Broken For now.
// Based on Deform Tunnel Square or Circular by iq https://www.shadertoy.com/view/Ms2SWW
//Original is MIT License

// 0 : circular
// 1 : squareish
#define SHAPE 0

uniform sampler2D tunnel_tex;

void vertex() {
}

void fragment() {
    // normalized coordinates
//https://docs.godotengine.org/en/stable/tutorials/shaders/converting_glsl_to_godot_shaders.html#id2
    vec2 iResolution = 1.0 / SCREEN_PIXEL_SIZE;
    vec2 pixel_coords = (2.0 * FRAGCOORD.xy - iResolution) / iResolution.y;

    float angle_of_pixel_to_center = atan(pixel_coords.x, pixel_coords.y);
    #if SHAPE==0
    float radius_to_pixel = length(angle_of_pixel_to_center);
    #else  
    vec2 squared_coordinates = angle_of_pixel_to_center * angle_of_pixel_to_center;
    vec2 coordinates_to_the_4th = squared_coordinates * squared_coordinates;
    vec2 coordinates_to_the_8th = coordinates_to_the_4th * coordinates_to_the_4th;
    float radius_to_pixel = pow(coordinates_to_the_8th.x + coordinates_to_the_8th.y, 1.0/8.0);
    #endif
    // index texture by radious and angle
    vec2 tex_uv = vec2(0.3 / radius_to_pixel + 0.1 * TIME, angle_of_pixel_to_center / PI);
    // fetch color with correct texture gradients to prevent discontinutity
    vec2 corrected_tex_uv = vec2(tex_uv.x, atan(pixel_coords.y, abs(pixel_coords.x)) / PI);
    vec3 base_color = textureGrad(tunnel_tex, tex_uv, dFdx(corrected_tex_uv), 
        dFdy(corrected_tex_uv)).xyz;
    // darken at the center
    vec3 final_color = base_color * radius_to_pixel;
    COLOR = vec4(final_color, 1.0);
}
  • xyz replied to this.

    WolfRage SCREEN_UV are normalized pixel coordinates.

      xyz Thank you for replying.
      I forgot to mention I actually started with SCREEN_UV. Unfortunately it results in this:

      If you have more ideas please let me know. Thank you for your time.

      shader_type spatial;
      //Broken For now.
      // Based on Deform Tunnel Square or Circular by iq https://www.shadertoy.com/view/Ms2SWW
      //Original is MIT License
      
      // 0 : circular
      // 1 : squareish
      #define SHAPE 0
      
      uniform sampler2D tunnel_tex;
      
      void vertex() {
          POSITION = vec4(VERTEX.xy, 1.0, 1.0);
      }
      
      void fragment() {
          // normalized coordinates
          vec2 pixel_coords = SCREEN_UV;
      
          float angle_of_pixel_to_center = atan(pixel_coords.x, pixel_coords.y);
          #if SHAPE==0
          float radius_to_pixel = length(angle_of_pixel_to_center);
          #else  
          vec2 squared_coordinates = angle_of_pixel_to_center * angle_of_pixel_to_center;
          vec2 coordinates_to_the_4th = squared_coordinates * squared_coordinates;
          vec2 coordinates_to_the_8th = coordinates_to_the_4th * coordinates_to_the_4th;
          float radius_to_pixel = pow(coordinates_to_the_8th.x + coordinates_to_the_8th.y, 1.0/8.0);
          #endif
          // index texture by radious and angle
          vec2 tex_uv = vec2(0.3 / radius_to_pixel + 0.01 * TIME, angle_of_pixel_to_center / PI);
          // fetch color with correct texture gradients to prevent discontinutity
          vec2 corrected_tex_uv = vec2(tex_uv.x, atan(pixel_coords.y, abs(pixel_coords.x)) / PI);
          vec3 base_color = textureGrad(tunnel_tex, tex_uv, dFdx(corrected_tex_uv), 
              dFdy(corrected_tex_uv)).xyz;
          // darken at the center
          vec3 final_color = base_color * radius_to_pixel;
          ALBEDO = final_color;
      }

        WolfRage Wait a second this may be my fault. Double checking myself.

          WolfRage Okay double checked myself and nope, it still does not work.

          • xyz replied to this.

            WolfRage How do you know the problem is normalized pixel coordinates? Try to output SCREEN_UV directly to pixel color to check that this part indeed works.

              xyz You are getting me thinking which I really appreciate.
              So in the spatial shader I converted this line to the uncommneted line below.

              //vec2 tex_uv = vec2(0.3 / radius_to_pixel + 0.01 * TIME, angle_of_pixel_to_center / PI);
                  vec2 tex_uv = vec2(SCREEN_UV.x, SCREEN_UV.y);

              Which produced:

              Now I am thinking about what we have here and what the implications are.

                WolfRage
                So by changing the code in the canvas_item shader to simply be:
                vec3 base_color = texture(tunnel_tex, UV).xyz;
                COLOR = vec4(base_color, 1.0);

                I can 1 for 1 map the texture. If instead we right
                vec3 base_color = texture(tunnel_tex, SCREEN_UV).xyz;
                Then the texture maps to the screen relative to the texture, screen moves but texture remains.
                But how to work backwards from here, is beyond me. Going to walk away for a few and think.

                In the end I achieved a similiar effect by using a video by Fencer Dev. So hats off to him for his tutorial that lined up with what I was trying to do. Also thank you to xyz for trying to help me out. Now I am off to convert the effect to a spatial shader.
                This was the video that helped me out:

                WolfRage changed the title to [SOLVED]Help Converting Shader Toy to Spatial Screen Shader .