Last Updated <November 7, 2012> -->

The final stage of the vertex transformation process is to map the points from the normalized view volume to their final position in the viewport on screen. We want to transform the view volume to the shape and position of the viewport.

The normalised view volume is a cube centred on the origin, bounded by points $(-1,-1,-1)$ and $(1,1,1)$. The u and v coordinates of each point will be transformed to x and y screen coordinates (pixel coordinates) and we will scale the n coordinates (pseudo-depth) to a range between 0 and 1 (scale the front plane to 0 and the back plane to 1), this depth value will be called $z$.

The x,y sceen coordinates wil be used to draw the pixel in the refresh buffer. The z value will be stored in the depth buffer for hidden surface removal.

The viewport transformation will be represented by a 4x4 matrix. It encapsulates 2 stages

- a scaling to the shape of the viewport
- a transformation to the position of the viewport

The viewport is defined as the rectangle between $(v_l,v_b)$ and $(v_r,v_t)$

The view-volume needs to be scaled to the width and height of the viewport. At this stage we will also scale the pseudo-depth to a range of 0 to 1. The normalised view volume has a height, width and depth of $2$.

The width of the viewport is $v_r-v_l$ and the height of the view port is $v_t-v_b$

To scale a value from one range of values to another, we divide by the size of the original range and multiply by the size of the new range.

Compare this process to the normalization transformation

Therefore the scaling matrix required is;

\[ \mbox{${\mathbf{\hat{S}}}$}=\left(\begin{array}{ccccc} \frac{v_r-v_l}{2}&0&0&0 \\ 0&\frac{v_t-v_b}{2}&0&0 \\ 0&0&\frac{1}{2}&0 \\ 0&0&0& 1 \end{array} \right) \]Finally we need to translate the scaled normalised view volume to the position of the viewport. This is a combination of two translations; first translate to the origin (add $\frac{v_r-v_l}{2}$ to $u$ and add $\frac{v_t-v_b}{2}$ to $v$. Second move from the origin to the position of the viewport (add $v_l$ and $v_b$ to $u$ and $v$). The n-coordinate (now in the range $\left\{-\frac{1}{2}\cdots\frac{1}{2}\right\}$) needs to be shifted by $+\frac{1}{2} $

Note; $\frac{v_r-v_l}{2} +v_l=\frac{v_r+v_l}{2}$, similarly the translation for $v$ is $\frac{v_t+v_b}{2}$.

So the translation matrix is;

\[ \mbox{${\mathbf{\hat{T}}}$}=\left(\begin{array}{ccccc} 1&0&0&\frac{v_r+v_l}{2}\\ 0&1&0&\frac{v_t+v_b}{2}\\ 0&0&1&\frac{1}{2}\\ 0&0&0&1 \end{array} \right) \]

Combining the above two transfomations gives us the Viewport Transformation Matrix;

\[ \mathbf{\hat{V_p}}=\mathbf{\hat{T}}\mathbf{\hat{S}} =\left(\begin{array}{ccccc} \frac{v_r-v_l}{2}&0&0&\frac{v_r+v_l}{2}\\ 0&\frac{v_t-v_b}{2}&0&\frac{v_t+v_b}{2}\\ 0&0&\frac{1}{2}&\frac{1}{2}\\ 0&0&0&1 \end{array} \right)\]

The aspect ratio is the relationship of the width of the viewport to its height $\frac{width}{height}$, this is sometimes written as $width:height$ as in $4:3$ or $16:9$.

It is important that the aspect ratio of the viewport is the same as the aspect ratio of the viewvolume in order to avoid distortion.

In OpenGL the viewport transformation is controlled by the function glViewPort() which is used to set the size and position of the viewport.

© Ken Power 1996-2016