SCREEN_TEXTURE : hint_screen_texture
This thing captures the entire screen, even what is outside the game window and it is very annoying, I only need what is in the window.

  • Megalomaniak replied to this.
  • kSarkans maybe there is an easier way idk...

    Of course there is. No need for any of that black magic 🙂, and all the relevant parameters are already there in built-ins. So just transform the object center into screen UV space and scale the UV coordinate around it:

    shader_type canvas_item;
    
    uniform sampler2D screen: hint_screen_texture;
    uniform float magFactor = 2.0;
    varying vec2 center;
    
    void vertex(){
    	center = (CANVAS_MATRIX * MODEL_MATRIX[3]).xy;
    }
    
    void fragment(){
    	vec2 centerUV = center * SCREEN_PIXEL_SIZE;
    	COLOR = texture(screen, (SCREEN_UV - centerUV) / magFactor + centerUV);
    }

    Btw you should rephrase your question to "How to make a magnifying glass shader" to make up for the xy problem situation 😉

    kSarkans I feel like this can probably be reported to the issue tracker, though try and search first. An opened issue might already exist.

    I don't think there IS a window texture to read from. Godot would have to write to it, which it isn't doing because it's already writing those pixels to the screen texture.

    What exactly are you trying to do and what is the issue you're having? There's surely a way to transform your UVs to just the rect portion of SCREEN_TEXTURE that you want.

      award Im trying to do a properly working magnifying glass.

      I found the best, in my opinion, shader from the Internet

      shader_type canvas_item;
      
      uniform vec2 tiling = vec2(1,1); 
      uniform vec2 offset = vec2(0,0);
      uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, repeat_enable, filter_linear_mipmap;
      
      void fragment()
      {
      	
      	vec4 color = texture(SCREEN_TEXTURE, SCREEN_UV * tiling + offset);
      	color.a = texture(TEXTURE, UV).a;
      	COLOR = color;
      }

      But since it does not work correctly without a script (the offset must be adjusted to the object on which the shader is applied), I had to look for a very long time to find the formula by which the offset will change.

      form_x = ((magnifier.position.x + magnifier.size.x/2) / (DisplayServer.window_get_size().x / (1.0-mat.get_shader_parameter("tiling").x)) )
      form_y = ((magnifier.position.y + magnifier.size.y/2) / (DisplayServer.window_get_size().y / (1.0-mat.get_shader_parameter("tiling").y)) )
      mat.set_shader_parameter("offset", Vector2(form_x, form_y))

      It works great, with one exception: if you resize the window or make the window fullscreen, the offset immediately starts to work incorrectly.

      Click to reveal Click to hide



      award and the reason of these bugs is my screen, which resolution isnt equals window's resolution. I'm too tired to look for new formulas, so the WINDOW_TEXTURE is the most easiest way. But as I understand, it is extremely difficult to make it, because it does not exist by default as SCREEN_TEXTURE

      maybe there is an easier way idk...

      • xyz replied to this.

        kSarkans maybe there is an easier way idk...

        Of course there is. No need for any of that black magic 🙂, and all the relevant parameters are already there in built-ins. So just transform the object center into screen UV space and scale the UV coordinate around it:

        shader_type canvas_item;
        
        uniform sampler2D screen: hint_screen_texture;
        uniform float magFactor = 2.0;
        varying vec2 center;
        
        void vertex(){
        	center = (CANVAS_MATRIX * MODEL_MATRIX[3]).xy;
        }
        
        void fragment(){
        	vec2 centerUV = center * SCREEN_PIXEL_SIZE;
        	COLOR = texture(screen, (SCREEN_UV - centerUV) / magFactor + centerUV);
        }

        Btw you should rephrase your question to "How to make a magnifying glass shader" to make up for the xy problem situation 😉

          kSarkans changed the title to How to make a magnifying glass shader .

          xyz can't believe it can be MUCH easier 🤦‍♂️

          Anyway, it turns out a little inaccurate without the offset. It already depends on the size of the viewport, so this will be easier to fix. As a last resort, i can leave everything as is, because the deviation is small.

          COLOR = texture(screen, (SCREEN_UV - centerUV) / magFactor + centerUV);

          COLOR = texture(screen, (SCREEN_UV - centerUV) / magFactor + centerUV + vec2(0.025, 0.033));

          0.025/0.033 is very close to 3/4 (game aspect ratio), so then... Otherwise, that is another story 🙂

          Many thanks for help 🙏

          • xyz replied to this.

            kSarkans I don't get any inaccuracies. In any case, it's not a good idea to hardcode offsets like this because the same numbers will result in a different offset when you change the resolution. If you need to offset it for a fraction of a pixel, use SCREEN_PIXEL_SIZE. It gives you the pixels size in normalized 0-1 screen space which coincides with UV space.

            kSarkans changed the title to How to make a properly working magnifying glass shader .