POV-Ray : Newsgroups : povray.text.scene-files : HSL --> RGB : Re: HSL --> RGB Server Time
29 Jul 2024 02:21:04 EDT (-0400)
  Re: HSL --> RGB  
From: Mark Donovan
Date: 11 Oct 1998 16:23:01
Message: <36210591.8D303C9D@worldnet.att.net>
I've done it. Here's a version of HSL to RGB and also a macro for HSB to
RGB. The descriptions explain the difference. These versions work
without trig or vector functions. To be complete, I've tacked on RGB to
HSL and RGB to HSB conversions.

Theran Cochran wrote:
> 
> I'm thinking about creating a macro to convert HSL colors to RGB. I want
> to know if someone has already done...

Mark Donovan
Phoenix, Arizona, USA
===
#local Version_Temp = version;
#version 3.1;

#ifdef(View_POV_Include_Stack)
#   debug "including rgb2hsl.inc\n"
#end

/*
   Convert HSL to RGB color space
   Date:   July 1998
   Author: Mark Donovan

 Description:

   Converts hue, saturation, and lightness a POV-Ray color. Each component
   is defined in the range 0.0 to 1.0. Hue value 0.0 is red. Fully saturated
   color is defined at lightness 0.5 and saturation 1.0.
   No test for values out of range.

 Typical call:

   #include "hsl2rgb.inc"
   // HSL is a vector <hue, saturation, lightness>
   #declare RGB = hsl2rgb(<0.743, 0.234, 0.123>);
   // returns POV-Ray color RGB = color rgb <red, green, blue>

*/

#macro hsl2rgb(HSL)
#local _HSL_H = HSL.x;
#local _HSL_S = HSL.y;
#local _HSL_L = HSL.z;

#local _HSL_Sextant = int(6.0 * _HSL_H);
#if (_HSL_L <= 0.5)
  #local _HSL_M = _HSL_L * (1.0 + _HSL_S);
#else
  #local _HSL_M = _HSL_L + _HSL_S - _HSL_L * _HSL_S;
#end
#local _HSL_m = 2.0 * _HSL_L - _HSL_M;
#if (_HSL_S = 0.0)
  #local _HSL_R = _HSL_L;
  #local _HSL_G = _HSL_L;
  #local _HSL_B = _HSL_L;
#else
  #switch (_HSL_Sextant)
  #case (0)
    #local _HSL_R = _HSL_M;
    #local _HSL_G = _HSL_m + (_HSL_M - _HSL_m) * _HSL_H * 6.0;
    #local _HSL_B = _HSL_m;
  #break
  #case (1)
    #local _HSL_R = _HSL_m + (_HSL_M - _HSL_m) * (2.0 - 6.0 * _HSL_H);
    #local _HSL_G = _HSL_M;
    #local _HSL_B = _HSL_m;
  #break
  #case (2)
    #local _HSL_R = _HSL_m;
    #local _HSL_G = _HSL_M;
    #local _HSL_B = _HSL_m + (_HSL_M - _HSL_m) * (6.0 * _HSL_H - 2.0);
  #break
  #case (3)
    #local _HSL_R = _HSL_m;
    #local _HSL_G = _HSL_m + (_HSL_M - _HSL_m) * (4.0 - 6.0 * _HSL_H);
    #local _HSL_B = _HSL_M;
  #break
  #case (4)
    #local _HSL_R = _HSL_m + (_HSL_M - _HSL_m) * (6.0 * _HSL_H - 4.0);
    #local _HSL_G = _HSL_m;
    #local _HSL_B = _HSL_M;
  #break
  #case (5)
    #local _HSL_R = _HSL_M;
    #local _HSL_G = _HSL_m;
    #local _HSL_B = _HSL_m + (_HSL_M - _HSL_m) * (6.0 - 6.0 * _HSL_H);
  #break
  #case (6)
    #local _HSL_R = _HSL_M;
    #local _HSL_G = _HSL_m;
    #local _HSL_B = _HSL_m + (_HSL_M - _HSL_m) * (6.0 - 6.0 * _HSL_H);
  #break
  #else
    #error "bad HSL conversion"
  #end
#end
color rgb <_HSL_R, _HSL_G, _HSL_B>
#end

#version Version_Temp;
===
#local Version_Temp = version;
#version 3.1;

#ifdef(View_POV_Include_Stack)
#   debug "including hsb2rgb.inc\n"
#end

