Cg Programming/Vector and Matrix Operations

The syntax of Cg is very similar to C (and therefore C++ and Java); however, there are built-in data types and functions for floating-point vectors and matrices, which are specific to Cg. These are discussed here. A full description of Cg can be found in Nvidia's Cg Tutorial and in Nvidia's Cg Language Specification.

Floating-Point Data Types with Full Precision
In Cg, the types,  , and   represent 2D, 3D, and 4D floating-point vectors. Vector variables are defined as you would expect if C, C++ or Java had these types:

The data types for floating-point 2×2, 3×3, and 4×4 matrices are:,  , and  : There are also types for matrices with different numbers of rows and columns, e.g. 3 rows and 4 columns:.

Data Types with Limited Precision
Apart from  data types, there are additional   types (,  ,  ,  ,  ,  ,  , etc.), and   types ( ,  ,  ,  , etc.), which represent numbers (i.e. scalars), vectors, and matrices of limited precision and range. Usually they provide better performance; thus, for best performance you should use one of the  types instead of the corresponding   types (in particular if the data represents geometric positions or texture coordinates) or even one of the   types (usually if the data represents colors) if the limited precision and range does not result in rendering artifacts.

Here, the code will always use the  types to avoid any problems related to limited precision and to keep it as simple as possible. There are also types for integer and boolean vectors, which will not be discussed here.

Constructors
Vectors can be initialized and converted by constructors of the same name as the data type: Note that some Cg compilers might complain if integers are used to initialize floating-point vectors; thus, it is good practice to always include the decimal point.

Casting a lower-dimensional vector to a higher-dimensional vector is achieved by supplying these constructors with the correct number of components:

Similarly, matrices can be initialized and constructed. Note that the values specified in a matrix constructor are consumed to fill the first row, then the second row, etc.:

Cg (but not all versions of HLSL) also accepts one floating-point number in the  constructor to set all components to the same value:

Furthermore, Cg (but not all versions of HLSL) can cast a higher-dimensional vector to a lower-dimensional vector with the vector constructors:

If a smaller matrix is constructed from a larger matrix, the top, left submatrix of the larger matrix is chosen:

Components
Components of vectors are accessed by array indexing with the -operator (indexing starts with 0) or with the  -operator and the element names   or   (or  ):

It is also possible to construct new vectors by extending the -notation:

Matrices are considered to consist of row vectors, which are accessed by array indexing with the -operator. Elements of the resulting (row) vector can be accessed as discussed above:

Operators
If the binary operators  are used between vectors of the same type, they just work component-wise: Note in particular that  represents a component-wise product of two vectors, which is not often seen in linear algebra. For matrices, these operators also work component-wise. Again, a component-wise product of two matrices is not often seen in linear algebra.

For the usual matrix-vector product or matrix-matrix product, see the built-in  function below. For the dot product and cross product between vectors, see the built-in functions  and   below.

The -operator can also be used to multiply a floating-point value (i.e. a scalar) to all components of a vector or matrix (from left or right):

Component-Wise Functions
The following functions work component-wise for variables of type,  ,  ,  ,  ,  ,  ,  ,  ,  ,  , and  , which are denoted as  : There are more built-in functions, which also work component-wise but are less useful for vectors, e.g.,,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,   (converts degrees to radians),   (converts radians to degrees),  ,  ,  ,  ,  ,  ,.

Matrix Functions
For the usual matrix-matrix product in linear algebra, the  function should be used. It computes components of the resulting matrix by multiplying a row (of the first matrix) with a column (of the second matrix), e.g.:

$$\mathrm{A} \mathrm{B} = \left[ \begin{matrix} a_{1,1} & a_{1,2} \\ a_{2,1} & a_{2,2} \end{matrix} \right] \left[ \begin{matrix} b_{1,1} & b_{1,2} \\ b_{2,1} & b_{2,2} \end{matrix} \right]$$ $$ = \left[ \begin{matrix} a_{1,1} b_{1,1} + a_{1,2} b_{2,1} & a_{1,1} b_{1,2} + a_{1,2} b_{2,2} \\ a_{2,1} b_{1,1} + a_{2,2} b_{2,1} & a_{2,1} b_{1,2} + a_{2,2} b_{2,2} \end{matrix} \right]$$

And in Cg:

Furthermore, the  function can be used for matrix-vector products of the corresponding dimension, e.g.:

$$\mathrm{M} \mathbf{v} = \left[ \begin{matrix} m_{1,1} & m_{1,2} \\ m_{2,1} & m_{2,2} \end{matrix} \right] \left[ \begin{matrix} v_{1} \\ v_{2} \end{matrix} \right]$$ $$= \left[ \begin{matrix} m_{1,1} v_{1} + m_{1,2} v_{2}\\ m_{2,1} v_{1} + m_{2,2} v_{2} \end{matrix} \right]$$

And in Cg:

Note that the vector has to be the second argument to be multiplied to the matrix from the right.

If a vector is specified as first argument, it is multiplied to a matrix from the left:

Multiplying a row vector from the left to a matrix corresponds to multiplying a column vector to the transposed matrix from the right:

$$\mathbf{v}^T \mathrm{M} = \left(\mathrm{M}^T \mathbf{v}\right)^T $$

In components:

$$\mathbf{v}^T \mathrm{M} = \left[ \begin{matrix} v_{1} & v_{2} \end{matrix} \right] \left[ \begin{matrix} m_{1,1} & m_{1,2} \\ m_{2,1} & m_{2,2} \end{matrix} \right]$$ $$= \left[ \begin{matrix} v_{1} m_{1,1} + v_{2} m_{2,1} & v_{1} m_{1,2} + v_{2} m_{2,2} \end{matrix} \right]$$ $$= \left( \left[ \begin{matrix} m_{1,1} & m_{2,1} \\ m_{1,2} & m_{2,2} \end{matrix} \right] \left[ \begin{matrix} v_{1} \\ v_{2} \end{matrix} \right]\right)^T$$ $$= \left(\mathrm{M}^T\mathbf{v}\right)^T$$

Thus, multiplying a vector from the left to a matrix corresponds to multiplying it from the right to the transposed matrix without explicitly computing the transposed matrix.

There is also a function  to compute the transposed matrix:

Geometric Functions
The following functions are particularly useful for vector operations. is any of:,  ,  ,  ,  ,  ,  ,  ,  , and   (only one of them per line).

Functions for Physics
The function computes the direction of a refracted ray if  specifies the normalized(!) direction of the incoming ray and   specifies the normalized(!) normal vector of the interface of two optical media (e.g. air and water). The vector  should point to the side from where   is coming, i.e. the dot product of   and   should be negative. The floating-point number  is the ratio of the refractive index of the medium from where the ray comes to the refractive index of the medium on the other side of the surface. Thus, if a ray comes from air (refractive index about 1.0) and hits the surface of water (refractive index 1.33), then the ratio  is 1.0 / 1.33 = 0.75. The computation of the function is: As the code shows, the function returns a vector of length 0 in the case of total internal reflection (see the entry in Wikipedia), i.e. if the ray does not pass the interface between the two materials.