rgl Scenes
pkgdown websitestestthatThe 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.
For installation instructions, see the README file in the top
level directory of the source tarball
rgl_1.3.17.tar.gz (or a later
version).
This document was written in R Markdown, using the knitr package
for production.  It corresponds to rgl version
1.3.17.
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 https://get.webgl.org for tests and links to a discussion.
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)))
plot of chunk plot3d()
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.
# This example requires the MASS package
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)
plot of chunk persp3d()
Note:  this example used the knitr hook functions
(see setupKnitr) to insert the
scene into this vignette; the previous example used the rglwidget
function.  We generally
recommend the newer rglwidget approach.
Note that both plot3d and persp3d are generic functions,
with the following methods defined:
methods(plot3d)
##  [1] plot3d.ashape3d*      plot3d.default*       plot3d.deldir*       
##  [4] plot3d.formula*       plot3d.function*      plot3d.lm*           
##  [7] plot3d.mesh3d*        plot3d.rglWebGL*      plot3d.rglbackground*
## [10] plot3d.rglbboxdeco*   plot3d.rglobject*     plot3d.rglscene*     
## [13] plot3d.rglsubscene*   plot3d.tri*           plot3d.triSht*       
## see '?methods' for accessing help and source code
methods(persp3d)
## [1] persp3d.ashape3d* persp3d.default*  persp3d.deldir*   persp3d.formula* 
## [5] persp3d.function* persp3d.tri*      persp3d.triSht*  
## see '?methods' for accessing help and source code
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:
| Function | Description | 
|---|---|
| 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.
rgl also has a number of objects which it constructs
from the primitives.
| Function | Description | 
|---|---|
| text3d,texts3d: | adds text | 
| abclines3d: | adds straight lines to plot (like abline) | 
| arc3d: | adds spherical arcs or spirals to plot | 
| 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) | 
| drape3d: | drapes lines on a surface or object(s) | 
| shadow3d: | projects mesh onto a surface | 
| arrow3d: | add an arrow to a scene | 
| pch3d: | draw base-style plotting symbols | 
| plotmath3d: | used by text3dfor math text | 
The following low-level functions control the look of the graph:
| Function | Description | 
|---|---|
| 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 | 
| thigmophobe3d: | choose label positions to avoid overlap | 
| setAxisCallbacks: | set user-defined axis annotations | 
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")
plot of chunk triangles3d()
aspect3d(1,1,1)
Besides the *3d functions mentioned above, there are
deprecated
functions
rgl.abclines, rgl.bbox, rgl.bg, rgl.clipplanes, rgl.lines, rgl.linestrips, rgl.planes, rgl.points, rgl.primitive, rgl.quads, rgl.setAxisCallback, rgl.spheres, rgl.sprites, rgl.surface, rgl.texts, rgl.triangles.
You should avoid using all of these functions, which do not
work properly with the *3d functions and will
soon be removed from rgl.  See the
?r3d help
topic for details.
The function
rgl.getAxisCallback
provides low-level support for setAxisCallbacks.
By default when you open a new plot with open3d:
You can change the camera angle simply by dragging the picture with the mouse.
To set the camera angle programmatically, use view3d.
This uses polar coordinates:
theta sets the rotation around the vertical axis, in degrees.phi sets the “vertical” rotation around the horizontal axis,
from -90 to 90 degrees.The default angle is roughly theta = 0, phi = -70. Starting from
this position:
theta, the graph will spin anticlockwise from your
point of view.phi to 0, you start to look down at the scene
from the top. If you increase phi above 0, you continue over and
start to see the graph from the “back” (and upside down).You can also use observer3d to change the camera
location using x,y,z coordinates. In particular, increasing
the z coordinate lets you zoom out, and decreasing it zooms you in.
One useful approach is to use the mouse to find a nice viewing angle.
You can then save it using par3d("userMatrix") and restore
the same view later:
myview <- par3d("userMatrix")
# ... later ...
par3d(userMatrix = myview)
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 deprecated rgl.light function should
no longer be used; use light3d instead.
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 are recognized in calls to material3d are
described in detail in the
?material3d help page, and listed in the rgl.material.names
variable.  All of them can be set except the ones in
rgl.material.readonly.
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”, “depth_test”, “polygon_offset”, “margin”, “floating”, “tag” and “blend”; see the help page for details.
There is also a deprecated rgl.material function that works
at a lower level; users should avoid it.
As described in the previous section, one of the material
properties is texture, the name of a bitmap file (in .png
format) containing an image to be displayed on the surface.
This section gives more details about textures.
In OpenGL, each vertex in a polygon may be associated with a
particular location in the bitmap.  The interior of the
polygon interpolates within the bitmap.  There are two
conventions in rgl functions for specifying these coordinates.
Functions which specify primitives (triangles3d, etc.) accept an optional matrix argument
texcoords which gives s (horizontal) and t (vertical)
locations within the bitmap in columns with one row per vertex.
The coordinates are (0,0) for the lower left, and (1,1)
for the upper right.  If values outside this range are given,
the image repeats, i.e. (1.1, 1.2) would specify the same
point in the image as (0.1, 0.2).
Other functions such as surface3d that take
matrices for each vertex coordinate accept texture coordinates
as matrices as well, in arguments texture_s and texture_t.
For example, the
following code displays four copies of a 2D plot on a quad,
because the texture coordinates run from 0 to 2 in both
s and t:
filename <- tempfile(fileext = ".png")
png(filename = filename)
plot(rnorm(1000), rnorm(1000))
safe.dev.off()
## quartz_off_screen 
##                 2
open3d()
## null 
##   59
xyz <- cbind(c(0,1,1,0), 0, c(0,0,1,1))
quads3d(xyz, texture = filename, texcoords = xyz[,c(1, 3)]*2, 
        col = "white", specular = "black")
