bug in colorRange shader

edited April 2014 in GLSL / Shaders

I get the following error with a shader i made: OpenGL error 1282 at top endDraw(): invalid operation

First i will show what i want to do (basically a threshold shader with a color as input):

input: img2

output (mouseDrag is depending) Screen Shot 2014-04-14 at 3.59.02 PM

PImage img;

color targetColor = color(250, 0, 0);
float fuzziness = 0.5;


void setup() {
  img = loadImage("img2.png");
  size(img.width, img.height);

  img.loadPixels();

  //noLoop();
}

// . . . . . . . . . . . . . . .

void draw() {
  image(img, 0, 0);

  int x, y;
  float v;

  if (!keyPressed) {
    for (int i = 0; i < img.pixels.length; i++) {
      x = i % img.width;
      y = (i - x) / img.width;

      v = colorInRangeValue(img.pixels[i], targetColor, fuzziness);

      if (v > 0) {
        set(x, y, color(v*255));
      }
      else {
        set(x, y, color(0));
      }
    }
  }
}

// . . . . . . . . . . . . . . .

void mouseClicked() {
  targetColor = get(mouseX, mouseY);
  println(red(targetColor)+"\t"+green(targetColor)+"\t"+blue(targetColor));
}

// . . . . . . . . . . . . . . .

void mouseDragged() {
  fuzziness = constrain(norm(mouseX, 0, width), 0, 1);
  println(fuzziness);
}

// . . . . . . . . . . . . . . .

// returns a value between 0 and 1
float colorInRangeValue(color colorToTest, color targetColor, float fuzziness) {
  // version 03

  if (fuzziness == 0) {
    return  colorToTest == targetColor ?  1 : 0;
  }

  float targetRed = red(targetColor);
  float targetGreen = green(targetColor);
  float targetBlue = blue(targetColor);

  float maxOffset = 255*fuzziness;

  float minR = targetRed-maxOffset;
  float maxR = targetRed+maxOffset;
  float minG = targetGreen-maxOffset;
  float maxG = targetGreen+maxOffset;
  float minB = targetBlue-maxOffset;
  float maxB = targetBlue+maxOffset;

  /*
  minR = constrain(minR, 0, 255);
   maxR = constrain(minR, 0, 255);
   minG = constrain(minR, 0, 255);
   maxG = constrain(minR, 0, 255);
   minB = constrain(minR, 0, 255);
   maxB = constrain(minR, 0, 255);
   */

  float r = red(colorToTest);
  float g = green(colorToTest);
  float b = blue(colorToTest);

  if (r >= minR && r <= maxR && g >= minG && g <= maxG && b >= minB && b <= maxB ) {



    // 0 ---------------------------------------------------------- 255
    //                      ^ targetColor   ^ colorToTest
    //    ^ minR                             ^maxR
    //    0                 1                0

    // value red, value green, value blue
    float vr, vg, vb;

    if (r >= targetRed) {
      vr = norm(r, maxR, targetRed);
    }
    else {
      vr = norm(r, minR, targetRed);
    }

    if (g >= targetGreen) {
      vg = norm(g, maxG, targetGreen);
    }
    else {
      vg = norm(g, minG, targetGreen);
    }

    if (b >= targetBlue) {
      vb = norm(b, maxB, targetBlue);
    }
    else {
      vb = norm(b, minB, targetBlue);
    }

    float m = min(vr, vg);
    m = min(m, vb);
    return m < 0 ? 0 : m;
  }
  return 0;
} 


// . . . . . . . . . . . . . . . . .

Here is my attempt to create a shader out of it:

PShader colorRange;
PImage img;

void setup() {

  img = loadImage("img2.png");
  size(img.width, img.height, P2D);
  colorRange = loadShader("colorRange.glsl");

 colorRange.set("targetColor", new PVector(1.0, 0.0, 0.0)); 

  stroke(255, 0, 0);
  rectMode(CENTER);
}

void draw() {

  colorRange.set("fuzziness", norm(mouseX, 0, width));

  filter(colorRange);
  image(img, 0, 0);

}

colorRange.glsl

#define PROCESSING_TEXTURE_SHADER

