January 9, 2016

Updated Shader

Not long after I began using my new shader, I updated it to take a parameter that would modify lightness in addition to hue and saturation. The texture being rendered is what normally provides the lightness value. But there were times that I wanted the same texture rendered, just darker (or lighter).

This was the original version:

vec3 rgb = hsl2rgb(vec3(u_Hue / 360.0, u_Sat / 100.0, gl_FragColor.x));

gl_FragColor.x is a value between 0 and 1 retrieved from the texture being rendered.

This was my initial lightness change:

vec3 rgb = hsl2rgb(vec3(u_Hue / 360.0, u_Sat / 100.0, gl_FragColor.x + u_Light / 100.0));

Pass in a value (u_Light) between -100 and 100 and combine it with the lightness value from the texture to calculate the final lightness value.

Since I have been messing around with adding caves - which need to be darker - I realized I made a mistake with the shader tweak. It was adjusting lightness linearly when instead it needed to proportionally make things lighter or darker.

This is what the latest version looks like:

vec3 rgb = hsl2rgb(vec3(u_Hue / 360.0, u_Sat / 100.0, gl_FragColor.x + gl_FragColor.x * u_Light / 100.0));

To illustrate this, here is an image that shows the difference between the last two versions of the shader. The first row adjusts the lightness of each pixel linearly, the second row adjusts it proportionally.

As you can see in the first row, the background and clothing darken to black first because they start out darker than the rest. The face and arms are lighter, so it takes them longer to darken. While this was amusing (glowing skin!), the second row is what I needed to render a darker scene.

For reference, here is the full current version of the shader:

precision mediump float;

uniform sampler2D u_TextureUnit;
uniform float u_Alpha;
uniform float u_Hue;
uniform float u_Sat;
uniform float u_Light;
varying vec2 v_TextureCoordinates;

vec3 hsl2rgb(vec3 HSL)
{
  float R = abs(HSL.x * 6.0 - 3.0) - 1.0;
  float G = 2.0 - abs(HSL.x * 6.0 - 2.0);
  float B = 2.0 - abs(HSL.x * 6.0 - 4.0);
  vec3 RGB = clamp(vec3(R,G,B), 0.0, 1.0);
  float C = (1.0 - abs(2.0 * HSL.z - 1.0)) * HSL.y;
  return (RGB - 0.5) * C + HSL.z;
}

void main()
{
   gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);
   vec3 rgb = hsl2rgb(vec3(u_Hue / 360.0, u_Sat / 100.0, gl_FragColor.x + gl_FragColor.x * u_Light / 100.0));
   gl_FragColor = vec4(rgb.r, rgb.g, rgb.b, gl_FragColor.a * u_Alpha / 100.0);
}

tagged: resource code