diff --git a/fsl/fslview/displaycontext/display.py b/fsl/fslview/displaycontext/display.py
index 15781f8730aff23d98462d5872c063da3a22eef5..9616e3cbe87fa93efbe3ce2d9853c3d0b4672f82 100644
--- a/fsl/fslview/displaycontext/display.py
+++ b/fsl/fslview/displaycontext/display.py
@@ -4,7 +4,15 @@
 #
 # Author: Paul McCarthy <pauldmccarthy@gmail.com>
 #
-"""
+"""This module provides definitions of an important class - the
+:class:`Display` class.
+
+A ``Display`` contains a specification for the way in which an
+:class:`~fsl.data.image.Image` instance is to be displayed.
+
+
+..note:: Put a description of the three coordinate systems which
+         exist in the system.
 """
 
 import logging
@@ -295,12 +303,6 @@ class Display(props.SyncableHasProperties):
         elif self.transform == 'affine':
             voxToDisplayMat = self.voxToWorldMat
 
-        # for pixdim/identity transformations, we want the world
-        # location (0, 0, 0) to map to voxel location (0, 0, 0)
-        if self.transform in ('id', 'pixdim'):
-            for i in range(3):
-                voxToDisplayMat[3, i] =  pixdim[i] * 0.5
-
         # Transformation matrices for moving between the voxel
         # coordinate system and the display coordinate system
         self.voxToDisplayMat = np.array(voxToDisplayMat, dtype=np.float32)
diff --git a/fsl/fslview/gl/gl21/generic_vert.glsl b/fsl/fslview/gl/gl21/generic_vert.glsl
index 719683b2c0c5b22b685e21bdf6491f71a7f95742..abef9271bbcd979692143e8ce21706b683c88221 100644
--- a/fsl/fslview/gl/gl21/generic_vert.glsl
+++ b/fsl/fslview/gl/gl21/generic_vert.glsl
@@ -8,6 +8,9 @@
  */
 #version 120
 
+
+uniform mat4 displayToVoxMat;
+
 /*
  * Optional transformation matrix which is applied to all
  * vertex coordinates (used by the e.g. lightbox canvas to
@@ -38,6 +41,12 @@ uniform float zCoord;
 varying vec3 fragTexCoords;
 
 
+/* 
+ * Image voxel coordinates corresponding to this vertex.
+ */ 
+varying vec3 fragVoxCoords;
+
+
 void main(void) {
 
     vec4 worldLoc = vec4(0, 0, 0, 1);
@@ -45,6 +54,26 @@ void main(void) {
     worldLoc[yax] = worldCoords.y;
     worldLoc[zax] = zCoord;
 
+    /*
+     * Transform the texture coordinates into voxel coordinates
+     */
+    fragVoxCoords = (displayToVoxMat * worldLoc).xyz;
+
+    /*
+     * Centre voxel coordinates - the display space of a voxel
+     * at a particular location (x, y, z) extends from
+     *
+     * (x-0.5, y-0.5, z-0.5)
+     *
+     * to
+     *
+     * (x+0.5, y+0.5, z+0.5),
+     *
+     * so we need to offset the coordinates by 0.5 to
+     * make the coordinates usable as voxel indices
+     */
+    fragVoxCoords.xyz = fragVoxCoords.xyz + 0.5;
+
     /*
      * Pass the vertex coordinates as texture
      * coordinates to the fragment shader
diff --git a/fsl/fslview/gl/gl21/gltensor_rgb_frag.glsl b/fsl/fslview/gl/gl21/gltensor_rgb_frag.glsl
index 76b28d8243a52bad5e95de4756be44b435606e0f..0cd2cdfe070b3e273b423daade81a18280691818 100644
--- a/fsl/fslview/gl/gl21/gltensor_rgb_frag.glsl
+++ b/fsl/fslview/gl/gl21/gltensor_rgb_frag.glsl
@@ -7,6 +7,8 @@
 
 #pragma include spline_interp.glsl
 
+#pragma include test_in_bounds.glsl
+
 /*
  * image data texture
  */
@@ -29,50 +31,26 @@ uniform vec3 imageShape;
  */
 uniform bool useSpline;
 
-/*
- * Transformation from display space to voxel coordinates.
- */
-uniform mat4 displayToVoxMat;
-
 /*
  * Image texture coordinates. 
  */
 varying vec3 fragTexCoords;
 
+/*
+ * Image voxel coordinates
+ */
+varying vec3 fragVoxCoords;
 
 void main(void) {
 
-    /*
-     * Transform the texture coordinates into voxel coordinates
-     */
-    vec4 voxCoords = displayToVoxMat * vec4(fragTexCoords, 1);
+    vec3 voxCoords = fragVoxCoords;
 
-    /*
-     * Centre voxel coordinates
-     */
-    voxCoords.xyz = voxCoords.xyz + 0.5;
+    if (!test_in_bounds(voxCoords, imageShape)) {
 
-    /*
-     * Don't render the fragment if it's outside the image space
-     */
-    if (voxCoords.x < -0.01 || voxCoords.x >= imageShape.x + 0.01 ||
-        voxCoords.y < -0.01 || voxCoords.y >= imageShape.y + 0.01 ||
-        voxCoords.z < -0.01 || voxCoords.z >= imageShape.z + 0.01) {
-        
         gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
         return;
     }
 
-    /*
-     * Be lenient at voxel boundaries
-     */
-    if (voxCoords.x <  0.0)          voxCoords.x = 0.01;
-    if (voxCoords.y <  0.0)          voxCoords.y = 0.01;
-    if (voxCoords.z <  0.0)          voxCoords.z = 0.01; 
-    if (voxCoords.x >= imageShape.x) voxCoords.x = imageShape.x - 0.01;
-    if (voxCoords.y >= imageShape.y) voxCoords.y = imageShape.y - 0.01;
-    if (voxCoords.z >= imageShape.z) voxCoords.z = imageShape.z - 0.01;
-
     /* 
      * Normalise voxel coordinates to (0.0, 1.0)
      */
diff --git a/fsl/fslview/gl/gl21/glvolume_frag.glsl b/fsl/fslview/gl/gl21/glvolume_frag.glsl
index e850a297a4c45bce0bbebc6f1bc0e22d22e015d2..15a508dd10a92fd0f2324fca9b0ce13983a81ac4 100644
--- a/fsl/fslview/gl/gl21/glvolume_frag.glsl
+++ b/fsl/fslview/gl/gl21/glvolume_frag.glsl
@@ -6,6 +6,7 @@
 #version 120
 
 #pragma include spline_interp.glsl
+#pragma include test_in_bounds.glsl
 
 /*
  * image data texture
@@ -27,11 +28,6 @@ uniform sampler1D colourTexture;
  */
 uniform bool useSpline;
 
-/*
- * Transformation from display space to voxel coordinates.
- */
-uniform mat4 displayToVoxMat;
-
 /*
  * Transformation matrix to apply to the 1D texture coordinate.
  */
@@ -43,39 +39,22 @@ uniform mat4 voxValXform;
 varying vec3 fragTexCoords;
 
 
-void main(void) {
+/*
+ * Image voxel coordinates
+ */
+varying vec3 fragVoxCoords;
 
-    /*
-     * Transform the texture coordinates into voxel coordinates
-     */
-    vec4 voxCoords = displayToVoxMat * vec4(fragTexCoords, 1);
 
-    /*
-     * Centre voxel coordinates
-     */
-    voxCoords.xyz = voxCoords.xyz + 0.5;
+void main(void) {
 
-    /*
-     * Don't render the fragment if it's outside the image space
-     */
-    if (voxCoords.x < -0.01 || voxCoords.x >= imageShape.x + 0.01 ||
-        voxCoords.y < -0.01 || voxCoords.y >= imageShape.y + 0.01 ||
-        voxCoords.z < -0.01 || voxCoords.z >= imageShape.z + 0.01) {
+    vec3 voxCoords = fragVoxCoords;
+
+    if (!test_in_bounds(voxCoords, imageShape)) {
         
         gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
         return;
     }
 
-    /*
-     * Be lenient at voxel boundaries
-     */
-    if (voxCoords.x <  0.0)          voxCoords.x = 0.01;
-    if (voxCoords.y <  0.0)          voxCoords.y = 0.01;
-    if (voxCoords.z <  0.0)          voxCoords.z = 0.01; 
-    if (voxCoords.x >= imageShape.x) voxCoords.x = imageShape.x - 0.01;
-    if (voxCoords.y >= imageShape.y) voxCoords.y = imageShape.y - 0.01;
-    if (voxCoords.z >= imageShape.z) voxCoords.z = imageShape.z - 0.01;
-
     /* 
      * Normalise voxel coordinates to (0.0, 1.0)
      */
diff --git a/fsl/fslview/gl/gl21/test_in_bounds.glsl b/fsl/fslview/gl/gl21/test_in_bounds.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..d01b2dd56e853a5e7c7fec4591b78ae66fcb7626
--- /dev/null
+++ b/fsl/fslview/gl/gl21/test_in_bounds.glsl
@@ -0,0 +1,29 @@
+/**
+ * Simple bounds test to determine whether the given voxel coordinates
+ * are within the bounds specified by the given array/image shape.
+ */
+bool test_in_bounds(inout vec3 coords, vec3 shape) {
+
+    /*
+     * Don't render the fragment if it's outside the image space
+     */
+    if (coords.x < -0.01 || coords.x >= shape.x + 0.01 ||
+        coords.y < -0.01 || coords.y >= shape.y + 0.01 ||
+        coords.z < -0.01 || coords.z >= shape.z + 0.01) {
+        
+        return false;
+    }
+
+    /*
+     * Be lenient at voxel boundaries
+     */
+    if (coords.x <  0.0)     coords.x = 0.01;
+    if (coords.y <  0.0)     coords.y = 0.01;
+    if (coords.z <  0.0)     coords.z = 0.01; 
+    if (coords.x >= shape.x) coords.x = shape.x - 0.01;
+    if (coords.y >= shape.y) coords.y = shape.y - 0.01;
+    if (coords.z >= shape.z) coords.z = shape.z - 0.01;
+
+
+    return true;
+}
\ No newline at end of file
diff --git a/fsl/utils/transform.py b/fsl/utils/transform.py
index 1ffea567dda9e29ae8efd9df46219a4135db71f6..f8d427ca3bc09276442ded2312020db754b64969 100644
--- a/fsl/utils/transform.py
+++ b/fsl/utils/transform.py
@@ -51,7 +51,21 @@ def scaleOffsetXform(scales, offsets):
 
 
 def axisBounds(shape, xform, axes=None):
-    """Returns the (lo, hi) bounds of the specified axis/axes."""
+    """Returns the (lo, hi) bounds of the specified axis/axes.
+
+    This function assumes that voxel indices correspond to the voxel
+    centre. For example, the voxel at ``(4, 5, 6)`` covers the space:
+    
+      ``[3.5 - 4.5, 4.5 - 5.5, 5.5 - 6.5]``
+    
+    So the bounds of the specified shape extends from the corner at
+
+    ``(-0.5, -0.5, -0.5)``
+
+    to the corner at
+
+    ``(shape[0] - 0.5, shape[1] - 0.5, shape[1] - 0.5)``
+    """
 
     scalar = False
 
@@ -64,12 +78,12 @@ def axisBounds(shape, xform, axes=None):
     
     x, y, z = shape[:3]
 
+    points = np.zeros((8, 3), dtype=np.float32)
+
     x -= 0.5
     y -= 0.5
     z -= 0.5
 
-    points = np.zeros((8, 3), dtype=np.float32)
-
     points[0, :] = [-0.5, -0.5, -0.5]
     points[1, :] = [-0.5, -0.5,  z]
     points[2, :] = [-0.5,  y,   -0.5]