uniform sampler2D texture;
varying vec4 vertTexCoord;
uniform float fuzziness;
uniform vec4 targetColor;

float minR, maxR, minG, maxG, minB, maxB;


float norm(float value, float start, float stop) {
    return (value - start) / (stop - start);
  }

void main() {

  minR = targetColor.r-fuzziness;
  maxR = targetColor.r+fuzziness;
  minG = targetColor.g-fuzziness;
  maxG = targetColor.g+fuzziness;
  minB = targetColor.b-fuzziness;
  maxB = targetColor.b+fuzziness;

  vec4 texColor = texture2D(texture, vertTexCoord.st).rgba;

  if (fuzziness == 0.0) {
    gl_FragColor = texColor == targetColor ? vec4(1.0, 1.0, 1.0, 1.0) : vec4(0.0, 0.0, 0.0, 1.0);
  }
  else {
    if ( texColor.r >= minR && texColor.r <= maxR && texColor.g >= minG && texColor.g <= maxG && texColor.b >= minB && texColor.b <= maxB ) {

      // value red, value green, value blue
      float vr, vg, vb;

      if (texColor.r >= targetColor.r) {
        vr = norm(texColor.r, maxR, targetColor.r);
      }
      else {
        vr = norm(texColor.r, minR, targetColor.r);
      }

      if (texColor.g >= targetColor.g) {
        vg = norm(texColor.g, maxG, targetColor.g);
      }
      else {
        vg = norm(texColor.g, minG, targetColor.g);
      }

      if (texColor.b >= targetColor.b) {
        vb = norm(texColor.b, maxB, targetColor.b);
      }
      else {
        vb = norm(texColor.b, minB, targetColor.b);
      }

      float m = min(vr, vg);
      m = min(m, vb);
      gl_FragColor = m < 0.0 ?  vec4(0.0, 0.0, 0.0, 1.0) : vec4(m, m, m, 1.0);
    }
    else {
     gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
    }
  }
}

I hope someone can help.

Answers

  • finally :D

    PShader colorRange;
    PImage img;
    
    void setup() {
    
      img = loadImage("img2.png");
      size(img.width, img.height, P2D);
      colorRange = loadShader("colorRange.glsl");
    
     colorRange.set("targetColor", 1.0, 0.0, 0.0, 1.0); 
    
      stroke(255, 0, 0);
      rectMode(CENTER);
    }
    
    void draw() {
    
      colorRange.set("fuzziness", constrain(norm(mouseX, 0, width), 0.0, 1.0));
    
      if(keyPressed) {
        resetShader();
      }
      else {
        shader(colorRange);
      }
      image(img, 0, 0);
    
    }
    

    the shader file:

    #define PROCESSING_TEXTURE_SHADER
    
    uniform sampler2D texture;
    varying vec4 vertTexCoord;
    uniform float fuzziness;
    uniform vec4 targetColor;
    
    float minR;
    float maxR;
    float minG;
    float maxG;
    float minB;
    float maxB;
    
    
    float norm(in float value, in float start, in float stop) {
        return (value - start) / (stop - start);
    }
    
    void main() {
    
    
      minR = max(0.0, targetColor.r-fuzziness);
      maxR = min(1.0, targetColor.r+fuzziness);
      minG = max(0.0, targetColor.g-fuzziness);
      maxG = min(1.0, targetColor.g+fuzziness);
      minB = max(0.0, targetColor.b-fuzziness);
      maxB = min(1.0, targetColor.b+fuzziness);
    
      vec4 texColor = texture2D(texture, vertTexCoord.st).rgba;
    
      float vr;
      float vg;
      float vb;
    
      vr = texColor.r >= targetColor.r ? norm(texColor.r, maxR, targetColor.r) : norm(texColor.r, minR, targetColor.r);
      vg = texColor.g >= targetColor.g ? norm(texColor.g, maxG, targetColor.g) : norm(texColor.g, minG, targetColor.g);
      vb = texColor.b >= targetColor.b ? norm(texColor.b, maxB, targetColor.b) : norm(texColor.b, minB, targetColor.b);
    
      gl_FragColor = vec4(vec3(min(vr, min(vg, vb))), 1.0);
    
    }
    
Sign In or Register to comment.