Sunday 17 February 2013

RYB Color Wheel



As a follow up to my previous post on the RGB color wheel, I made the RYB Color Wheel.

This time I got a bit smarter so I decided to build this wheel in Stage3D, since I could use the GPU to interpolate the colors on the triangle for me. I have not actually coded directly in Stage3D before since I used Starling framework which wraps around Stage3D to make it much easier to use. This Hello Triangle tutorial by Marco Scabia helped me jump through the basic hoops of setting up the render scene.

I first tried to change the formula for the HSV/HSL computation. I remember this graph from the HSL-HSV Wikipedia page which showed me the RGB values behaviour when the hue changes.


HSV-RGB relation


I wanted to modify the mathematical formula to alter this graph to shift the yellow to the green's position to make it a primary color. I tried this out by editing the gradient of the svg file from wikipedia in Adobe Illustrator.


HSV-RYB relation with yellow shifted


This was what I got, but I quickly realized that this method would not suffice as I should not be getting such bright colors, and I should not even see cyan in the wheel. I tried to cut off cyan by adding a node at the 180 hue green and blue and interpolating directly to the 240 hue value and I thought I took a step forward.

However, I also did a quick web search and found a research paper which suited my needs. The paper, titled Paint Inspired Color Compositing by Nathan Gossett and Baoquan Chen, used custom color values for a color cube and did a 1-for-1 mapping between the RGB cube to the new RYB cube and then trilinear interpolated the RYB cubes colors to figure out the RGB values. They got the values from the Johannes Itten color model, which is widely used in art education.

I decided to adopt their method to implement my RYB color wheel, so credits goes to them for the RGB-RYB conversion. I decided to plot the graph again using the values provided by them to see what it looked like:



HSV-RYB relation


Learning Points:

  • RYB can be mapped instead of done via a formula. I think there is still value in building the formula version for efficiency purposes but currently, this suits my needs already.
  • Most of the RYB colors are standard but RYB green is (0.0, 0.66, 0.2)
  • RYB blue is not pure blue (0.163, 0.373, 0.6).
  • RYB black is not pure black (0.2, 0.094, 0.0)!
  • In fact, there is a lot of red everywhere. From the graph, you can tell that red is most prominent color of the three primary colors RGB. Even in black, there is a relatively strong red component, which equates to brownish black.
  • I was wondering if the components of RGB had any effect on Value or Lightness of a color. Reading up Wikipedia tells me that Lightness is actually ambiguous! And there are actually 4 different ways to calculated Lightness of a color. That's definitely something new to me because I knew that if the grayscale version of two colors were the same, they would be the same Lightness, but I did not know that there could be several ways to achieve that.
  • The research paper suggested giving a bias towards to the colors at the corners of the cube by altering the interpolation function to a cubic one. For this reason, I decided to implement a linear function compare the results. You can click the button above in the flash swf to see the difference. I do not have much opinion on which is better at the moment, although linear interpolation would definitely be cheaper computation wise so that may be the function I would probably use for real-time games purposes.
  • In the process of converting RYB to RGB, I came across trilinear interpolation. Trilinear interpolation is essentially interpolating all the 8 corners of a cube to find a point within the cube. It is done by first interpolating the 4 pairs of corners in one axis (e.g. X-axis), then interpolating the 2 pairs of results in the next axis (e.g. Y-axis), and finally interpolating the 1 last pair of result in the last axis (e.g. Z-axis).
  • In writing this blog, I also learned how to use SVG graphics inside Blogger. You can read more here if you are interested.
  • As this is the first time experimenting directly with Stage3D (instead of using the Starling Framework wrapper), I also got into some hiccups with the Matrix which is passed into the vertex shader for view projection. I realized that Stage3D by defaults provides a normalized viewport so for e.g. top left of the screen is (0,0) and bottom right is (1,1). I wanted to look into setting up the projection matrix for a proper camera system but I think I will want to look into that again in future.


No comments:

Get Adsense

Want to earn money like me? Get Google Adsense now by clicking this