rgl icon indicating copy to clipboard operation
rgl copied to clipboard

Shiny displays are too slow

Open dmurdoch opened this issue 4 years ago • 5 comments

An rgl scene can be shown in a Shiny app, but small changes to the scene take a long time to show up, because currently the whole scene needs to be sent to the browser and processed; there isn't an easy way to say to update the current scene with minimal new data transferred.

dmurdoch avatar Feb 02 '21 21:02 dmurdoch

Naive question, does that mean a scene cannot be controlled by reactive variables in a shiny app?

I am new to rgl but I do like the concept of rendering scenes within a shiny app based on data within the app.

schienstockd avatar Dec 28 '21 00:12 schienstockd

No, it just makes it harder to do. It's easy to generate a new scene in Shiny, but that's slow. What you need to do is to figure out how to trigger some Javascript that will send messages to the existing scene. See the WebGL vignette for examples where the messages are generated by HTML controls like buttons and sliders. If your Shiny code can generate those messages, that will be quick.

dmurdoch avatar Dec 28 '21 09:12 dmurdoch

Are there examples available with multiple vertices being simultaneously updated by vertexControl()? I haven't been able to wrap my head around it, unfortunately. I would greatly appreciate being able to avoid redraws of an existing scene when plotting meshes in a Shiny app.

J0vid avatar Dec 31 '21 06:12 J0vid

Here's a simple one. It starts with a cube (which is rendered as 6 quads, with 24 total vertices), and then rotates two of the vertices around the z axis.

open3d()
shade3d(cube3d(), col="red")
objid <- ids3d()$id
xyz <- rgl.attrib(objid, "vertices")

# Move the first 2 vertices

values <- matrix(NA, 100, 6)
theta <- seq(0, 2*pi, len = 100)
for (i in 1:100) {
  xyz1 <- rotate3d(xyz[1:2,], x = 0, y = 0, z = 1, angle = theta[i])
  values[i, 1:3] <- xyz1[1,]
  values[i, 4:6] <- xyz1[2,]
}
widget <- rglwidget(width = 500, height = 500) %>%
          playwidget(vertexControl(values = values, 
                                   vertices = rep(1:2, each=3),
                                   attributes = rep(c("x", "y", "z"), 2),
                                   objid = objid,
                                   param = 1:100))

widget

dmurdoch avatar Dec 31 '21 10:12 dmurdoch

I was able to get it to work with my mesh assets, although I've definitely got to make my part of the code faster to insert it into a Shiny app. Thank you for that excellent example, Duncan! output

J0vid avatar Dec 31 '21 18:12 J0vid