Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: Newbie question about moving a selected number of pixels

  1. #1
    Intern Contributor
    Join Date
    Sep 2016
    Posts
    75

    How can I move pixels of a particular color and leave the others in place?

    I know how to draw shapes, move, and deform them by modifying the uv coordinates:

    Code :
     
    // Code moves a circle to the right of the screen...
     
    void main () {
     
        vec2 uv     = gl_FragCoord.xy / screen.xy;
        vec4 tex2D  = texture2D(sampler, u_texCoords);
        uv.x        *= screen.x / screen.y; // aspect ratio
     
        vec4 color = vec4(0.0);
     
        uv -= 0.5;
     
        uv -= vec2(0.3, 0.0);
        float d = length(uv);
        color.a = smoothstep(0.3 - 0.01, 0.3, d);
        gl_FragColor = color;
     
    }

    I needed to modify the texture UV in order to move it, I can move and warp the image, but now the only thing left is to move particular pixel colors. I pass in the modified texture UV before calling texture2D which gives me the color vec4.



    What if I want to move all the green elements and leave the rest in the same place? I'm clearly not understanding something. Below I'll share the code I've tried so far, I've removed some of the code so it's not as long, but this covers the mug portion of the drawing. Thanks in advance, hope I made sense.

    Code :
     
    void main () {
     
        vec2 uv     = gl_FragCoord.xy / screen.xy;
        vec2 ndc    = vec2(uv.x * 2.0 - 1.0, uv.y * 2.0 - 1.0);
     
     
        uv.x        *= screen.x / screen.y; // aspect ratio
        uv -= 0.5;
     
        vec2 texCoords = u_texCoords;
        texCoords -= vec2(0.2, 0.2); // It moves :) But how can I move based on color?
     
        vec4 tex2D  = texture2D(sampler, texCoords);
     
        gl_FragColor = Paint(uv, tex2D);
     
    }


    I would have done something similar to this:

    Code :
    vec4 Paint (vec2 uv, vec4 tex) {
     
        vec4 color = vec4(0.0);
     
        if (tex.r == (223.0 / 255.0) && tex.g == (242.0 / 255.0) && tex.b == (247.0 / 255.0) && tex.a == 1.0) {
     
            uv -= vec2(0.4, 0.0); // nothing happens
     
            color.a = 1.0;
        }
     
        return color;
    }

    I'm able to replace colors I choose with another color, but this won't work for moving those particular pixels.
    Last edited by hashbrown; 11-03-2017 at 01:10 PM.

  2. #2
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,474
    Quote Originally Posted by hashbrown View Post
    What if I want to move all the green elements and leave the rest in the same place?
    Upon entry to the fragment shader, the destination fragment coordinates are already determined.

    If you're moving the pixels by a fixed distance, then you need to sample the texture at a point which is that distance in the opposite direction. If the colour matches (use the distance() function rather than equality checks) then write it to gl_FragColor; otherwise sample the texture at the original texture coordinates and write that value to gl_FragColor.

    If you're moving by a distance which depends upon the source value, then a fragment shader may not be a suitable approach, as you'd have to test multiple pixels until you find one which ends up at the destination coordinates. Another option is to use imageStore within a compute shader (but note that unlike a fragment shader, there's no guarantee that each pixel will be written exactly once; some pixels may be written several times, some may not be written at all).

  3. #3
    Intern Contributor
    Join Date
    Sep 2016
    Posts
    75
    Quote Originally Posted by GClements View Post
    Upon entry to the fragment shader, the destination fragment coordinates are already determined.

    If you're moving the pixels by a fixed distance, then you need to sample the texture at a point which is that distance in the opposite direction. If the colour matches (use the distance() function rather than equality checks) then write it to gl_FragColor; otherwise sample the texture at the original texture coordinates and write that value to gl_FragColor.

    If you're moving by a distance which depends upon the source value, then a fragment shader may not be a suitable approach, as you'd have to test multiple pixels until you find one which ends up at the destination coordinates. Another option is to use imageStore within a compute shader (but note that unlike a fragment shader, there's no guarantee that each pixel will be written exactly once; some pixels may be written several times, some may not be written at all).
    GC, thanks, I'm clear now

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •