如何在 R 中使用 OpenGL 加速有效地为图像栅格设置动画?
Posted
技术标签:
【中文标题】如何在 R 中使用 OpenGL 加速有效地为图像栅格设置动画?【英文标题】:How to efficiently animate image rasters using OpenGL acceleration in R? 【发布时间】:2019-05-05 23:30:01 【问题描述】:这是对这些问题的后续问题:
Performant 2D OpenGL graphics in R for fast display of raster image using qtpaint (qt) or rdyncall (SDL/OpenGL) packages? Most efficient way of drawing a heatmap from matrix with OpenGL?我想以交互方式查看二维元胞自动机空间离散模拟的输出。所以我从简单开始,试图了解绘制整数值矩阵的速度有多快。我在这里尝试使用rgl
包,据我所知,该包是在 R 中提供(理论上)最快(?)图形设备的包。
我正在使用rgl
尝试这种方法,但帧速率是每秒 30 帧,我发现它相当低(参见下面的代码)。我的示例是从仅 100x100 的 R 矩阵绘制光栅图像。而且,我在闪烁,我不知道为什么。
这是我的方法(遵循@ben-bolker 的回答),现在使用来自@user2554330 的反馈。
library(viridisLite)
library(rgl)
n_colours <- 100
n_row <- 500
n_col <- 500
vv <- viridis(n_colours)
setup <- function()
view3d(theta=0, phi=0) ## head-on view
#par3d(zoom=0.65, windowRect = c(0,0, n_col, n_row), viewport = c(0,0, n_col, n_row))
par3d(zoom=0.65, windowRect = c(0,0, n_col, n_row), viewport = c(0,0, n_col, n_row))
# draw <- function(m)
# d <- dim(m)
# surface3d(x = 1:d[1], y = 1:d[2], z = matrix(0, d[1], d[2]),
# color = vv[m],
# smooth=FALSE, lit=FALSE ## turn off smoothing/lights
# )
#
# draw2 <- function(m)
# par3d(skipRedraw = TRUE) # but skip blank update
# clear3d()
#
# d <- dim(m)
# surface3d(x = 1:d[1], y = 1:d[2], z = matrix(0, d[1], d[2]),
# color = vv[m],
# smooth=FALSE, lit=FALSE ## turn off smoothing/lights
# )
# par3d(skipRedraw = FALSE) # Make sure image is shown
#
draw3 <- function(colours)
par3d(skipRedraw = TRUE) # but skip blank update
clear3d()
d <- dim(m)
surface3d(x = 1:d[1], y = 1:d[2], z = matrix(0, d[1], d[2]),
color = colours,
smooth=FALSE, lit=FALSE ## turn off smoothing/lights
)
par3d(skipRedraw = FALSE) # Make sure image is shown
nframes <- 100
n_matrices <- list()
for(i in 1:nframes)
n_matrices[[i]] <- vv[matrix(sample(1:n_colours, n_row*n_col, replace = TRUE), nrow = n_row)]
setup()
# time <- system.time(
# for (i in 1:nframes)
# draw(n_matrices[[i]])
# par3d(skipRedraw = FALSE) # Make sure image is shown
#
# par3d(skipRedraw = TRUE) # but skip blank update
# pop3d()
#
# par3d(skipRedraw = FALSE)
# )
time <- system.time(
for (i in 1:nframes)
draw3(n_matrices[[i]])
)
fps <- nframes/time[3]
fps
【问题讨论】:
【参考方案1】:闪烁的原因也会减慢您的显示速度。您的pop3d()
电话要求rgl
重绘没有显示表面的图像。通过告诉rgl
跳过重绘,您可以获得大约两倍的速度:
time <- system.time(
for (i in 1:nframes)
draw(n_matrices[[i]])
par3d(skipRedraw = FALSE) # Make sure image is shown
par3d(skipRedraw = TRUE) # but skip blank update
pop3d()
par3d(skipRedraw = FALSE)
)
【讨论】:
谢谢@user2554330!这确实加快了速度。您是否知道如何使窗口大小使一个矩阵元素精确对应一个像素? 我已将pop3d()
与clear3d()
交换,并将绘图/清除功能移至draw3()
。另外,我现在才将颜色传递给draw3d()
,看看是否会有任何性能改进,但它似乎是微不足道的。现在,由于某种原因,最后一帧总是被移动和放大(像素看起来更大)。你知道为什么吗?另外,如何使用缩放参数?如何让窗口完全被纹理填满,周围没有任何空白?你也知道为什么我不能在 for 循环结束之前杀死窗口吗?
似乎这种for循环的方法使窗口无法与鼠标交互。是不是因为计算太忙于绘制新帧,以至于几乎没有时间从鼠标捕获事件?以上是关于如何在 R 中使用 OpenGL 加速有效地为图像栅格设置动画?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Opengl windows 上加速使用 Cairo 绘图?