In particular, you should know at least:

- The difference between a 3D vector, like "vec3"; and a 1D
scalar, like "float". I try to consistently write vectors
in uppercase, like "vec3 A", and scalars in lowercase, like
"float a". You can't add vectors and scalars, so you do need to
keep track of the difference.

- Vectors as positions/locations/coordinates ("absolute", with
w==1.0), shifts/offsets/directions ("relative", with w==0.0),
and
unit-length directions ("normalized", a special case of relative
vectors).

- Know how to calculate a vector's length, via the Euclidian distance: len=sqrt(x*x+y*y+z*z);
- Know that "to normalize" means to make a vector have unit
length (for example, by
dividing it by its length).

- Homogenous vector interpretation: (x,y,z,1) is an absolute location; (x,y,z,0) is a relative direction.
- "It's just a bag of floats" vector interpretation: the color
(r,g,b,a) can and is treated like as a vector, especially on the
graphics hardware.

- Dot product: compute the "similarity" of two vectors

- A dot B = A.x*B.x + A.y*B.y + A.z*B.z

- For unit vectors, A dot B is the cosine of the angle between
A and B.

- You can figure this out if you write down the dot product of two unit 2D vectors: A=(1,0) lying along the x axis, B=(cos theta, sin theta) in polar coordinates. Then A dot B = cos theta.
- For unit vectors, A dot B is:
- 1 if A and B lie in the same direction (angle=0)

- 0 if A and B are orthogonal (angle=90)
- -1 if A and B lie in the opposite directions (angle=180)
- Always the "signed length" of the projection of A onto B
(or vice versa).

- For any vector, A dot A is the square of A's length. For a unit vector, A dot A is 1.
- In general, A dot B = length(A) * length(B) * cos(angle
between A and B)

- Dot product is commutative: A dot B = B dot A

- Dot product distributes like multiplication: A dot (B + C) = A dot B + A dot C
- Dot product is friendly with scalars: c*(A dot B) = (c*A) dot B = A dot (c*B)
- "A dot B" is the math notation. In code you usually write "float f = dot(A,B);" or "var f=A.dot(B);".
- Dot product is very handy in computer graphics for computing
diffuse (Lambertian) lighting:
for surface normal N and light direction L, "float light =
dot(N,L);".

- Coordinate frames
- A set of 3 orthogonal and normalized (orthonormal) vectors
(call them S, U, and V) is actually a rotation matrix, and it
has some magical properties.

- The magic is if I take any point X=s*S+u*U+v*V, then

- X dot S = (s*S+u*U+v*V) dot S

- X dot S = s * (S dot S) + u * (U dot S) + v * (V dot S)
- X dot S = s*1 + u * 0 + v * 0 (because S
is unit, and S, U, and V are orthogonal)

- or X dot S = s
- That is, the 's' coordinate of the (S,U,V) coordinate system is just X dot S!
- To get into the coordinate system: dot the incoming vector with each axis.
- s=X dot S; u=X dot U; v=X dot V;
- To get out of the coordinate system: scale each axis by the coordinates.
- X=s*S+u*U+v*V;
- To put the coordinate origin at W, just subtract W from X before dotting (or, subtract W dot S after dotting)
- Cross product: compute a new vector orthogonal to the two
source vectors

- A cross B = (A.y*B.z-A.z*B.y, A.z*B.x-A.x*B.z, A.x*B.y-A.y*B.x)
- On your right hand, if your index finger is A, and your middle finger is B, your thumb points along "A cross B".
- "A cross B" is the math notation. In code you usually
write "vec3 C = cross(A,B);" or "var C=A.cross(B);".

- The vector A cross B is orthogonal to both A and B. (dot(A,C) = dot(B,C) = 0)
- length(cross(A,B)) == length(A)*length(B)*sin(angle between
A and B)

- Cross product can be used to make any two non-orthogonal vectors A and B into an orthogonal frame (X,Y,Z). The idiomatic use is:
- X = A (pick a vector to be one axis)

- Z = A cross B (new 'Z' axis is orthogonal to A/B
plane)

- Y = Z cross X
- Note that the cross product is anti-commutative: A cross B =
- B cross A

- No operator overloading, so you need "a.addSelf(b)" instead of "a+=b". This makes expressions like "P+=dt*V+0.5*dt*dt*A;" quite painful.
- No function overloading, so "dot(a,b)" or "normalize(c)" can't work with both vec2 and vec3. Instead, it's a method call like "a.dot(b)" or "c.normalize()".
- Low performance, even for a CPU.

For example:

Operation |
GLSL or "osl/vec3.h" |
THREE.Vector3; |

Vector addition |
vec3 c=a+b; |
var c=a.clone().addSelf(b); |

Incremental addition |
c+=d; |
c.addSelf(d); |

Vector scaling |
vec3 s=a*0.5; |
var s=a.clone().multiplyScalar(0.5); |

Dot product |
float x=dot(a,b); |
var x=a.dot(b); |

Cosine of angle between vectors |
float cos_ang=dot(a,b) /
(length(a)*length(b)); |
var cos_ang=a.dot(b) /
(a.length()*b.length()); |

Make unit vector |
vec3 d=normalize(p); |
var d=p.clone().normalize(); |

For examples, see the calculations in the boundary planes demo or the boundary sphere demo.