## Warning: These vignettes assume pandoc version 1.13.1; older versions may
## give poor formatting.

Introduction

The rgl package is used to produce interactive 3-D plots. It contains high-level graphics commands modelled loosely after classic R graphics, but working in three dimensions. It also contains low level structure inspired by (but incompatible with) the grid package.

This document gives an overview. See the help pages for details.

About this document

This document was written in R Markdown, using the knitr package for production. It corresponds to rgl version 0.95.1441.

Most of the highlighted function names are HTML links. The internal links should work in any browser; the links to help topics should work if you view the vignette from within the R help system.

The document includes WebGL figures. To view these, you must have Javascript and WebGL enabled in your browser. Some older browsers may not support this – see http://get.webgl.org for tests and links to a discussion.

The WebGL figures were produced using the rglwidget package, version 0.1.1434.

Basics and High Level Functions

The plot3d function plots points within an rgl window. It is similar to the classic plot function, but works in 3 dimensions.

For example

with(iris, plot3d(Sepal.Length, Sepal.Width, Petal.Length, 
                  type="s", col=as.numeric(Species)))

can be used to plot three columns of the iris data.
Allowed plot types include "p", "l", "h", "s", meaning points, lines, segments from z=0, and spheres. There’s a lot of flexibility in specifying the coordinates; the xyz.coords function from the grDevices package is used for this.

You can use your mouse to manipulate the plot. The default is that if you click and hold with the left mouse button, you can rotate the plot by dragging it. The right mouse button is used to resize it, and the middle button changes the perspective in the point of view.

If you call plot3d again, it will overwrite the current plot. To open a new graphics window, use open3d.

The other high level function is persp3d to draw surfaces. It is similar to the classic persp function, but with greater flexibility. First, any of x, y or z can be specified using matrices, not just z. This allows parametric surfaces to be plotted. An even simpler specification is possible: x may be a function, in which case persp3d will work out the grid itself. See ?persp3d.function for details. For example, the MASS package estimates Gamma parameters using maximum likelihood in a ?MASS::fitdistr example. Here we show the log likelihood surface.

library(MASS)
# from the fitdistr example
set.seed(123)
x <- rgamma(100, shape = 5, rate = 0.1)
fit <- fitdistr(x, dgamma, list(shape = 1, rate = 0.1), lower = 0.001)
loglik <- function(shape, rate) sum(dgamma(x, shape=shape, rate=rate, 
                                           log=TRUE))
loglik <- Vectorize(loglik)
xlim <- fit$estimate[1]+4*fit$sd[1]*c(-1,1)
ylim <- fit$estimate[2]+4*fit$sd[2]*c(-1,1)

mfrow3d(1, 2, sharedMouse = TRUE)
persp3d(loglik, 
        xlim = xlim, ylim = ylim,
        n = 30)
zlim <- fit$loglik + c(-qchisq(0.99, 2)/2, 0)
next3d()
persp3d(loglik, 
        xlim = xlim, ylim = ylim, zlim = zlim,
        n = 30)

You must enable Javascript to view this page properly.

On the left, the whole surface over a range of the parameters; on the right, only the parts of the surface with log likelihood values near the maximum.

Note: this example used the knitr hook functions (see setupKnitr) to insert the scene into this vignette; the previous example used the rglwidget function from the package of the same name. We generally recommend the newer rglwidget approach.

Adding Graphical Elements

Primitive shapes

Just as we have points and lines in classic graphics, there are a number of low level functions in rgl to add graphical elements to the currently active plot. The “primitive” shapes are those that are native to OpenGL:

points3d: adds points
lines3d: adds lines
segments3d: adds line segments
triangles3d: adds triangles
quads3d: adds quadrilaterals

Each of the above functions takes arguments x, y and z, again using xyz.coords for flexibility. They group successive entries as necessary. For example, the triangles3d function takes each successive triple of points as the vertices of a triangle.

You can use these functions to annotate the current graph, or to construct a figure from scratch.

Constructed shapes

rgl also has a number of objects which it constructs from the primitives.

text3d, texts3d: adds text
abclines3d: adds straight lines to plot (like abline)
planes3d: adds planes to plot
clipplanes3d: add clipping planes to plot
sprites3d, particles3d: add sprites (fixed shapes or images) to plot
spheres3d: adds spheres
surface3d, terrain3d: a surface (as used in persp3d)

Axes and other “decorations”

The following low-level functions control the look of the graph:

axes3d, axis3d: add axes to plot
box3d, bbox3d: add box around plot
title3d: add title to plot
mtext3d: add marginal text to plot
decorate3d: add multiple “decorations” (scales, etc.) to plot
aspect3d: set the aspect ratios for the plot
bg3d, bgplot3d: set the background of the scene
show2d: show a 2D plot or image in a 3D scene
legend3d: set a legend for the scene
grid3d: add a reference grid to a graph

For example, to plot three random triangles, one could use

triangles3d(cbind(x=rnorm(9), y=rnorm(9), z=rnorm(9)), col = "green")
decorate3d()
bg3d("lightgray")
aspect3d(1,1,1)

You must enable Javascript to view this page properly.

Besides the *3d functions mentioned above, there are even lower-level functions rgl.primitive, rgl.points, rgl.linestrips, rgl.lines, rgl.triangles, rgl.quads, rgl.texts, rgl.abclines, rgl.planes, rgl.bg, rgl.clipplanes, rgl.bbox, rgl.spheres, rgl.sprites, rgl.surface.
You should avoid using these functions, which do not work well with the higher level *3d functions. See the ?r3d help topic for details.

Controlling the Look of the Scene

Lighting

In most scenes, objects are “lit”, meaning that their appearance depends on their position and orientation relative to lights in the scene. The lights themselves don’t normally show up, but their effect on the objects does.

Use the light3d function to specify the position and characteristics of a light. Lights may be infinitely distant, or may be embedded within the scene. Their characteristics include ambient, diffuse, and specular components, all defaulting to white. The ambient component appears the same from any direction. The diffuse component depends on the angle between the surface and the light, while the specular component also takes the viewer’s position into account.

The rgl.light function is a lower-level function with different defaults; users should normally use light3d.

Materials

The mental model used in rgl is that the objects being shown in scenes are physical objects in space, with material properties that affect how light reflects from them (or is emitted by them). These are mainly controlled by the material3d function, or by arguments to other functions that are passed to it.

The material properties that can be set by calls to material3d are described in detail in the ?material3d help page. Here we give an overview.

Property Default Meaning
color white vector of surface colors to apply to successive vertices for diffuse light
alpha 1 transparency: 0 is invisible, 1 is opaque
lit TRUE whether lighting calculations should be done
ambient black color in ambient light
specular white color in specular light
emission black color emitted by the surface
shininess 50 controls the specular lighting: high values look shiny
smooth TRUE whether shading should be interpolated between vertices
texture NULL optional path to a “texture” bitmap to be displayed on the surface
front, back fill should polygons be filled, or outlined?
size 3 size of points in pixels
lwd 1 width of lines in pixels

Other properties include “texmipmap”, “texmagfilter”, “texminfilter”, “texenvmap”, “fog”, “point_antialias”, “line_antialias”, “depth_mask”, and “depth_test”; see the help page for details.

There is also an rgl.material function that works at a lower level; users should normally avoid it.

par3d: Miscellaneous graphical parameters

The par3d function, modelled after the classic graphics par function, sets or reads a variety of different rgl internal parameters. Some parameters are completely read-only; others are fixed at the time the window is opened, and others may be changed at any time.

Name Changeable? Description
antialias fixed Amount of hardware antialiasing
cex Default size for text
family Device-independent font family name; see ?text3d
font Integer font number
useFreeType Should FreeType fonts be used if available?
fontname read-only System-dependent font name set by rglFonts
FOV Field of view, in degrees. Zero means isometric perspective
ignoreExtent Should rgl ignore the size of new objects when computing the bounding box?
skipRedraw Should rgl suppress updates to the display?
maxClipPlanes read-only How many clip planes can be defined?
modelMatrix read-only The OpenGL ModelView matrix; partly set by view3d or the obsolete rgl.viewpoint
projMatrix read-only The OpenGL Projection matrix
bbox read-only Current bounding-box of the scene
viewport Dimensions in pixels of the scene within the window
windowRect Dimensions in pixels of the window on the whole screen
listeners Which subscenes respond to mouse actions in the current one
mouseMode What the mouse buttons do. See “mouseMode”
observer read-only The position of the observer; set by observer3d
scale Rescaling for each coordinate; see aspect3d
zoom Magnification of the scene

Default settings

The r3dDefaults list and the getr3dDefaults function control defaults in new windows opened by open3d.
The function looks for the variable in the user’s global environment, and if not found there, finds the one in the rgl namespace. This allows the user to override the default settings for new windows.

Once found, the r3dDefaults list provides initial values for par3d parameters, as well as defaults for material3d and bg3d in components "material" and "bg" respectively.

Meshes: Constructing Shapes

rgl includes a number of functions to construct and display various solid shapes. These generate objects of class "shape3d", "mesh3d" or "shapelist3d". The details of the classes are described below. We start with functions to generate them.

Specific solids

These functions generate specific shapes. Optional arguments allow attributes such as colour or transformations to be specified.

tetrahedron3d, cube3d, octahedron3d, dodecahedron3d, icosahedron3d: Platonic solids
cuboctahedron3d, oh3d: other solids
open3d()
cols <- rainbow(7)
layout3d(matrix(1:16, 4,4), heights=c(1,3,1,3))
text3d(0,0,0,"tetrahedron3d"); next3d()
shade3d(tetrahedron3d(col=cols[1])); next3d()
text3d(0,0,0,"cube3d"); next3d()
shade3d(cube3d(col=cols[2])); next3d()
text3d(0,0,0,"octahedron3d"); next3d()
shade3d(octahedron3d(col=cols[3])); next3d()
text3d(0,0,0,"dodecahedron3d"); next3d()
shade3d(dodecahedron3d(col=cols[4])); next3d()
text3d(0,0,0,"icosahedron3d"); next3d()
shade3d(icosahedron3d(col=cols[5])); next3d()
text3d(0,0,0,"cuboctahedron3d"); next3d()
shade3d(cuboctahedron3d(col=cols[6])); next3d()
text3d(0,0,0,"oh3d"); next3d()
shade3d(oh3d(col=cols[7]))

You must enable Javascript to view this page properly.

Generating new shapes

These functions generate new shapes:

cylinder3d: generate a tube or cylinder
polygon3d: generate a flat polygon by triangulation
extrude3d: generate an “extrusion” of a polygon
turn3d: generate a solid of rotation
ellipse3d: generate an ellipsoid in various ways
tmesh3d, qmesh3d: generate a shape from vertices and faces
shapelist3d: generate a shape by combining other shapes

A related function is triangulate, which takes a two dimensional polygon and divides it up into triangles using the “ear-clipping” algorithm.

The underlying class structure for shapes

"shape3d" is the basic abstract type. Objects of this class can be displayed by shade3d (which shades faces), wire3d (which draws edges), or dot3d (which draws points at each vertex.) Note that wire3d and dot3d only work within R; in HTML output from writeWebGL only shade3d is supported.

"mesh3d" is a descendant type. Objects of this type contain the following fields:

Field Meaning
vb A 4 by n matrix of vertices in homogeneous coordinates. Each column is a point.
it (optional) A 3 by t matrix of vertex indices. Each column is a triangle.
ib (optional) A 4 by q matrix of vertex indices. Each column is a quadrilateral.
material (optional) A list of material properties.
normals (optional) A matrix of the same shape as vb, containing normal vectors at each vertex.
texcoords (optional) A 2 by n matrix of texture coordinates corresponding to each vertex.

Manipulating shapes

The final set of functions manipulate and modify mesh objects:

addNormals: add normal vectors to make a shape look smooth
subdivision3d: add extra vertices to make it look even smoother

Multi-figure Layouts

rgl has several functions to support displaying multiple different “subscenes” in the same window. The high level functions are

