Search code examples
rrgl

rgl fade with depth, depth perception


How can I show objects further away with a fade-out effect in rgl?

Currently, given a 3D scatter plot, R's rgl package displays objects further away with a smaller size. However, I still find it difficult to perceive an object's depth, especially when many points are plotted. In the following example, without rotating, it is hard to see which point is behind another.

x <- 1:101
y <- rnorm(101, sd=15)
z <- x + rnorm(101, sd=15)
library(rgl)
plot3d(x,y,z, type='s')

But in the image below, it is easy to see that points on the left of the picture are further away. How can I achieve a similar effect in rgl? There is an alpha argument, but that does not depend on the depth of each point.


Solution

  • OpenGL supports "fog", and rgl gives you some control over it, though it's not completely obvious how to get it. However, this works if you run it before most functions:

    r3dDefaults$material$fog <- TRUE
    r3dDefaults$bg$fogtype <- "linear"
    

    If you want some parts of your display to fade out and others not, set the material for the non-fogged parts with fog = FALSE. This is normally the default.

    The choices for fog type are c("none", "linear", "exp", "exp2"). With linear fog, your example looks like this:

    screenshot

    If you want to have the fog only affecting the points, you could do it like this:

    r3dDefaults$material$fog <- FALSE
    r3dDefaults$bg$fogtype <- "linear"
    plot3d(x, y, z, type = "s", fog = TRUE)
    

    This works because material properties are only applied to the data, not the axes. I think this version looks better, but your taste may vary:

    enter image description here

    One limitation: fog is not currently supported by the WebGL code produced by rglwidget().

    Edit: It was noted in the comments that calling bgplot3d clears the fog. This was a bug in rgl versions up to 0.100.33, that has been fixed as of 0.100.34. See How do I install the latest version of rgl? for where to get it.

    Edit 2: The development version of rgl (currently 0.102.4) now supports fog in WebGL as well as in R. The display is a little different for fogtype = "exp" and fogtype = "exp2"; I think it actually looks better.