Image Filter Shader Create a line every 20 pixels on x axis

edited December 2016 in GLSL / Shaders

I have been playing about with trying to create a line every 20 pixels on the x axis but the mod does not equal exact zero which I dont know why. When I apply the filter to the image, it creates lines about every 20 pixels but some lines are thicker than a pixel across. I dont get any result for mod < 1 so I had to set it to mod< 1.1 to get the lines. How would I fix the code to get lines every 20 pixels that are only a pixel wide. Thanks

This is on android btw.

precision mediump float;
uniform sampler2D inputImageTexture;
varying vec2 textureCoordinate;

uniform float resX;
uniform float resY;

void main(){
    vec3 color = texture2D(inputImageTexture, textureCoordinate).rgb;

    float a = 0.0;

    if(textureCoordinate.x < 0.0){
        a = (1.0 - (textureCoordinate.x * -1.0)) * (resX/2.0);
    }else{
        a = (textureCoordinate.x * (resX/2.0)) + (resX/2.0);
    }

    float yCoord = floor(a);

    float modX = mod(yCoord, 20.0);

    if(modX < 1.1){
        color = vec3(0.4);
    }

    gl_FragColor = vec4(color, 1.0);
}

Answers

  • You know, no one really uses shaders for something as trivial as that. I don't see why you must.
    In any case, please format your code.
    Select your code, ctrl + o to indent, leave a line above and below.

  • edited December 2016

    @alex578344 --

    Is the goal to learn how to create a simple shader to learn about how shaders work (a fine goal), or is the goal to create perfect lines? I can't give feedback on your Android code specifically, but if your goal is lines, your options include:

    1. for loop through x positions, call line on x%20 == 0
    2. for loops through x/y positions, call set x%20 == 0
    3. for loop through pixels[], set on (index%width)%20 == 0
    4. a shader

    If speed is a major concern, I believe (?) these are sorted roughly slowest-to-fastest. However, #1 is certainly the easiest code to read and understand -- it does what you say you want to do directly in idiomatic Processing by calling line.

  • @jeremydouglass Huh? I'm pretty sure he means to use a shader. It is mentioned in the question.

  • The mod will be fractional if ycoord is fractional.

    And I don't understand what ycoord is (it's based on x so why ycoord?), or why you are using a texture at all.

    to get a line every 20 pixels you just need something like

    varying vec4 vertColor;     // incoming colour
    
    void main() {
      if (mod(gl_FragCoord.x, 20) == 0) {
        // grey
        gl_FragColor = vec3(0.4);
      } else {
        // no change
        gl_FragColor = vertColor;
      }
    }
    // untested
    

    vertColor is the colour you are setting the pixel. it uses this except when the x coord of the pixel (not texel) is a multiple of 20.

    and to get the (frag) shader to run, copy the image to the screen, using image(img, 0, 0, width, height) or something

  • edited December 2016

    @koogs This is a texture shader. I can only use the mod function with floats so when I use ints as the parameters it doesnt work. Then when I change the ints to floats the same problem happens when I run it as my code. The mod(xCoord, 20.0) leaves me with a fractional answer and not a integer.?? The only way I can go around it is rounding down or up and then some of the lines are thicker than others.

  • Answer ✓

    I know it's a texture shader - I read the code.

    But I'm saying that for your goal to "create a line every 20 pixels on the x axis" you don't need a texture shader and a simple frag shader will do it.

    Unless, of course, that isn't the whole story.

    Maybe post a complete, runnable example.

Sign In or Register to comment.