Skip to content
Snippets Groups Projects
Commit 39627e4f authored by Paul McCarthy's avatar Paul McCarthy
Browse files

1. Display -> voxel transformation moved from fragment shaders to generic

vertex shader.

2. Bounds test used in gl21/[tensor/volume]_frag moved to separate file.

3. Transformation matrix offset by 0.5, in Display class, removed, as
I've decided that it should be unnecessary.
parent b2e69d53
No related branches found
No related tags found
No related merge requests found
......@@ -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)
......
......@@ -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
......
......@@ -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)
*/
......
......@@ -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)
*/
......
/**
* 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
......@@ -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]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment