topical media & game development

talk show tell print

graphic-flex-image-effects-10-source-isolateColor.pbk / pbk



  <languageVersion: 1.0;>
  
  kernel IsolateColor
  <
      namespace:      "com.bobs27";
      vendor:         "Todd Yard";
      version:        1;
      description:    "Isolates hue in image.";
  >
  {
  
      parameter int3 color
      <
          minValue:       int3(0, 0, 0);
          maxValue:       int3(255, 255, 255);
          defaultValue:   int3(255, 0, 0);
          description:    "The color to isolate.";
      >;
  
      parameter int hueThreshold
      <
          minValue:       int(0);
          maxValue:       int(360);
          defaultValue:   int(10);
          description:    "The amount off-hue to allow.";
      >;
  
      parameter int luminanceThreshold
      <
          minValue:       int(0);
          maxValue:       int(255);
          defaultValue:   int(100);
          description:    "The amount off-luminance to allow.";
      >;
  
      parameter int hideNonIsolated
      <
          minValue:       int(0);
          maxValue:       int(1);
          defaultValue:   int(0);
          description:    "Whether alpha of 0 should be applied to non-isolated pixels.";
      >;
  
      const float3 grayValues = float3(0.3, 0.59, 0.11);
      
      input image4 source;
      output pixel4 result;
      
      void
      evaluatePixel()
      {
      
          float4 px = sampleNearest(source, outCoord());
  
          // determine hue of color to isolate, between 0 and 360
          int hue = 0;
          int r = color.r;
          int g = color.g;
          int b = color.b;
          if (r == g && g == b) {
              hue = 0;
          } else if (r >= g && g >= b) {
              hue = 60 * (g - b)/(r - b);
          } else if (g >= r && r >= b) {
              hue = 60 + 60*(g - r)/(g - b);
          } else if (g >= b && b >= r) {
              hue = 120 + 60*(b - r)/(g - r);
          } else if (b >= g && g >= r) {
              hue = 180 + 60*(b - g)/(b - r);
          } else if (b >= r && r >= g){
              hue = 240 + 60*(r - g)/(b - g);
          } else if (r >= b && b >= g) {
              hue = 300 + 60*(r - b)/(r - g);
          }
          float isolateHue = float(hue);
          
          // determine hue of color current pixel being evaluated, between 0 and 360
          hue = 0;
          r = int(px.r * 255.0);
          g = int(px.g * 255.0);
          b = int(px.b * 255.0);
          if (r == g && g == b) {
              hue = 0;
          } else if (r >= g && g >= b) {
              hue = 60 * (g - b)/(r - b);
          } else if (g >= r && r >= b) {
              hue = 60 + 60*(g - r)/(g - b);
          } else if (g >= b && b >= r) {
              hue = 120 + 60*(b - r)/(g - r);
          } else if (b >= g && g >= r) {
              hue = 180 + 60*(b - g)/(b - r);
          } else if (b >= r && r >= g){
              hue = 240 + 60*(r - g)/(b - g);
          } else if (r >= b && b >= g) {
              hue = 300 + 60*(r - b)/(r - g);
          }
          float pixelHue = float(hue);
          
          // since hue "wraps" around the 360 degrees, do some manipulation so that
          // values can be more easily evaluated when too close to end of spectrum
          if (pixelHue - float(hueThreshold) < 0.0 && isolateHue + float(hueThreshold) > 360.0) {
              pixelHue = 360.0 - float(hueThreshold);
          } else if (pixelHue + float(hueThreshold) > 360.0 && isolateHue - float(hueThreshold) < 0.0) {
              pixelHue = float(hueThreshold) - 360.0;
          }
          
          // determine the luminance/brightness/value of colors
          float pixelLuminance = px.r * 0.3 + 
                                 px.g * 0.59 +
                                 px.b * 0.11;
          float isolateLuminance = float(color.r)/255.0 * 0.3 + 
                                   float(color.g)/255.0 * 0.59 +
                                   float(color.b)/255.0 * 0.11;
         
          // if luminance and hue are NOT within thresholds...
         if (abs(pixelHue - isolateHue) > float(hueThreshold) ||
              abs(pixelLuminance - isolateLuminance) > float(luminanceThreshold)/255.0
          ) {
              // either hide pixel completely by setting alpha to 0
              if (hideNonIsolated == 1) {
                  px.a = 0.0;
              // or recolor pixel to grayscale
              } else {
                  float distanceToDesaturatedValues = dot(px.rgb, grayValues);
                  px.rgb = float3(distanceToDesaturatedValues);
              }
          }
  
          result = px;
          
      }
      
  }


(C) Æliens 18/6/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.