/*
   Convert HSB to RGB color space
   Date:   July 1998
   Author: Mark Donovan

 Description:

   Converts hue, saturation, and value to a POV-Ray color. Each component
   is defined in the range 0.0 to 1.0. Hue value 0.0 is red. Fully saturated
   color is defined at brightness 1.0 and saturation 1.0. No test for values
   out of range.

 Typical call:

   #include "hsb2rgb.inc"
   // HSB is a vector
   #declare RGB = hsb2rgb(<0.743, 0.234, 0.123>);
   // returns POV-Ray color RGB = color rgb <red, green, blue>

*/

#macro hsb2rgb(HSB)
#local _HSB_H = HSB.x;
#local _HSB_S = HSB.y;
#local _HSB_V = HSB.z;

// HSB to RGB conversion
#if (_HSB_S = 0.0)
  #local _HSB_R = _HSB_V;
  #local _HSB_G = _HSB_V;
  #local _HSB_B = _HSB_V;
#else
  #if (_HSB_H >= 1.0)  // red is red
    #declare _HSB_H = 0.0;
  #end
  #local _HSB_h = _HSB_H * 6.0;
  #local _HSB_i = int(_HSB_h);
  #local _HSB_f = _HSB_h - _HSB_i;
  #local _HSB_p = _HSB_V * (1.0 - _HSB_S);
  #local _HSB_q = _HSB_V * (1.0 - (_HSB_S * _HSB_f));
  #local _HSB_t = _HSB_V * (1.0 - (_HSB_S * (1.0 - _HSB_f)));
  #switch (_HSB_i)
  #case (0)
    #local _HSB_R = _HSB_V;
    #local _HSB_G = _HSB_t;
    #local _HSB_B = _HSB_p;
  #break
  #case (1)
    #local _HSB_R = _HSB_q;
    #local _HSB_G = _HSB_V;
    #local _HSB_B = _HSB_p;
  #break
  #case (2)
    #local _HSB_R = _HSB_p;
    #local _HSB_G = _HSB_V;
    #local _HSB_B = _HSB_t;
  #break
  #case (3)
    #local _HSB_R = _HSB_p;
    #local _HSB_G = _HSB_q;
    #local _HSB_B = _HSB_V;
  #break
  #case (4)
    #local _HSB_R = _HSB_t;
    #local _HSB_G = _HSB_p;
    #local _HSB_B = _HSB_V;
  #break
  #case (5)
    #local _HSB_R = _HSB_V;
    #local _HSB_G = _HSB_p;
    #local _HSB_B = _HSB_q;
  #break
  #else
    #error "bad HSB conversion"
  #end
#end
color rgb <_HSB_R, _HSB_G, _HSB_B>
#end

#version Version_Temp;
===
#local Version_Temp = version;
#version 3.1;

#ifdef(View_POV_Include_Stack)
#   debug "including rgb2hsl.inc\n"
#end

/*
   Convert HSL to RGB color space
   Date:   July 1998
   Author: Mark Donovan

 Description:

   Converts hue, saturation, and lightness a POV-Ray color. Each component
   is defined in the range 0.0 to 1.0. Hue value 0.0 is red. Fully saturated
   color is defined at lightness 0.5 and saturation 1.0.
   No test for values out of range.

 Typical call:

   #include "hsl2rgb.inc"
   // HSL is a vector <hue, saturation, lightness>
   #declare RGB = hsl2rgb(<0.743, 0.234, 0.123>);
   // returns POV-Ray color RGB = color rgb <red, green, blue>

*/

#macro hsl2rgb(HSL)
#local _HSL_H = HSL.x;
#local _HSL_S = HSL.y;
#local _HSL_L = HSL.z;

#local _HSL_Sextant = int(6.0 * _HSL_H);
#if (_HSL_L <= 0.5)
  #local _HSL_M = _HSL_L * (1.0 + _HSL_S);
#else
  #local _HSL_M = _HSL_L + _HSL_S - _HSL_L * _HSL_S;
#end
#local _HSL_m = 2.0 * _HSL_L - _HSL_M;
#if (_HSL_S = 0.0)
  #local _HSL_R = _HSL_L;
  #local _HSL_G = _HSL_L;
  #local _HSL_B = _HSL_L;
