GLSL help - smoothstep ?


    Jun 10 2007 | 3:24 am
    greetings.
    I have written a shader that is reminiscent of the Sin City look, ie,
    black and white and red all over.
    However, im getting some dithering where my reds are below my
    threshold limit and the neighboring pixels return to black and white.
    Ive tried to add smoothstep in there, but cant seem to get it right.
    Anyone care to take a gander?
    This shader was going to be released open source anyway, so heres the
    code, check it out - id love to know if im going about this the wrong
    way, but ive been hacking at it for a while, and this is the best
    version that ive got. Note that the license is Creative Commons Share
    Alike Non Commercial Attribution, not that uh, it matters much id wager.
    Throw this on slab and shoot something with red and other colors
    through. It works pretty well.
    --
    source="v001.blackandwhitecolor.vp.glsl" />
    source="v001.blackandwhitecolor.fp.glsl" />
    -- vp
    varying vec2 texcoord0;
    void main()
    {
    // perform standard transform on vertex
    gl_Position = ftransform();
    // transform texcoords
    texcoord0 = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);
    }
    ---
    fp program
    ---
    uniform float thresh;
    // define our rectangular texture samplers
    uniform sampler2DRect tex0;
    // define our varying texture coordinates
    varying vec2 texcoord0;
    varying vec2 texdim0;
    void main (void)
    {
    vec4 input0 = texture2DRect(tex0, texcoord0);
    // luma
    const vec4 lumcoeff = vec4(0.299,0.587,0.114,0.);
    float luminance = dot(input0,lumcoeff);
    vec4 luma = vec4(luminance);
    // saturation of each channel as the difference between luma and the
    input textures value in the channel.
    vec4 sat = vec4( (input0.r - (luma.r/3.)), (input0.g - (luma.g/3.)),
    (input0.b - (luma.b/3.)), 1.0);
    // now we find if we are above the saturation threshold for red.
    // note we have to deal with weird colors like purple and yellow
    that are also 100% red, but arent actually red :(
    float mixamount = (thresh >= sat.r || sat.b >= thresh || sat.g >=
    thresh) ? thresh : sat.r;
    vec4 result = mix(luma, sat, mixamount);
    // vec4 result = smoothstep(thresh, 1.0, red);
    gl_FragColor = vec4(result.rgb,1.0);
    }
    ---
    v a d e //
    www.vade.info
    abstrakt.vade.info

    • Jun 10 2007 | 3:31 am
      forgot to mention - heres a preview image:
      enjoy.
      v a d e //
      www.vade.info
      abstrakt.vade.info
    • Jun 11 2007 | 5:59 pm
      Hey Man,
      I haven't taken the time to figure out exactly how you are trying to use
      the smoothstep() function yet, but below is a version of my lumagate
      shader (the one used in the article) that makes use of smoothstep() to
      provide a fade parameter. I would also recommend against the use of the
      if/then stuff, as there is pretty inconsistent support for conditionals
      in GLSL. I would recommend using step() and mix() for conditional
      logic. Here is an example of what I am talking about, based on the
      conditional statement you are using:
      float mixamount = mix(sat.r,thresh,float(thresh >= sat.r || sat.b >=
      thresh || sat.g >= thresh));
      I can probably help more if I know what exactly smoothstep is being used
      for in this particular case.
      Best,
      Andrew B.
      P.s. here is a smoothstep example:
      //setup for single texture
      varying vec2 texcoord0;
      uniform sampler2DRect tex0;
      //luma threshold
      uniform vec2 lum;
      uniform vec2 fade;
      uniform vec4 lumcoeff;
      void main()
      {
      vec4 a = texture2DRect(tex0, texcoord0);
      vec3 b = vec3 (a);
      // calculate our luminance
      float luminance = dot(a,lumcoeff);
      float clo = smoothstep(lum.x,lum.x+fade.x,luminance);
      float chi = 1.-smoothstep(lum.y-fade.y,lum.y,luminance);
      float amask = float (clo * chi);
      // output texture with transparency
      gl_FragColor = vec4(b,amask);
      }
    • Jun 11 2007 | 6:11 pm
      Actually, now that I've taken a moment to think of it, you should really
      have a look at how we do things in the co.chromakey.jxs shader. It
      seems like what you are doing has a very similar logic scheme to a
      chromakey effect, except that instead of compositing, you are selecting
      a range of colors to saturate/desaturate. Let me know what you come up
      with.
      AB
    • Jun 11 2007 | 6:33 pm
      Thanks Andrew. I was actually doing a bit of research and I think the
      better way of doing what I want is to use HSL colorspace conversion
      and do my logic based on the saturation vector as threshold and color
      selection based on the hue vector. You are correct about chromakey,
      dont know why I didnt think of that earlier.
      Thanks. Im heading off to easyrgb.com to try fiddle with that HSL
      code conversion.
      Peace!
      On Jun 11, 2007, at 2:11 PM, andrew benson wrote:
      > Actually, now that I've taken a moment to think of it, you should
      > really
      > have a look at how we do things in the co.chromakey.jxs shader. It
      > seems like what you are doing has a very similar logic scheme to a
      > chromakey effect, except that instead of compositing, you are
      > selecting
      > a range of colors to saturate/desaturate. Let me know what you
      > come up
      > with.
      >
      > AB
      v a d e //
      www.vade.info
      abstrakt.vade.info