sunLoadingImage
whowedImag
decoration left 1
decoration left 2
transhome
transprojects
transgallery
transarticles
decoration rigth
English

Show/Hide search bar
black cat logo variable logo
[27 Dec 2012]

Useful vectors in Computer Graphics

Normal of a triangle

Calculation of normals for triangles can be useful when polygonal mesh was saved without normals, when its required to determine normal to plane, etc. To calculate normal to triangle we need two vectors: a and b. Cross product of these vectors will give normal to the triangle. Direction of normal depends on order of vectors in cross product.

Vector a
Vector b
Normal of triangle
Normal to triangle
Normal at a vertex

In polygonal meshes each vertex is usually shared by multiple triangles. How to determine normal for such vertex? We can copy each shared vertex in such a way that it will be unique for triangle, and assign triangles normals to appropriate vertices. This will lead to visible changes between polygons during lighting. This may be desirable effect, for example, for cube mesh, where each side has normals that are equal to normals of triangles. If visual difference between polygons is undesirable, then normals should be smoothed. Therere following methods for calculation of smoothed normals (result should be normalized in all cases):

  • add together normals of all triangles that share vertex. N=N1+N2+N3. This method is used most often.
  • multiply normal of each triangle by area of the appropriate triangle. Then add together normals of all triangles that share vertex. N=N1*A1+N2*A2+N3*A3. Area of a triangle is calculated as half of the cross product of triangles edges.
  • multiply normal of each triangle by angle adjacent to the vertex. N=N1*q1+N2*q2+N3*q3. Angle is calculated as acos of dot product of edges that are adjacent to the vertex.
  • combined method. Normals are weighted by areas of triangles and by adjacent angles. N=N1*A1*q1+N2*A2*q2+N3*A3*q3.
    Smoothed normal
    Normal to a line

    To find normal to a line in 2D space it's required only to swap x and y components of line's direction, and to invert one of them. So if line has direction (x, y), then normals to this line are n=(-y, x) or
    n=(y, -x). These two normals point in opposite directions.

    Line has infinite number of normals in 3D space. To find any of these normals, we can use cross product. Let line has direction a. Take an arbitrary vector b with direction that isn't equal to a (and not opposite). Result of cross product (n) of vectors a and b will be perpendicular to line.

    Normal to line
    Tangent and normal to curve

    Tangent to curve can be calculated with help of first derivative of curve's equation, and normal as perpendicular to tangent. For example for 2D case, for equations like y=f(x):

  • Equation of curve
  • Equation of curve
  • Point where tangent is required
  • Point where tangent is required
  • First derivative of curve's equation
  • First derivative of curve

    Find gradient at the point of interest (pass x coordinate of the point to derivative). Gradient shows how y depends on change of x.

  • Gradient at point (2,4)
  • Gradient at point (2,4)

    So, if x changes by 1, then y changes by 4. Find equation of tangent line with tilt that corresponds to gradient, and passes through point (2,4). You can use equation of line for this:

  • Equation of line
  • Equation of line
  • Equation of line in form y=f(x)
  • Equation of line in form y=f(x)
  • Tangent at point (2,4)
  • Tangent at point (2,4)
    Curve and tangent
    Tangent to curve without explicit equation

    In many cases equation of curve is unknown. In case if curve is parametric, like Bezier curve, then each point along the curve can be represented as parametric value t. If t represents point on the curve, then t+Δ represents next point on the curve (imagine that Δ is infinitesimally small value). Tangent to curve at point t can be calculated as direction from point t to point t+Δ. For floating point calculations Δ is small value, but at the same time it should be sufficient to calculate direction. The direction will be close to real tangent. Normal is calculated as perpendicular to tangent.

    Tangent and normal to curve
    Light vector, eye vector and half vector

    During calculation of lighting following vectors are used:

    Vectors for local lighting
  • n - normal to the surface. Usually it's calculated by interpolation of normals of triangle's vertices.
  • v - eye vector. It's calculated as direction from point on the surface P to position of the camera.
  • L - light vector. It's calculated as direction from point on the surface P to position of the light. If light source doesn't have defined position (like directional light), then light vector is equal to direction of light source. If light isn't point light source, and it has physical volume, then position of light is defined as finite number of positions inside light's volume.
  • r - reflected vector. It's used for simulation of highlights, mirror surfaces, calculation of bounced rays, etc.
  • t - refracted vector. It's used for simulation of transparent and translucent objects.
  • h - half vector. It's calculated as normalized sum of vectors L and v. From the image you can see that angle between vectors n and h is approximation to angle between vectors v and r. This property is used during calculaiton of specular lighting in standard Blinn-Phong lighting model (so there's no need to calculate reflected vector r).
    Reflected vector

    Reflected vector is calculated as reflection about the axis (in our case - about normal of the surface). In GLSL reflected vector can be calculated with help of reflect() function. It requires incident vector and normal vector as input arguments. Actual calculation of reflected vector is following (n and L vectors should be normalized):

  • calculate length of t - projection of vector L on vector n (dot product of n and L).
  • calculate position of point T1 as doubled t in direction of n.
  • calculate point T2 by substraction of L from T1.
  • reflected vector is equal to vector from point on the surface P to point T2.


    Calculation of reflected vector R
    Refracted vector

    Refracted vector is calculated according to Slell's Law. In GLSL refracted vector can be calculated with help of refract() function. It requires incident vector, normal vector and ratio of indexes of refraction (n1/n2) as input parameters. Actual calculation of refracted vector is following (n and L vectors should be normalized):

  • Cosine of angle near incident ray
  • Cosine of angle near incident ray
  • Sine of angle near incident ray
  • Sine of angle near incident ray
  • Cosine of angle near refracted ray
  • Cosine of angle near refracted ray
  • Sine of angle near refracted ray
  • Sine of angle near refracted ray
    Now we can calculate cosine of angle γ:
  • Substitute sine θ with cosine θ
  • Substitute sine θ with cosine θ
  • Substitute sine γ with cosine θ
  • Substitute sine γ with cosine θ

    Now we have all required values for calculation of refracted vector. As you can see from the image, refracted vector is based on two components: part along incident ray and part along normal (yellow line). So final formula for refracted ray is:

    Formula for calculation of refracted vector Calculation of refracted vector t
    Orthogonalization of vectors

    Three self orthogonal vectors can be used to create new coordinate system, frame of reference, tangent space, etc. Imagine that we have three vectors and these vectors should be axes of new coordinate system. But these vectors aren't necessarily perpendicular. The algorithm for transformation of three arbitrary vectors to orthonormal basis is called orthogonalization. Orthogonalized vectors will differ from initial vectors. In most cases orthogonalization is done by Gram-Schmidt process:

  • Among three vectors select vector that will coincide with the axis Y'. For example, vector Y.
    Basic axis
  • Select next vector - X. It is not perpendicular to Y' axis. The deviation from perpendicularity can be expressed as displacement d1 along direction that is opposite to axis Y'. Offset can be determined by dot product. So add offset to vector X and normalize result. Result will be orthogonal to Y', and it is new axis - X'.
    Second axis
  • Now take vector Z. It is not perpendicular to both Y' and X' axes. Determine diviations from perpendicularity for vector Z (d2 and d3) for axes X' and Y'. Offset vector Z along -X' by distance d2 and along -Y' by distance d3, and normalize result. Now you have Z' axis.
    Third axis
    Orthogonalization of vectors

    Result of Gram-Schmidt orthogonalization depends on choise of first vector. First vecror will coincide with axis, and other two vectors will be modified in order to be orthogonal. In many cases it's ok, for example, during calculation of tangent space, when normal of the surface should be fixed. But for some cases it's preferable to preserve similarity between initial vectors and orthogonalized vectors as much as possible. In such case you can use iterative Gram-Schmidt orthogonalization. On each iteration take next vector, calculate required offset, but modify vector only by small amount of offset. Repeat this for some time, and then perform standard Gram-Schmidt orthogonalization. New axes will be more similar to the initial vectors.




  • Sun and Black Cat- Igor Dykhta (igor dykhta email) 2007-2014