plot of chunk Texture
Some other notes:
quads3d() above was specified to be white.  By default,
the colors in the bitmap will modify the color of the
surface.  If col is black (a common default), you won’t see anything,
so a warning may be issued.specular
to black prevents those."texmode" allows texture colors to
be used differently.  The default is "modulate", where the texture
values combine multiplicatively with the underlying values."textype".  The default is "rgb", which
takes the red-green-blue colors from the bitmap and
uses them to modify the corresponding colors in the polygon."textype" and "texmode" are described
in the material3d help page."tex*" material properties control how
the interpolation within the image is done.OpenGL supports 1- and 3-dimensional textures;
these are not currently supported in rgl.rgl uses the same ideas as base graphics for drawing
text:  there are font families named "sans",
"serif", and "mono" for drawing text of those
types.  In rgl, the "symbol" family is not supported.
New font families can be defined using the low-level
function rglFonts, or more simply
using the higher level function
rglExtrafonts.  The latter function
requires the extrafont package to be installed.
The par3d function, modelled after the classic
graphics par function, sets or reads
a variety of different rgl internal
parameters, listed in the rgl.par3d.names
variable.  All of them can be set except the ones in
rgl.par3d.readonly.  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 rglignore the size of new objects when computing the bounding box? | |
| skipRedraw | Should rglsuppress 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 | 
| 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 | 
The deprecated rgl.viewpoint function
should not be used.
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.
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.
These functions generate specific shapes. Optional arguments allow attributes such as color or transformations to be specified.
| Function | Description | 
|---|---|
| tetrahedron3d,cube3d,octahedron3d,dodecahedron3d,icosahedron3d: | Platonic solids | 
| cuboctahedron3d,oh3d: | other solids | 
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]))
plot of chunk Solids
A very large collection of polyhedra is contained in the Rpolyhedra package.
These functions generate new shapes:
| Function | Description | 
|---|---|
| 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 | 
| mesh3d: | generate a shape from indexed vertices | 
| shapelist3d: | generate a shape by combining other shapes | 
| as.mesh3d: | a generic function; see below | 
A related function is triangulate, which takes a
two dimensional polygon and divides it up into triangles using the
“ear-clipping” algorithm.
The generic function as.mesh3d
is provided to allow data structures produced by
other code to be converted to mesh
structures.  Currently the following classes
are supported:
| Class | Package | Description | 
|---|---|---|
| deldir | deldir | Delaunay triangulations of irregular point clouds | 
| triSht | interp | Also Delaunay triangulations | 
| tri | tripack | Generalized Delaunay triangulations | 
| ashape3d | alphashape3d | Alpha-shapes | 
| rglId | rgl | rglobject identifiers | 
The checkDeldir function checks that a compatible version
of the deldir package is installed.
The default as.mesh3d.default method is a simple way
to construct a mesh from a matrix of vertices; it can use
mergeVertices (which can also be used on its own)
to merge repeated vertices within the matrix, allowing
addNormals to be used to give a smooth appearance.
The as.tmesh3d generic is a variation that
guarantees the resulting object will have no quad entries.
Functions tmesh3d, qmesh3d are now obsolete;
use mesh3d instead.
"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.)
"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. | 
| ip | (optional) A vector of vertex indices for points. | 
| is | (optional) A 2 by s matrix of vertex indices. Each column is a line segment. | 
| 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. | 
| values | (optional) A vector of length n holding values at each vertex | 
| meshColor | (optional) A text value indicating how colors and texture coordinates should be interpreted. | 
| tags | (optional) A vector added by some functions (e.g. clipMesh3d) to relate output parts to input parts. | 
These functions compute and plot contours of functions on surfaces, or clip objects along a contour of a function.
| Function | Description | 
|---|---|
| contourLines3d: | draw contour lines on surface | 
| filledContour3d: | fill between contours on surface | 
| clipMesh3d: | clip mesh object using curved boundary | 
| clipObj3d: | clip general object using curved boundary | 
These functions manipulate and modify mesh objects:
| Function | Description | 
|---|---|
| addNormals: | add normal vectors to make a shape look smooth | 
| subdivision3d: | add extra vertices to make it look even smoother | 
| merge: | merge mesh objects | 
| facing3d: | subset of mesh facing “up” | 
| getBoundary3d: | get the boundary of a mesh object | 
The individual steps in subdivision3d are also available:
deform.mesh3d, divide.mesh3d, normalize.mesh3d. These
are mainly intended for internal use.
rgl has several functions to support displaying multiple different
“subscenes” in the same window.  The high level functions are
| Function | Description | 
|---|---|
| mfrow3d: | Multiple figures (like par(“mfrow”) | 
| layout3d: | Multiple figures (like layout) | 
| next3d: | Move to the next figure (like plot.neworframe) | 
| 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.
| Function | Description | 
|---|---|
| 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 | 
rgl ScenesThe rgl package can produce output that can be embedded
in other documents.  The recommended way to do this has changed several
times over the years.  We will start with the current
recommendation, then list older methods.
Currently the best way to embed an rgl scene in a document
is to produce the document in HTML using R Markdown.  Early in
the document, you should have code like this in one of the
setup code chunks:
```{r echo=FALSE, include=FALSE}
library(rgl)
setupKnitr(autoprint = TRUE)
```
The call to setupKnitr() will install a number of hooks
and set options in knitr so that rgl code is handled properly.
The autoprint = TRUE argument makes rgl act in the document
almost the same way it would act in the console, or the way
base graphics are handled by knitr:  If you print the value
of high level rgl functions, a plot will be inserted into the
output, but maybe only after low level modifications to it are
complete.  For example, this code block prints both
triangles and spheres in a single plot at the end:
xyz <- matrix(rnorm(27), ncol = 3)
triangles3d(xyz, col = rainbow(9))
spheres3d(xyz, col = rainbow(9), radius = 0.1)
plot of chunk Autoprint
There are a few differences if you have a complicated situation:
rgl function
calls being automatically printed.
If the calls are in a loop or other code block where automatic
printing doesn’t happen, you’ll need some trickery to get
things to print.  For example, this will print three plots:plots <- NULL
for (i in 1:3) {
  plot3d(rnorm(10), rnorm(10), rnorm(10))
  plots <- htmltools::tagList(plots, rglwidget())
  close3d()
}
plots
rgl functions return
results using lowlevel() or highlevel() to mark which
kind of plot they are.  If you are using a function from
another package to produce the plot, you may need to insert
an explicit call to one of those to get it to print.  Use lowlevel() if the function just modifies an existing plot,
highlevel() if it starts a new one.  For example,foreignHigh()   # Produces a high level plot, but doesn't return
                # an appropriate value
highlevel()
foreignLow()    # Modifies the previous plot
lowlevel()
This should display the output at the end of the code chunk, when modifications are assumed complete.
While some PDF previewers support interactive 3D graphics,
most don’t.  To produce a screenshot of an rgl scene in an R Markdown
document with PDF output, simply follow the directions given
above.  The auto-printing will detect PDF output and use
snapshot3d to produce a PNG file to insert.  (See below
if you want to insert a different format of graphic.)
If you really need interactive output, see the
writeASY function.
You may not want to use the setupKnitr(autoprint = TRUE)
method described above.  It is very new, and may still have
bugs; you may have an older document and not want to edit it
to work that way.
In this case, you can insert plots manually. Use setup code
```{r echo=FALSE, include=FALSE}
library(rgl)
setupKnitr()
```
and call rglwidget() at top level whenever you want to
insert a plot.
There are a couple of other differences in default behaviour if
you are not using autoprint:
By default, each code chunk continues the rgl scene from
earlier chunks.  You’ll need an explicit open3d
call to get a clean window.
Also by default, the rgl window is not closed at the end of
the chunk.  This probably doesn’t matter, but you may find
you run out of memory if your scenes are really big.
The original way to insert an rgl scene in a document was to use
the deprecated writeWebGL function to write HTML code to insert in a document.
Later, Sweave and knitr hooks were added.  These are no longer supported, and you should update old documents to use the newer methods.  If you are
reading documents that suggest using those methods, let the
author know they need updating!
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")
##        none        left       right      middle       wheel 
##      "none" "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, and "none" refers to
actions that take place when the mouse is moved
without pressing any button.
The button actions generally correspond to click and drag operations.
Possible values for “mouseMode” for the mouse pointer or wheel are as follows:
| Mode | Description | 
|---|---|
| "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 select3dfunction | 
| "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 setUserCallbacks,rgl.setMouseCallbacks,rgl.setWheelCallback.  Usergl.getMouseCallbacksandrgl.getWheelCallbackto retrieve. | 
The following functions make use of the mouse for selection within a scene.
| Function | Description | 
|---|---|
| identify3d: | like the classic graphics identifyfunction | 
| select3d: | returns a function that tests whether a coordinate was selected | 
| selectpoints3d: | selects from specific objects | 
| hover3d: | displays “hover” info about points | 
selectionFunction3d produces the selection
function from information about the projection and mouse
selection region; it is used internally in the
functions above.
The deprecated rgl.select3d function is an obsolete version of
select3d, and rgl.select is a low-level support
function.
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:
| Function | Description | 
|---|---|
| play3d: | Repeatedly call the update function | 
| spin3d: | Update the display by rotating at a constant rate | 
| par3dinterp: | Compute new values of some par3dparameters 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 rglwidget, though the
playwidget function provides equivalent functionality.
There are three functions in rgl that support control of an rgl
scene using the TCL/TK framework.
| Function | Description | 
|---|---|
| tkspin3d: | Set up buttons in a window to control a scene | 
| tkspinControl: | Embed the control buttons in a separate TCL/TK frame | 
| tkpar3dsave: | Create a dialog to interactively save mouse actions | 
These functions were formerly contained (without the tk prefixes on
their names) in the tkrgl package.  That package is now deprecated.
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:
| Function | Description | 
|---|---|
| scene3d: | Save a scene to an R variable, which can be saved and reloaded | 
| rglwidget: | Prints as HTML and Javascript to display a scene in a web browser. (See also User Interaction in WebGL.) | 
| writeASY: | Write files for Asymptote | 
| 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) | 
| as.rglscene: | Generic function, no methods in rgl | 
The rgl2gltf
package can read or write GLTF and GLB files.  It includes an
as.rglscene method to convert GLTF objects to rgl scenes.  The
code in rgl’s Buffer R6 class is based on the GLTF
format.  It is used by rglwidget to make output
webpages somewhat smaller than they were previously.
There are also functions to save snapshots or other recordings of a scene, without any 3D information being saved:
| Function | Description | 
|---|---|
| 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: | knitrhook functions for inserting images into a document. | 
| setupKnitr: | Function to set up knitrhooks | 
The rgl.snapshot function is a low level
version of snapshot3d(); it requires that the rgl display
be onscreen and copies from there.  snapshot3d() tries to
use the webshot2 package so it will work even with no display.
The functions rgl.Sweave.off, Sweave.snapshot are
involved in Sweave processing and not normally called by users.
There are two ways in which rgl scenes are normally
displayed within R.  The older one is in a dedicated
window.  In Unix-alikes this is an X11 window;  it is
a native window in Microsoft Windows.  On macOS, the
XQuartz system (see https://www.xquartz.org) needs to be
installed to support this.
To suppress this display, set options(rgl.useNULL = TRUE) before opening a new rgl window.  See
the help page for the rgl.useNULL function
for how to set this before starting R.
The newer way to display a scene is by using WebGL
in a browser window or in the Viewer pane in RStudio.
To select this, set options(rgl.printRglwidget = TRUE).
Each operation that would change the scene will
return a value which triggers a new WebGL display
when printed.
You should use the following scheme for exporting a scene to a web page. There’s also an older scheme, which is no longer supported.
The recommended approach works with the htmlwidgets framework
(see http://www.htmlwidgets.org/).  In an R Markdown document
in knitr, use the
rglwidget function.  (You can also use
chunk option webgl=TRUE; we recommend the explicit use of
rglwidget.)  This approach also
allows display of rgl scenes in
RStudio.  Besides
rgl scenes, various controls for them can
be displayed, and there are a few utility functions
that can be useful:
| Function | Description | 
|---|---|
| propertyControl: | set individual properties | 
| clipplaneControl: | control a clipping plane | 
| subsetControl: | control which objects are displayed | 
| ageControl: | “age” vertices of an object | 
| vertexControl: | control properties of vertices | 
| par3dinterpControl: | WebGL control like par3dinterp | 
| playwidget: | display and automate controls | 
| toggleWidget: | display a button to toggle some items | 
| %>%: | magrittrpipe | 
| figHeight,figWidth: | Dimensions of figures in R Markdown document | 
| rglShared: | share data using crosstalkpackage | 
| rglMouse: | change mouse mode in RGL scene | 
| asRow: | arrange multiple objects in an HTML display | 
| getWidgetId: | get the elementIdfrom a widget | 
These functions work with the above scheme in Shiny apps:
| Function | Description | 
|---|---|
| sceneChange: | used in Shinyfor large scene changes | 
| shinyGetPar3d,shinySetPar3d: | get or set par3dvalues from Shiny | 
| shinyResetBrush: | reset the mouse brush in Shiny | 
The selectionFunction3d function is also likely
to be involved in mouse interactions when using Shiny.
Some functions are mainly for internal use:
elementId2Prefix, playwidgetOutput, renderPlaywidget, rglwidgetOutput, renderRglwidget, registerSceneChange.
More details are given in the vignette
User Interaction in WebGL.
The functions lowlevel, highlevel, rglId are also for internal use,
marking function results for automatic
printing.  Finally, the function
setUserShaders allows you to
use hand-written shaders in WebGL, and
getShaders allows you to see what
shader would be used.
rgl maintains internal structures for all the scenes it displays.
The following functions allow users to find information about them
and manipulate them.  In cases where there are both *3d
and rgl.* versions of functions, most users should use
the *3d version:  the rgl.* functions are more primitive
and are mainly intended for internal use.
| Function | Description | 
|---|---|
| open3d: | open a new window | 
| close3d: | close the current window | 
| cur3d: | id of the active device | 
| set3d: | set a particular device to be active | 
| pop3d: | delete objects from the scene | 
| clear3d: | delete all objects of certain classes | 
| ids3d: | ids, types and tags of current objects | 
| tagged3d: | find tags or objects with tags | 
Some of these functions have alternate names for
back compatibility:
rgl.cur, rgl.ids, rgl.pop.
Either name will work,
but the *3d version is recommended for new code.
Some have deprecated versions:
rgl.clear, rgl.set.  Those should not be called.
These functions are mainly intended for programming, and
have no corresponding *3d counterparts:
| Function | Description | 
|---|---|
| rgl.bringtotop: | bring the current window to the top | 
| rgl.dev.list: | ids of all active devices | 
| rgl.attrib,rgl.attrib.info,rgl.attrib.count: | attributes of objects in the scene | 
| rgl.projection: | return information about the current projection | 
| rgl.user2window,rgl.window2user: | convert between coordinates in the current projection | 
The as.triangles3d generic function is intended to
extract coordinates in a form suitable for passing to
triangles3d.  Currently a method is provided for
rglId objects.
In addition to these, there are some deprecated functions which
should not be called: rgl.init, rgl.open, rgl.close, rgl.quit.
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:
| Function | Description | 
|---|---|
| asEuclidean,asHomogeneous: | convert between homogeneous and Euclidean coordinates when x, y and z are columns | 
| asEuclidean2,asHomogeneous2: | convert when x, y and z are rows | 
| 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 | 
| projectDown: | a 3D to 2D projection down a vector | 
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.
Sometimes it may be convenient to interactively
rotate a scene to a particular view, then
display it in lattice or base graphics.
The rglToLattice and rglToBase functions support this.
For example, we first display the volcano data in rgl:
persp3d(volcano, col = "green")
plot of chunk unnamed-chunk-6
# Only evaluated if the lattice & orientlib packages are installed
lattice::wireframe(volcano, col = "green", 
		   screen = rglToLattice())
plot of chunk unnamed-chunk-7
angles <- rglToBase()
persp(volcano, col = "green", shade = TRUE,
      theta = angles$theta, phi = angles$phi)
plot of chunk unnamed-chunk-7
Note that the orientlib package must be
available for these functions to work.
pkgdown websitesThe “Using RGL in pkgdown web sites” vignette
describes how to use rgl in a pkgdown web site.  The
utility function in_pkgdown_example can be used
to detect that pkgdown is being used.
testthatThe testthat package is widely used for unit tests
in packages.  Such tests are hard to write with rgl,
because the output is visual and interactive rather than
a simple value.  The expect_known_scene,
compare_proxy.mesh3d and
all.equal.mesh3d functions help with
this by removing system-dependent features of rgl
output.
The WebGL displays created using rglwidget
rely on a large body of Javascript code included in this
package.  To help in development of this code, the
makeDependency function was written.
It may be useful in other packages that include Javascript.
This section is for miscellaneous functions and objects that don’t fall in any of the other categories in this document.
The setGraphicsDelay function is designed
to work around what appears to be a bug on macOS:  if
a standard plot window is opened too quickly after an rgl
window, R can crash.  This function inserts a one second
delay when it appears to be needed.
The gltfTypes vector contains
constants used in OpenGL and glTF.
This vignette is always a work in progress.  Some 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:
## [1] "rgl.incrementID" "safe.dev.off"    "textureSource"
The following functions and constants are described in this document:
%>%                                       decorate3d                     movie3d                             rgl.getMouseCallbacks     shinyGetPar3d  
Buffer                                 deform.mesh3d               mtext3d                             rgl.getWheelCallback       shinyResetBrush  
GramSchmidt                       delFromSubscene3d       newSubscene3d                 rgl.material.names           shinySetPar3d  
Sweave.snapshot               deldir                             next3d                               rgl.material.readonly     show2d  
abclines3d                         divide.mesh3d               normalize.mesh3d           rgl.par3d.names                 snapshot3d  
addNormals                         dodecahedron3d             observer3d                       rgl.par3d.readonly           spheres3d  
addToSubscene3d               dot3d                               observer3d                       rgl.pixels                           spin3d  
ageControl                         drape3d                           octahedron3d                   rgl.postscript                   sprites3d  
all.equal.mesh3d             elementId2Prefix         oh3d                                   rgl.projection                   subdivision3d  
arc3d                                   ellipse3d                       open3d                               rgl.select                           subsceneInfo  
arrow3d                               expect_known_scene     par3d                                 rgl.setMouseCallbacks     subsceneList  
as.mesh3d                           extrude3d                       par3dinterp                     rgl.setWheelCallback       subsetControl  
as.mesh3d.default           facing3d                         par3dinterpControl       rgl.snapshot                       surface3d  
as.rglscene                       figHeight                       particles3d                     rgl.useNULL                         tagged3d  
as.tmesh3d                         figWidth                         pch3d                                 rgl.user2window                 terrain3d  
as.triangles3d                 filledContour3d           persp3d                             rgl.window2user                 tetrahedron3d  
asEuclidean                       gc3d                                 pipe                                   rglExtrafonts                     text3d  
asEuclidean2                     getBoundary3d               planes3d                           rglFonts                               texts3d  
asHomogeneous                   getShaders                     play3d                               rglId                                     thigmophobe3d  
asHomogeneous2                 getWidgetId                   playwidget                       rglMouse                               title3d  
asRow                                   getr3dDefaults             playwidgetOutput           rglShared                             tkpar3dsave  
ashape3d                             gltfTypes                       plot3d                               rglToBase                             tkspin3d  
aspect3d                             grid3d                             plotmath3d                       rglToLattice                       tkspinControl  
axes3d                                 highlevel                       points3d                           rglwidget                             tmesh3d  
axis3d                                 hook_rgl                         polygon3d                         rglwidgetOutput                 toggleWidget  
bbox3d                                 hook_webgl                     pop3d                                 rotate3d                               transform3d  
bg3d                                     hover3d                           projectDown                     rotationMatrix                   translate3d  
bgplot3d                             icosahedron3d               propertyControl             scale3d                                 translationMatrix  
box3d                                   identify3d                     qmesh3d                             scaleMatrix                         tri  
checkDeldir                       identityMatrix             quads3d                             scene3d                                 triSht  
clear3d                               ids3d                               r3dDefaults                     sceneChange                         triangles3d  
clearSubsceneList           in_pkgdown_example     readOBJ                             segments3d                           triangulate  
clipMesh3d                         layout3d                         readSTL                             select3d                               turn3d  
clipObj3d                           legend3d                         registerSceneChange     selectionFunction3d         useSubscene3d  
clipplaneControl             light3d                           renderPlaywidget           selectpoints3d                   vertexControl  
clipplanes3d                     lines3d                           renderRglwidget             set3d                                     view3d  
close3d                               lowlevel                         rgl.Sweave                       setAxisCallbacks               view3d  
compare_proxy.mesh3d     makeDependency             rgl.Sweave.off               setGraphicsDelay               wire3d  
contourLines3d                 material3d                     rgl.attrib                       setUserCallbacks               writeASY  
cube3d                                 merge.mesh3d                 rgl.attrib.count           setUserShaders                   writeOBJ  
cuboctahedron3d               mergeVertices               rgl.attrib.info             setupKnitr                           writePLY  
cur3d                                   mesh3d                             rgl.bringtotop               shade3d                                 writeSTL  
currentSubscene3d           mfrow3d                           rgl.dev.list                   shadow3d  
cylinder3d                         mouseMode                       rgl.getAxisCallback     shapelist3d