#else
  #switch (_HSL_Sextant)
  #case (0)
    #local _HSL_R = _HSL_M;
    #local _HSL_G = _HSL_m + (_HSL_M - _HSL_m) * _HSL_H * 6.0;
    #local _HSL_B = _HSL_m;
  #break
  #case (1)
    #local _HSL_R = _HSL_m + (_HSL_M - _HSL_m) * (2.0 - 6.0 * _HSL_H);
    #local _HSL_G = _HSL_M;
    #local _HSL_B = _HSL_m;
  #break
  #case (2)
    #local _HSL_R = _HSL_m;
    #local _HSL_G = _HSL_M;
    #local _HSL_B = _HSL_m + (_HSL_M - _HSL_m) * (6.0 * _HSL_H - 2.0);
  #break
  #case (3)
    #local _HSL_R = _HSL_m;
    #local _HSL_G = _HSL_m + (_HSL_M - _HSL_m) * (4.0 - 6.0 * _HSL_H);
    #local _HSL_B = _HSL_M;
  #break
  #case (4)
    #local _HSL_R = _HSL_m + (_HSL_M - _HSL_m) * (6.0 * _HSL_H - 4.0);
    #local _HSL_G = _HSL_m;
    #local _HSL_B = _HSL_M;
  #break
  #case (5)
    #local _HSL_R = _HSL_M;
    #local _HSL_G = _HSL_m;
    #local _HSL_B = _HSL_m + (_HSL_M - _HSL_m) * (6.0 - 6.0 * _HSL_H);
  #break
  #case (6)
    #local _HSL_R = _HSL_M;
    #local _HSL_G = _HSL_m;
    #local _HSL_B = _HSL_m + (_HSL_M - _HSL_m) * (6.0 - 6.0 * _HSL_H);
  #break
  #else
    #error "bad HSL conversion"
  #end
#end
color rgb <_HSL_R, _HSL_G, _HSL_B>
#end

#version Version_Temp;
===
#local Version_Temp = version;
#version 3.1;

#ifdef(View_POV_Include_Stack)
#   debug "including hsb2rgb.inc\n"
#end

/*
   Convert HSB to RGB color space
   Date:   July 1998
   Author: Mark Donovan

 Description:

   Converts hue, saturation, and value to a POV-Ray color. Each component
   is defined in the range 0.0 to 1.0. Hue value 0.0 is red. Fully saturated
   color is defined at brightness 1.0 and saturation 1.0. No test for values
   out of range.

 Typical call:

   #include "hsb2rgb.inc"
   // HSB is a vector
   #declare RGB = hsb2rgb(<0.743, 0.234, 0.123>);
   // returns POV-Ray color RGB = color rgb <red, green, blue>

*/

#macro hsb2rgb(HSB)
#local _HSB_H = HSB.x;
#local _HSB_S = HSB.y;
#local _HSB_V = HSB.z;

// HSB to RGB conversion
#if (_HSB_S = 0.0)
  #local _HSB_R = _HSB_V;
  #local _HSB_G = _HSB_V;
  #local _HSB_B = _HSB_V;
#else
  #if (_HSB_H >= 1.0)  // red is red
    #declare _HSB_H = 0.0;
  #end
  #local _HSB_h = _HSB_H * 6.0;
  #local _HSB_i = int(_HSB_h);
  #local _HSB_f = _HSB_h - _HSB_i;
  #local _HSB_p = _HSB_V * (1.0 - _HSB_S);
  #local _HSB_q = _HSB_V * (1.0 - (_HSB_S * _HSB_f));
  #local _HSB_t = _HSB_V * (1.0 - (_HSB_S * (1.0 - _HSB_f)));
  #switch (_HSB_i)
  #case (0)
    #local _HSB_R = _HSB_V;
    #local _HSB_G = _HSB_t;
    #local _HSB_B = _HSB_p;
  #break
  #case (1)
    #local _HSB_R = _HSB_q;
    #local _HSB_G = _HSB_V;
    #local _HSB_B = _HSB_p;
  #break
  #case (2)
    #local _HSB_R = _HSB_p;
    #local _HSB_G = _HSB_V;
    #local _HSB_B = _HSB_t;
  #break
  #case (3)
    #local _HSB_R = _HSB_p;
    #local _HSB_G = _HSB_q;
    #local _HSB_B = _HSB_V;
  #break
  #case (4)
    #local _HSB_R = _HSB_t;
    #local _HSB_G = _HSB_p;
    #local _HSB_B = _HSB_V;
  #break
  #case (5)
    #local _HSB_R = _HSB_V;
    #local _HSB_G = _HSB_p;
    #local _HSB_B = _HSB_q;
  #break
  #else
    #error "bad HSB conversion"
  #end
#end
color rgb <_HSB_R, _HSB_G, _HSB_B>
#end

#version Version_Temp;
===


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.