Passing of Vertex Attributes

To use the data of VBOs for the used-defined
in
variables, the usual procedure will be as follows:

With glGetAttribLocation a location identifier for an in variable is queried.
For example, when the variable in the shader code is called "inputColor"

int colorLoc = glGetAttribLocation(progID, "inputColor");

The function glVertexAttribPointer(colorLoc, size, type, normalized, stride, offset) then defines the mapping between an in variable
and VBO attribute

Finally, the attribute needs to be activated by

glEnableVertexAttribArray(colorLoc);

In a subsequent call to glDrawArray or glDrawElements with activated VBO the in variable
of the vertex shader is then filled with the attribute data for each drawn vertex

Data Input and Output in the Fragment Shader

User-defined out variables of the vertex shader are interpolated in the rasterizer and the interpolated values are supplied as in variables
to the fragment shader

The out variables of the fragment shader will be sent to the framebuffer

For example, if the out variable "outputColor" should be written into the first color buffer
of the framebuffer, this can be achieved by

glBindFragDataLocation(progID, 0, "outputColor");

Uniform Variables

In addition to in variables, uniform variables are another way to pass data to a shader

In contrast to the in variables that contain the vertex attributes, the uniform variables
include data that remains constant for all vertices during a call to glDrawArray or glDrawElements

Uniform Variables

The location identifier of a uniform variable can be queried by

paraLoc = glGetUniformLocation(progID, "parameter");

Afterwards, the uniform variable can be set with

glUniform1i(paraLoc, 123);

or, if the variable is a float-vector

glUniform3fv(threeVectorLoc, 1, threeVector);

and in case of a matrix

glUniformMatrix4fv(modelviewLoc, 1, transpose, modelview);

Example: Passing the Transformation Matrices As Uniforms

In this example, the modelview matrix and the projection matrix are passed as uniform variables.
The functionality of the GL_MODELVIEW and GL_PROJECTION matrices (which are known from the fixed-function pipeline) are simulated.

Example: Passing the Transformation Matrices As Uniforms

Transformation of Surface Normals

The modelview matrix transforms vertices from the local coordinate system to the camera coordinate system

A later application of illumination models requires that the surface normal of each vertex is also transformed from the local coordinate system to the camera coordinate system

So far, the fixed-function pipeline has taken care of the transformation of normals. With shaders, this is now also a task of the programmer.

Transformation of Surface Normals

When transforming surface normals, it should be considered that a normal is a unit vector that is neither translated nor scaled
during a transformation with the modelview matrix $\mathtt{T}_{\mathrm{\small modelview}}$. It is only rotated.

Problem: How can the transformation matrix $\mathtt{T}_{\mathrm{\small normal}}$ of the normal be calculated from the
modelview matrix $\mathtt{T}_{\mathrm{\small modelview}}$ ?

$\mathbf{V}_1$

$\mathbf{V}_2$

$\tilde{\mathbf{V}}_2$

$\tilde{\mathbf{V}}_1$

$\mathtt{T}_{\mathrm{\small modelview}}$

$\mathbf{N}$

$\tilde{\mathbf{N}}$

$\tilde{\mathbf{N}}'= \mathtt{T}_{\mathrm{\small
normal}} \mathbf{N}$

$\mathbf{M}$

$\tilde{\mathbf{M}}$

Camera coordinate system

Local coordinate system

Transformation of Surface Normals

Observation: In the local coordinate system the normal $\mathbf{N}=(n_x,n_y,n_z,0)^{\top}$ is orthogonal to the tangent $\mathbf{M}=(m_x,m_y,m_z,0)^{\top}$.
Because of the transformation with $\mathtt{T}_{\mathrm{\small modelview}}$ the normal is mapped wrongly, but the tangent is still pointing in the right direction

Approach: Before the transformation, it holds that $\mathbf{N}^{\top}\mathbf{M} = 0$ and this relationship should be maintained after the transformation, therefore: