Example a/volume_render: Volume rendering of 3-D images of the foot

Reads a series of images from the Visible Human Dataset into one large 3-dimensional texture. Uses hundreds of parallel iso-surfaces aligned with your screen so that you get a volume rendering.

Note that all images used are copyright to and obtained under license from The Visible Human Project.

VHP Home Page

Default render with no pixel processing.

Filter out the blue.

Light the volume.

Screenshot of example a/volume_render

The comfile run by this example is as follows:

# Volume rendering of 3-D images of the foot
# Reads a series of images from the Visible Human Dataset into one large
# 3-dimensional texture.  Isosurfaces are used to generate view slices
# orthogonal to the viewing direction so that a basic volume rendering
# can be produced.
# Note that all images are copyright to and obtained under license
# from the Visible Human Project:
# http://www.nlm.nih.gov/research/visible/visible_human.html
# Read in 128 images of 256x400 resolution into 3-D texture 'foot'. These
# are a cropped subset of the Visible Human Dataset containing just the
# left foot. (You might as well use power-of-two resolutions as I have
# since internal storage is padded to the next highest power-of-two.
# Otherwise keep 3-D textures as small as possible for speed!)
# Since this data has one texture-pixel (or texel) per mm, we set the
# physical size of the texture to 256x400x128.
# Note the image file numbers are substituted into the pattern "0000"
# and go from 1860 to 1733 with an increment of -1.
# The compress parameter requests the graphics hardware to compress the texture
# in its representation of the texture allowing the image to be stored in much less
# memory than uncompressed.
# It takes a few seconds to read in this much image data.
 gfx create texture foot width 256 height 400 depth 128 clamp_wrap linear_filter image $example/foot0000.jpg number_pattern "0000" number_series 1860 1733 -1 compress;

 # Create a material containing the texture that we may select along
 # with appropriate texture coordinates, to visualise the 3-D image
 # on our graphics.
 gfx create material foot texture foot;

 # Read in a 256x400x128 mm single-element block to view the texture in.
 # These dimensions match the physical size and location of the texture.
 # Later we will use the "coordinates" field as texture coordinates.
 gfx read nodes $example/texture_block.exnode
 gfx read elements $example/texture_block.exelem

 #Clear the lines out and set the lowest discritisation as we are only going to 
 #make planes as geometry.
 gfx modify g_element texture_block general clear circle_discretization 6 default_coordinate coordinates element_discretization "1*1*1" native_discretization none;

 #Create our volume viewing window
 gfx create window 1;
 gfx modify window 1 view perspective eye_point 126.1 861.711 818.194 interest_point 128 200 64 up_vector 0.700925 -0.535256 0.471386 view_angle 40 near_clipping_plane 10.0333 far_clipping_plane 3585.56 relative_viewport ndc_placement -1 1 2 2 viewport_coordinates 0 0 1 1;

 # Fields for aligning with the window view
 gfx define field ndc_projection window_projection window 1 from world to normalised_window_fill;
 gfx define field minus_one constant -1
 gfx define field negative_ndc projection field coordinates projection_matrix ndc_projection;
 gfx define field ndc multiply field negative_ndc minus_one
 gfx define field ndc.3 coordinate_system rectangular_cartesian composite ndc.3;
 gfx define field ndc_minimum nodeset_minimum field ndc.3 nodeset nodes
 gfx define field ndc_diff add fields ndc.3 ndc_minimum scale 1 -1
 gfx define field ndc_maximum nodeset_maximum field ndc_diff nodeset nodes
 gfx define field normalise_ndc_3 divide fields ndc_diff ndc_maximum

 gfx mod mat foot alpha 0.015;

 gfx create spectrum filtered_alpha_spectrum clear overwrite;

 sub create_planes
	my $num_planes = shift;
	my $far_depth = 1.0;
	my $near_depth = 0.0;

	gfx modify g_element texture_block iso_surfaces as iso_planes iso_scalar normalise_ndc_3 range_number_of_iso_values $num_planes first_iso_value $far_depth last_iso_value $near_depth use_elements select_on material foot texture_coordinates coordinates selected_material default_selected render_shaded;

	# To help visualise what is going on you can draw the lines around each of the iso_surface planes
	# observing how they update as you adjust your viewing direction
	#	 gfx modify g_element texture_block iso_surfaces iso_scalar ndc.3 iso_values @iso_values use_faces select_on material blue texture_coordinates coordinates selected_material default_selected render_shaded;


 sub filter_blue
	my $alpha = shift;
	my $low_value = shift;
	my $high_value = shift;

	#Hide the blue material by making an alpha spectrum based on the volume
	#colours and filtering out those in the blue zone.

	gfx define field default_alpha constant 1.0;

	#The input colour is really just a place holder for the input to a field
	#spectrum, but by making it a sample texture for the texture which will be
	#rendered then if the output is displayed at element points it will make sense

	gfx define field input_colour sample_texture field foot coordinates coordinates;
	gfx define field blue_value_low constant @$low_value;
	gfx define field blue_value_high constant @$high_value;
	gfx define field blue_value_alpha constant 0.0;

	gfx define field is_above_low_value_components greater_than fields input_colour blue_value_low;
	gfx define field is_above_low_value sum_components field is_above_low_value_components;
	gfx define field is_below_high_value_components less_than fields input_colour blue_value_high ;
	gfx define field is_below_high_value sum_components field is_below_high_value_components;
	gfx define field is_blue_sum add fields is_above_low_value is_below_high_value;
	#There are six tests inequality tests we have added up, all must be true
	gfx define field is_blue equal_to fields is_blue_sum [ 6 ];
	gfx define field not_is_blue equal_to fields is_blue [ 0 ];

	gfx define field masked_alphaA multiply fields is_blue blue_value_alpha;
	gfx define field masked_alphaB multiply fields not_is_blue default_alpha;
	gfx define field filtered_alpha add fields masked_alphaA masked_alphaB;

	gfx modify spectrum filtered_alpha_spectrum clear overwrite;
	gfx modify spectrum filtered_alpha_spectrum field alpha input input_colour output filtered_alpha;

#Now that we are filtering out the blue we can make the stuff we want to see
#less translucent
	gfx modify material foot per_pixel_mode colour_lookup_spectrum filtered_alpha_spectrum colour_lookup_red colour_lookup_green colour_lookup_blue alpha $alpha;

 sub light_volume
	#We need lots more planes for this as the normal will interpolate on 
	#the plane.
	#Let us see inside a bit better too
	filter_blue(0.05, [0, 0, 0], [0.5, 0.6, 1.0]);

	gfx modify window 1 view perspective eye_point 574.81 -101.528 910.236 interest_point 128 200 64 up_vector 0.255918 -0.859967 -0.441545 view_angle 28.0051 near_clipping_plane 10.0333 far_clipping_plane 3585.56 relative_viewport ndc_placement -1 1 2 2 viewport_coordinates 0 0 1 1;

	gfx mod light default point pos 200 400 -1300;

	#Enable lighting
	#The lit_volume_normal_scaling is used to scale the normal so that the
	#magnitude of the greatest difference approaches 1 for lit_volume_scale_alpha
	#and can be used if the texture is scaled unequally in coordinate space
	#to scale the normals equivalently.
	gfx modify material foot per_pixel_mode colour_lookup_spectrum filtered_alpha_spectrum colour_lookup_red colour_lookup_green colour_lookup_blue lit_volume_finite_difference_normal lit_volume_scale_alpha lit_volume_normal_scaling 3 3 3;



# Start with a low number of planes and no fragment programs so it works for everyone

 if ($TESTING)
	filter_blue(0.15, [0, 0, 0], [0.5, 0.6, 1.0]);
	if (0)
		# don't test light_volume as so slow on non-accellerated hardware the test times out on our testing machine:
 gfx modify window 1 set slow

Files used by this example are:

Name                  Modified     Size

volume_render.com 09-Mar-2016 7.4k COPYRIGHT 17-Mar-2014 504 foot1733.jpg 17-Mar-2014 39k foot1734.jpg 17-Mar-2014 39k foot1735.jpg 17-Mar-2014 38k foot1736.jpg 17-Mar-2014 37k foot1737.jpg 17-Mar-2014 38k foot1738.jpg 17-Mar-2014 37k foot1739.jpg 17-Mar-2014 38k foot1740.jpg 17-Mar-2014 37k foot1741.jpg 17-Mar-2014 32k foot1742.jpg 17-Mar-2014 35k foot1743.jpg 17-Mar-2014 35k foot1744.jpg 17-Mar-2014 34k foot1745.jpg 17-Mar-2014 35k foot1746.jpg 17-Mar-2014 37k foot1747.jpg 17-Mar-2014 38k foot1748.jpg 17-Mar-2014 41k foot1749.jpg 17-Mar-2014 42k foot1750.jpg 17-Mar-2014 45k foot1751.jpg 17-Mar-2014 47k foot1752.jpg 17-Mar-2014 49k foot1753.jpg 17-Mar-2014 52k foot1754.jpg 17-Mar-2014 54k foot1755.jpg 17-Mar-2014 58k foot1756.jpg 17-Mar-2014 51k foot1757.jpg 17-Mar-2014 52k foot1758.jpg 17-Mar-2014 51k foot1759.jpg 17-Mar-2014 50k foot1760.jpg 17-Mar-2014 50k foot1761.jpg 17-Mar-2014 51k foot1762.jpg 17-Mar-2014 54k foot1763.jpg 17-Mar-2014 53k foot1764.jpg 17-Mar-2014 52k foot1765.jpg 17-Mar-2014 52k foot1766.jpg 17-Mar-2014 53k foot1767.jpg 17-Mar-2014 54k foot1768.jpg 17-Mar-2014 55k foot1769.jpg 17-Mar-2014 52k foot1770.jpg 17-Mar-2014 52k foot1771.jpg 17-Mar-2014 52k foot1772.jpg 17-Mar-2014 53k foot1773.jpg 17-Mar-2014 52k foot1774.jpg 17-Mar-2014 51k foot1775.jpg 17-Mar-2014 49k foot1776.jpg 17-Mar-2014 51k foot1777.jpg 17-Mar-2014 50k foot1778.jpg 17-Mar-2014 50k foot1779.jpg 17-Mar-2014 49k foot1780.jpg 17-Mar-2014 49k foot1781.jpg 17-Mar-2014 48k foot1782.jpg 17-Mar-2014 48k foot1783.jpg 17-Mar-2014 48k foot1784.jpg 17-Mar-2014 48k foot1785.jpg 17-Mar-2014 47k foot1786.jpg 17-Mar-2014 48k foot1787.jpg 17-Mar-2014 48k foot1788.jpg 17-Mar-2014 47k foot1789.jpg 17-Mar-2014 47k foot1790.jpg 17-Mar-2014 47k foot1791.jpg 17-Mar-2014 47k foot1792.jpg 17-Mar-2014 47k foot1793.jpg 17-Mar-2014 46k foot1794.jpg 17-Mar-2014 46k foot1795.jpg 17-Mar-2014 45k foot1796.jpg 17-Mar-2014 45k foot1797.jpg 17-Mar-2014 44k foot1798.jpg 17-Mar-2014 44k foot1799.jpg 17-Mar-2014 43k foot1800.jpg 17-Mar-2014 43k foot1801.jpg 17-Mar-2014 43k foot1802.jpg 17-Mar-2014 43k foot1803.jpg 17-Mar-2014 42k foot1804.jpg 17-Mar-2014 43k foot1805.jpg 17-Mar-2014 43k foot1806.jpg 17-Mar-2014 43k foot1807.jpg 17-Mar-2014 43k foot1808.jpg 17-Mar-2014 43k foot1809.jpg 17-Mar-2014 43k foot1810.jpg 17-Mar-2014 43k foot1811.jpg 17-Mar-2014 42k foot1812.jpg 17-Mar-2014 42k foot1813.jpg 17-Mar-2014 42k foot1814.jpg 17-Mar-2014 42k foot1815.jpg 17-Mar-2014 42k foot1816.jpg 17-Mar-2014 42k foot1817.jpg 17-Mar-2014 42k foot1818.jpg 17-Mar-2014 41k foot1819.jpg 17-Mar-2014 42k foot1820.jpg 17-Mar-2014 42k foot1821.jpg 17-Mar-2014 43k foot1822.jpg 17-Mar-2014 44k foot1823.jpg 17-Mar-2014 46k foot1824.jpg 17-Mar-2014 49k foot1825.jpg 17-Mar-2014 52k foot1826.jpg 17-Mar-2014 55k foot1827.jpg 17-Mar-2014 55k foot1828.jpg 17-Mar-2014 48k foot1829.jpg 17-Mar-2014 45k foot1830.jpg 17-Mar-2014 44k foot1831.jpg 17-Mar-2014 35k foot1832.jpg 17-Mar-2014 46k foot1833.jpg 17-Mar-2014 45k foot1834.jpg 17-Mar-2014 44k foot1835.jpg 17-Mar-2014 45k foot1836.jpg 17-Mar-2014 45k foot1837.jpg 17-Mar-2014 44k foot1838.jpg 17-Mar-2014 44k foot1839.jpg 17-Mar-2014 43k foot1840.jpg 17-Mar-2014 42k foot1841.jpg 17-Mar-2014 35k foot1842.jpg 17-Mar-2014 32k foot1843.jpg 17-Mar-2014 31k foot1844.jpg 17-Mar-2014 31k foot1845.jpg 17-Mar-2014 31k foot1846.jpg 17-Mar-2014 29k foot1847.jpg 17-Mar-2014 29k foot1848.jpg 17-Mar-2014 30k foot1849.jpg 17-Mar-2014 31k foot1850.jpg 17-Mar-2014 31k foot1851.jpg 17-Mar-2014 31k foot1852.jpg 17-Mar-2014 32k foot1853.jpg 17-Mar-2014 30k foot1854.jpg 17-Mar-2014 28k foot1855.jpg 17-Mar-2014 23k foot1856.jpg 17-Mar-2014 23k foot1857.jpg 17-Mar-2014 21k foot1858.jpg 17-Mar-2014 21k foot1859.jpg 17-Mar-2014 20k foot1860.jpg 17-Mar-2014 20k texture_block.exelem 17-Mar-2014 3.5k texture_block.exnode 17-Mar-2014 424