mfrow3d: Multiple figures (like par(“mfrow”)
layout3d: Multiple figures (like layout)
next3d: Move to the next figure (like plot.new or frame)
subsceneList: List all the subscenes in the current layout
clearSubsceneList Clear the current list and revert to the previous one

There are also lower level functions.

newSubscene3d: Create a new subscene, with fine control over what is inherited from the parent
currentSubscene3d: Report on the active subscene
subsceneInfo: Get information on current subscene
useSubscene3d: Make a different subscene active
addToSubscene3d, delFromSubscene3d: Add objects to a subscene, or delete them
gc3d: Do “garbage collection”: delete objects that are not displayed in any subscene

Utility Functions

User interaction

By default, rgl detects and handles mouse clicks within your scene, and uses these to control its appearance. You can find out the current handlers using the following code:

par3d("mouseMode")
##        left       right      middle       wheel 
## "trackball"      "zoom"       "fov"      "pull"

The labels c("left", "right", "middle") refer to the buttons on a three button mouse, or simulations of them on other mice. "wheel" refers to the mouse wheel.

The button actions generally correspond to click and drag operations. Possible values for “mouseMode” for buttons or the wheel are as follows:

"none" No action
"trackball" The mouse acts as a virtual trackball. Clicking and dragging rotates the scene
"xAxis", "yAxis", "zAxis" Like "trackball", but restricted to rotation about one axis
"polar" The mouse affects rotations by controlling polar coordinates directly
"selecting" The mouse is being used by the select3d function
"zoom" The mouse zooms the display
"fov" The mouse affects perspective by changing the field of view
"pull" Rotating the mouse wheel towards the user “pulls the scene closer”
"push" The same rotation “pushes the scene away”
"user" A user action set by rgl.setMouseCallbacks, rgl.setWheelCallback. Use rgl.getMouseCallbacks and rgl.getWheelCallback to retrieve

The following functions make use of the mouse for selection within a scene.

identify3d like the classic graphics identify function
select3d returns a function that tests whether a coordinate was selected
selectpoints3d selects from specific objects

The rgl.select3d function is an obsolete version of select3d, and rgl.select is a low-level support function.

Animations

rgl has several functions that can be used to construct animations. These are based on functions that update the scene according to the current real-world time, and repeated calls to those. The functions are:

play3d Repeatedly call the update function
spin3d Update the display by rotating at a constant rate
par3dinterp Compute new values of some par3d parameters by interpolation over time

See the movie3d function for a way to output an animation to a file on disk.
Animations are not currently supported in the HTML written by writeWebGL, though the rglwidget::playwidget function provides equivalent functionality.

Exporting and importing scenes

rgl contains several functions to write scenes to disk for use by other software, or to read them in.

In order from highest fidelity to lowest, the functions are:

scene3d Save a scene to an R variable, which can be saved and reloaded
writeWebGL Write HTML and Javascript to display a scene in a web browser. (See also User Interaction in WebGL.)
writePLY Write PLY files (commonly used in 3D printing)
readOBJ, writeOBJ Read or write OBJ files (commonly used in 3D graphics)
readSTL, writeSTL Read or write STL files (also common in 3D printing)
rgl.useNULL A helper function for setting a NULL device

See the help page rgl.useNULL for instructions on how to use rgl on a “headless” system.

There are also functions to save snapshots or other recordings of a scene, without any 3D information being saved:

snapshot3d Save a PNG file bitmap of the scene
rgl.postscript Save a Postscript, LaTeX, PDF, SVG or PGF vector rendering of the scene
movie3d Save a series of bitmaps to be assembled into a movie
rgl.pixels Obtain pixel-level information about the scene in an R variable
rgl.Sweave Driver function for inserting a snapshot into a Sweave document.
hook_rgl, hook_webgl knitr hook functions for inserting images into a document.
setupKnitr Function to set up knitr hooks

The rgl.snapshot function is identical to snapshot3d. The functions rgl.Sweave.off, Sweave.snapshot are involved in Sweave processing and not normally called by users.

Working with WebGL scenes

There are currently two schemes for exporting a scene to a web page. Both require the rglwidget package and use the same underlying code.

The recommended approach works with the htmlwidgets framework (see http://www.htmlwidgets.org/). In an R Markdown document in knitr, use the chunk option webgl=TRUE, or the rglwidget::rglwidget() function. More details are given in the vignette User Interaction in WebGL.

The older approach uses the writeWebGL function to export a scene to HTML and Javascript code.
The functions below write HTML and Javascript for working with the exported scene.

propertySlider insert a slider to make changes to a scene
clipplaneSlider insert a slider to control a clipping plane
subsetSlider insert a slider to control which objects are displayed
toggleButton insert a button to toggle some items
propertySetter function to modify properties
subsetSetter function to choose subsets
ageSetter function to “age” vertices
par3dinterpSetter function like par3dinterp
vertexSetter function to modify individual vertices
matrixSetter function to modify matrices

Working with the scene

rgl maintains internal structures for all the scenes it displays. The following functions allow users to find information about them and manipulate them.

open3d open a new window
rgl.close close the current window
rgl.bringtotop bring the current window to the top
rgl.cur id of the active device
rgl.dev.list ids of all active devices
rgl.set set a particular device to be active
rgl.ids ids and types of all current objects
rgl.attrib, rgl.attrib.count: attributes of objects in the scene
pop3d, rgl.pop delete an object from the scene
clear3d, rgl.clear delete all objects of certain classes
rgl.projection return information about the current projection
rgl.user2window, rgl.window2user convert between coordinates in the current projection

In addition to these, there are some other related functions which should rarely be called by users: rgl.init, rgl.open, rgl.quit.

Working with 3-D vectors

Most rgl functions work internally with “homogeneous” coordinates. In this system, 3-D points are represented with 4 coordinates, generally called (x, y, z, w). The corresponding Euclidean point is (x/w, y/w, z/w), if w is nonzero; zero values of w correspond to “points at infinity”. The advantage of this system is that affine transformations including translations and perspective shifts become linear transformations, with multiplication by a 4 by 4 matrix.

rgl has the following functions to work with homogeneous coordinates:

asEuclidean, asHomogeneous: convert between homogeneous and Euclidean coordinates
rotate3d, scale3d, translate3d: apply a transformation
transform3d: apply a general transformation
rotationMatrix, scaleMatrix, translationMatrix: compute the transformation matrix
identityMatrix return a 4 x 4 identity matrix

There is also a function GramSchmidt, mainly for internal use: it does a Gram-Schmidt orthogonalization of a 3x3 matrix, with some specializations for its use in cylinder3d.

Warning: Work in Progress!

This vignette is in a preliminary form. Many aspects of the rgl package are not described, or do not have examples. There may even be functions that are missed completely, if the following list is not empty:

## character(0)

Index of Functions

The following functions and constants are described in this document:

GramSchmidt   hook_webgl   qmesh3d   rgl.projection   spin3d  
Sweave.snapshot   icosahedron3d   quads3d   rgl.quads   sprites3d  
abclines3d   identify3d   r3dDefaults   rgl.quit   subdivision3d  
addNormals   identityMatrix   readOBJ   rgl.select   subsceneInfo  
addToSubscene3d   layout3d   readSTL   rgl.select3d   subsceneList  
ageSetter   legend3d   rgl.Sweave   rgl.set   subsetSetter  
asEuclidean   light3d   rgl.Sweave.off   rgl.setMouseCallbacks   subsetSlider  
asHomogeneous   lines3d   rgl.abclines   rgl.setWheelCallback   surface3d  
aspect3d   material3d   rgl.attrib   rgl.snapshot   terrain3d  
axes3d   matrixSetter   rgl.attrib.count   rgl.spheres   tetrahedron3d  
axis3d   mfrow3d   rgl.bbox   rgl.sprites   text3d  
bbox3d   mouseMode   rgl.bg   rgl.surface   texts3d  
bg3d   movie3d   rgl.bringtotop   rgl.texts   title3d  
bgplot3d   mtext3d   rgl.clear   rgl.triangles   tmesh3d  
box3d   newSubscene3d   rgl.clipplanes   rgl.useNULL   toggleButton  
clear3d   next3d   rgl.close   rgl.user2window   transform3d  
clearSubsceneList   observer3d   rgl.cur   rgl.viewpoint   translate3d  
clipplaneSlider   octahedron3d   rgl.dev.list   rgl.window2user   translationMatrix  
clipplanes3d   oh3d   rgl.getMouseCallbacks   rglFonts   triangles3d  
cube3d   open3d   rgl.getWheelCallback   rotate3d   triangulate  
cuboctahedron3d   par3d   rgl.ids   rotationMatrix   turn3d  
currentSubscene3d   par3dinterp   rgl.init   scale3d   useSubscene3d  
cylinder3d   par3dinterpSetter   rgl.light   scaleMatrix   vertexSetter  
decorate3d   particles3d   rgl.lines   scene3d   view3d  
delFromSubscene3d   persp3d   rgl.linestrips   segments3d   wire3d  
dodecahedron3d   planes3d   rgl.material   select3d   writeOBJ  
dot3d   play3d   rgl.open   selectpoints3d   writePLY  
ellipse3d   plot3d   rgl.pixels   setupKnitr   writeSTL  
extrude3d   points3d   rgl.planes   shade3d   writeWebGL  
gc3d   polygon3d   rgl.points   shapelist3d  
getr3dDefaults   pop3d   rgl.pop   show2d  
grid3d   propertySetter   rgl.postscript   snapshot3d  
hook_rgl   propertySlider   rgl.primitive   spheres3d