CS307: HSL/HSV Color Models and Color Interpolation
Plan
- HSL and HSV color models
- Parametric lines and triangles
- Color interpolation
- Quiz questions
- Exercise: Colorful stars
HSL and HSV Color Models
HSV and HSL are common, useful color models. Hue and Saturation are the same for both models. Value and Lightness are similar. For humans, these models are more intuitive than RGB.
Three.js provides support for HSL and there are
many online tools for selecting HSL colors.
In the example below, the setHSL()
method is used to specify hue,
saturation, and lightness values for a color. Note that each of these quantities
must be converted to a range from 0.0 to 1.0.
var myColor = new THREE.Color(); myColor.setHSL(0.6, 0.9, 0.8); alert("myColor is " + myColor.getHexString());
This text is displayed with
myColor
as background.
The CMYK model is good to know about, but won't be used in this course.
Parametric Triangles and Color Interpolation
So far, we displayed faces with solid color. Suppose we want to specify different colors for the vertices and display smoothly varying color over a face. To understand how this is done, we need to know how to describe a triangle using parametric equations.
The parametric equation of a triangle defines an area that is created from a vertex and a line segment, using a parametric equation between the vertex and a point on the line segment, where the point on the line segment is itself defined by a parametric equation.
The equation Q(s,t) can also be expressed as:
\[ Q(s,t) = A(1-t)s+Bts + C(1-s) \]
We can think of this as a weighted sum of the coordinates of the three vertices:
Q = A * wa + B * wb + C * wc wa + wb + wc = 1 0 ≤ wa, wb, wc, ≤ 1
Suppose we have three vertices A,B,C with x,y,z coordinates shown in the following diagram, and want to compute the coordinates of a point D inside the triangle, where t = 0.25 and s = 0.67? The steps of this calculation are shown below the diagram.
Q(s,t) = A(1-t)s + Bts + C(1-s)
Q(2/3,1/4) = (0,4,2)(3/4)(2/3) + (4,12,0)(1/4)(2/3) + (10,6,1)(1/3)
D = (0,4,2)(1/2) + (4,12,0)(1/6) + (10,6,1)(1/3)
D = (0,2,1) + (2/3,2,0) + (10/3,2,1/3)
D = (4,6,4/3)
Now suppose the vertices A,B,C have different colors, and we want to determine a color for the point D within the triangle that "blends" together the colors of the vertices? In particular, suppose A is yellow, B is green, and C is cyan. How can we calculate the color of D?
color = (color of A)(1-t)s + (color of B)ts + (color of C)(1-s)
(r,g,b) = (1,1,0)(3/4)(2/3) + (0,1,0)(1/4)(2/3) + (0,1,1)(1/3)
(r,g,b) = (1,1,0)(1/2) + (0,1,0)(1/6) + (0,1,1)(1/3)
(r,g,b) = (1/2,1/2,0) + (0,1/6,0) + (0,1/3,1/3)
(r,g,b) = (1/2,1,1/3) = (0.5,1,0.33)
Color Interpolation in Three.js
There are three key elements for doing color interpolation over triangles in Three.js:
- the
vertexColors
attribute of the geometry is an array of colors - each
THREE.Face3
object contains an array of three colors, also namedvertexColors
, with one color for each vertex in the face - in the
THREE.MeshBasicMaterial
object, we set thevertexColors
attribute to the magic constantTHREE.VertexColors
Color Hexcones
Let's take a minute to look at the Color Cones demo.
Color Interpolation
We'll explore these ideas with our
colorful square.
Below are diagrams and essential code for this example. The
TW.computeFaceColors()
function creates the vertexColors
arrays that are stored for each face in the geometry:
function squareGeometry () { var squareGeom = new THREE.Geometry(); squareGeom.vertices = [new THREE.Vector3(0,0,0), // vertices new THREE.Vector3(1,0,0), new THREE.Vector3(1,1,0), new THREE.Vector3(0,1,0)]; squareGeom.faces = [new THREE.Face3(0,1,3), // faces new THREE.Face3(1,2,3)]; return squareGeom; } var squareGeom = squareGeometry(); // create geometry // define the colors for each of the four vertices squareGeom.vertexColors = [new THREE.Color("magenta"), new THREE.Color("blue"), new THREE.Color("red"), new THREE.Color("green")]; // setup the vertex colors for each face TW.computeFaceColors(squareGeom); // create a material that uses vertex colors // and interpolated color within faces var squareMaterial = new THREE.MeshBasicMaterial( {vertexColors: THREE.VertexColors, side: THREE.DoubleSide} ); // create a mesh and add to the scene var squareMesh = new THREE.Mesh(squareGeom, squareMaterial); scene.add(squareMesh);
Quiz Questions
I'll cover as many of your quiz questions as I can.
Exercise: Colorful Stars
This stars-start.html code file
contains a function named starGeometry()
that creates and
returns a Three.Geometry
object for a three-pointed star.
This diagram shows the order in which the vertices and colors are defined, and placement of faces:
Modify the code to create a star that uses color interpolation of the triangular faces, and adds it to the scene. Your star might look like this:
Some tips:
- The starting code includes an array of
THREE.Color
objects namedcolors
. Feel free to change the colors to whatever you want! - When creating the material for the star using
THREE.MeshBasicMaterial
, add a second property to the input object (in addition to thevertexColors
property) that tells Three.js to render both sides of the triangular faces:side: THREE.DoubleSide
Here's a possible solution: stars1.html
(Optional) Add six additional stars to the scene that each have a uniform color, and are placed around the central star, something like this:
Some tips for this part:
- Think about how this can be done with a loop (Hint: The
starGeometry()
function has a loop example that may be handy) - Use the same array of colors that you used for the central star
- Recall that
position.set()
can be used to place a mesh at a desired location - Remember to adjust the bounding box supplied to
TW.cameraSetup()
to see the additional stars
Your code might look like this: stars.html
To Do for Next Class
- Reading for Friday: The Instance Transform and More on Parametric Equations (intersecting lines in 2D and 3D)
- Assignment 1 (obelisk) due