Download the entire example:

Name                             Modified     Size

examples_a_volume_render.tar.gz 09-Mar-2016 11M

Testing status by version:

StatusTestedReal time (s)
cmgui-wxFailureSun Mar 6 00:35:59 201617
last breakTue Feb 24 03:39:00 201517
cmgui-wx-debugFailureSun Mar 6 00:32:15 201617
last breakTue Feb 24 03:34:00 201516
cmgui-wx-debug-memorycheckFailureSun Mar 6 00:31:39 201617
last breakTue Feb 24 03:34:00 201517
cmgui-wx-debug-valgrindFailureSun Mar 6 03:06:29 2016706
last breakSun Mar 6 02:54:00 2016706
cmgui-wxFailureSun Mar 6 00:01:35 20160
last breakSun Mar 6 00:01:00 20160
cmgui-wx-debugFailureSun Mar 6 00:01:35 20160
last breakSun Mar 6 00:01:00 20160
cmgui-wx-debug-memorycheckFailureSun Mar 6 00:01:35 20160
last breakSun Mar 6 00:01:00 20160
cmgui-wx-debug-valgrindFailureSun Mar 6 00:03:00 201610
last breakSun Mar 6 00:02:00 201610

Testing status by file:

Html last generated: Wed Mar 9 16:02:59 2016

Input last modified: Wed Mar 9 15:49:44 2016

CMISS Help / Examples / a / volume_render