POV-Ray : Newsgroups : povray.beta-test : Colors.inc-macros incomplete : Re: Colors.inc-macros incomplete Server Time
5 Nov 2024 03:16:56 EST (-0500)
  Re: Colors.inc-macros incomplete  
From: Tor Olav Kristensen
Date: 10 Sep 2001 21:13:41
Message: <3B9D6505.101CB65F@hotmail.com>
Tor Olav Kristensen wrote:
> 
> Ken wrote:
> >
> > Warp wrote:
> > >
> > >   Yes, I think they are under developement.
> >
> > Yes, and the person developing them left for college and has never
> > been heard from again. We may have to scrap them unless someone
> > else takes over and finishes them.
> 
> I had a quick look at those macros. And I
> also skimmed through some of the relevant
> sections in this FAQ:
>...
> It seems to me that the mentioned macros
> are far from done...
> 
> So I would suggest to scrap them.

Well, I think that I now understand how 
the first macro; CHSL2RGB()
(Convert HSL to RGB) was meant to work.

I have rewritten it. But I couldn't get
the .filter and .transmit components to
work (strange things happened).

The macro seems to work OK now, but one
cannot feed it with 4D or 5D color vectors.

Here's my suggestion for it:

#macro CHSL2RGB(vColor)

  // Extract Hue, Saturation and Lightness components
  #local H = vColor.red;
  #local S = vColor.green;
  #local L = vColor.blue;

  // Construct RGB from Hue
  #switch (H)
    #range (0/3, 1/3)         // H: 0/3 -> 1/3
      #local R = (1/3 - H)*6; // R:  2  ->  0
      #local G = (H - 0/3)*6; // G:  0  ->  2
      #local B = 0;           // B:  0  ->  0
    #break
    #range (1/3, 2/3)         // H: 1/3 -> 2/3
      #local R = 0;           // R:  0  ->  0
      #local G = (2/3 - H)*6; // G:  2  ->  0
      #local B = (H - 1/3)*6; // B:  0  ->  2
    #break
    #range (2/3, 3/3)         // H: 2/3 -> 3/3
      #local R = (H - 2/3)*6; // R:  0  ->  2
      #local G = 0;           // G:  0  ->  0
      #local B = (3/3 - H)*6; // B:  2  ->  0
    #break
    #else
      #error "Error in CHSL2RGB: Value for Hue component is out of
range."
  #end // switch

  #local vClampedRGB = <min(R, 1), min(G, 1), min(B, 1)>;

  //  Incorporate saturation and lightness
  #local vRGB = ((1 - S)*<1, 1, 1> + S*vClampedRGB)*L;

  color rgb <vRGB.red, vRGB.green, vRGB.blue>

#end // macro CHSL2RGB


And here's some examples on how it converts colors:

Red     HSL: <0/6, 1, 1> => RGB: <1, 0, 0>
Yellow  HSL: <1/6, 1, 1> => RGB: <1, 1, 0>
Green   HSL: <2/6, 1, 1> => RGB: <0, 1, 0>
Cyan    HSL: <3/6, 1, 1> => RGB: <0, 1, 1>
Blue    HSL: <4/6, 1, 1> => RGB: <0, 0, 1>
Magenta HSL: <5/6, 1, 1> => RGB: <1, 0, 1>
Red     HSL: <  1, 1, 1> => RGB: <1, 0, 0>
Black   HSL: <  X, X, 0> => RGB: <0, 0, 0>
White   HSL: <  X, 0, 1> => RGB: <1, 1, 1>
(X means don't care)


And here's an example that shows how to use it:

#declare HSL_Red     = <  0, 1, 1>;
#declare HSL_Yellow  = <1/6, 1, 1>;
#declare HSL_Green   = <1/3, 1, 1>;
#declare HSL_Cyan    = <1/2, 1, 1>;
#declare HSL_Blue    = <2/3, 1, 1>;
#declare HSL_Magenta = <5/6, 1, 1>;
#declare HSL_Red     = <  1, 1, 1>;

#declare HSL_Black   = <  0, 0, 0>;
#declare HSL_White   = <  0, 0, 1>;
#declare HSL_Grey    = HSL_White/2;

sphere {
  <0, 0, 0>, 1
  pigment { CHSL2RGB(HSL_Red) }
}

light_source {
  100*<-1, 1, -1>
  CHSL2RGB(HSL_White)
}

camera {
  location <2, 1, -3>
  look_at <0, 0, 0>
}

background { CHSL2RGB(HSL_Grey) }



But if I were to write this macro from 
scratch, then i would have used an angle
(in degrees) for the Hue component.

I.e. like this:

Red     HSL: <  0, 1, 1> => RGB: <1, 0, 0>
Yellow  HSL: < 60, 1, 1> => RGB: <1, 1, 0>
Green   HSL: <120, 1, 1> => RGB: <0, 1, 0>
Cyan    HSL: <180, 1, 1> => RGB: <0, 1, 1>
Blue    HSL: <240, 1, 1> => RGB: <0, 0, 1>
Magenta HSL: <300, 1, 1> => RGB: <1, 0, 1>
Black   HSL: <  X, X, 0> => RGB: <0, 0, 0>
White   HSL: <  X, 0, 1> => RGB: <1, 1, 1>
// X means don't care


And I would have omitted the color and rgb
keywords before the returned vector.

Then the macro would have looked like this:


#macro ConvertHSLtoRGB(vColor)

  // Extract Hue, Saturation and Lightness components
  #local H = vColor.x;
  #local S = vColor.y;
  #local L = vColor.z;

  // Construct RGB from Hue
  #switch (mod(H, 360))
    #range (0, 120)
      #local R = (120 -   H)/60;
      #local G = (  H -   0)/60;
      #local B = 0;
    #break
    #range (120, 240)
      #local R = 0;
      #local G = (240 -   H)/60;
      #local B = (  H - 120)/60;
    #break
    #range (240, 360)
      #local R = (  H - 240)/60;
      #local G = 0;
      #local B = (360 -   H)/60;
    #break
  #end // switch

  #local vClampedRGB = <min(R, 1), min(G, 1), min(B, 1)>;

  // Incorporate saturation and lightness
  (((1 - S)*<1, 1, 1> + S*vClampedRGB)*L)

#end // macro ConvertHSLtoRGB


And some code to show how it works could
look like this:

#declare HSL_Red     = <  0, 1, 1>; // or <360, 1, 1> or < 720, 1, 1>
...
#declare HSL_Yellow  = < 60, 1, 1>; // or <420, 1, 1> or < 780, 1, 1>
...
#declare HSL_Green   = <120, 1, 1>; // or <480, 1, 1> or < 840, 1, 1>
...
#declare HSL_Cyan    = <180, 1, 1>; // or <540, 1, 1> or < 900, 1, 1>
...
#declare HSL_Blue    = <240, 1, 1>; // or <600, 1, 1> or < 960, 1, 1>
...
#declare HSL_Magenta = <300, 1, 1>; // or <660, 1, 1> or <1020, 1, 1>
...

#declare HSL_Black   = <  0, 0, 0>;
#declare HSL_White   = <  0, 0, 1>;
#declare HSL_Grey    = HSL_White/2;

sphere {
  <0, 0, 0>, 1
  pigment { color ConvertHSLtoRGB(HSL_Cyan) }
}

light_source {
  100*<-1, 1, -1>
  color ConvertHSLtoRGB(HSL_White)
}

camera {
  location <2, 1, -3>
  look_at <0, 0, 0>
}

background { color ConvertHSLtoRGB(HSL_Grey) }


Tor Olav


Post a reply to this message

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