Webgl动画纹理性能与canvas drawImage性能相比 [英] Webgl animated texture performance versus canvas drawImage performance

查看:1127
本文介绍了Webgl动画纹理性能与canvas drawImage性能相比的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始一个项目,我想从一个视频片段,并重新绘制这些部分到屏幕上的不同对象。我知道我可以这样做,通过使用drawImage重新绘制视频的部分到一个canvas元素。在做研究,似乎可以在WebGL中使用动画纹理做同样的事情。有没有人知道如果使用WebGL动画纹理这样做而不是drawImage会有任何性能的提高?

解决方案

WebGL在2D画布性能上有一个优势,但是,因为你处理视频,那么问题是,如果有是使用WebGL的任何点。



考虑到NTSC世界中的视频很少超过30 FPS(PAL 25 fps),你将有一个很好的时间预算切片视频和重绘。还要考虑 drawImage 是一个非常快的操作,并且具有硬件支持(以及没有),你可以加权这些反对使用WebGL,它不工作在所有硬件像低端消费者和旧硬件),并且对它的支持各不相同(在撰写本文时)。



在这种情况下,我最初坚持使用2D画布。如果你需要做包装和投影切片到3D对象,然而2D画布不是最好的选择。您可以直接在canvas元素上使用CSS 3D变换来处理某些,例如四边形变换。只要使用不同的画布元素,每个代表一个切片,如果你需要不同的变换。



这里的一个技巧btw。是创建一个离屏画布,你将框架绘制到第一。这样,您就不必使用运行中的视频抓取视频,因为根据浏览器如何抓取视频位图数据,可能是一种昂贵的操作。



示例:



  var ctx = canvas.getContext('2d'),sw = 32,frame = document.createElement(canvas),//frame bufferfctx = frame.getContext(2d); frame.width = 500; frame.height = 280; video.addEventListener ,sliceAndDice,false); function sliceAndDice(){fctx.drawImage(video,0,0); //视频到帧缓冲器以使其更平滑//对于(var x = 0; x  

 < canvas id =canvaswidth = 560 height = 320>< / canvas>< video style =display:noneid =videowidth =500height =280preload =autoautoplay = > < source src =// clips.vorwaerts-gmbh.de/big_buck_bunny.mp4type =video / mp4> < source src =// clips.vorwaerts-gmbh.de/big_buck_bunny.webmtype =video / webm> < source src =// clips.vorwaerts-gmbh.de/big_buck_bunny.ogvtype =video / ogg>< / video>  

div>



有320个切片的另一个演示,可以用2D画布推动它:



 

 < canvas id = canvaswidth = 560 height = 320>< / canvas>< video style =display:noneid =videowidth =500height =280preload = < source src =// clips.vorwaerts-gmbh.de/big_buck_bunny.mp4type =video / mp4>< source src =// clips.vorwaerts-gmbh.de/big_buck_bunny.webm type =video / webm>< source src =// clips.vorwaerts-gmbh.de/big_buck_bunny.ogvtype =video / ogg>< / video>  


I'm beginning a project where I would like to slice sections from a single video and redraw those sections onto different objects on the screen. I know I can do this by using drawImage to redraw the sections of the video onto a canvas element. In doing research, it appears that it would be possible to do the same thing with an animated texture in WebGL. Does anyone know if there would be any performance gains by using a WebGL animated texture to do this rather than drawImage?

解决方案

WebGL has an edge over 2D canvas performance wise, however, since you are dealing with video then the question would be if there is any point using WebGL.

Considering that video in the NTSC world rarely exceed 30 FPS (PAL 25 fps) you will have a nice time budget slicing the video and redrawing them. Also considering that drawImage is a very fast operation and has hardware support as well (and works without), you could weight these against bothering with WebGL which does not work on all hardware (like low-end consumer and older hardware), and support for it varies (at the moment of this writing).

I would initially stick with 2D canvas in this case. If you need to do wrapping and projecting of the slices onto 3D objects then 2D canvas is not the best choice however. You could use CSS 3D transformation for some things directly on the canvas element like quadrilateral transform for example. Just use different canvas elements each representing a slice if you need different transformations.

A trick here btw. is to create an off-screen canvas which you draw the frame into first. This way you don't have to grab from the element with a running video which may be an expensive operation depending on how the browser will grab the video bitmap data.

An example:

var ctx = canvas.getContext('2d'),
    sw = 32,
    frame = document.createElement("canvas"), // "frame buffer"
    fctx = frame.getContext("2d");

frame.width = 500;
frame.height = 280;

video.addEventListener("playing", sliceAndDice, false);
function sliceAndDice() {

  fctx.drawImage(video, 0, 0); // video to "frame buffer" to make it more smooth
  
    // some misc slicing
    for(var x = 0; x < frame.width; x += sw) {
        var y = Math.sin(x*1.5) * sw + 20;
        ctx.drawImage(frame, x      , 0, sw, frame.height,   // source slice
                             x * 1.1, y, sw, frame.height);  // dest. slice
    }
    requestAnimationFrame(sliceAndDice);
}

<canvas id="canvas" width=560 height=320></canvas>
<video style="display:none" id="video" width="500" height="280" preload="auto" autoplay="true">
  <source src="//clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" type="video/mp4">
  <source src="//clips.vorwaerts-gmbh.de/big_buck_bunny.webm" type="video/webm">
  <source src="//clips.vorwaerts-gmbh.de/big_buck_bunny.ogv" type="video/ogg">
</video>

An alternative demo with 320 slices to show you can push it pretty far with just 2D canvas:

var ctx = canvas.getContext('2d'),
    frame = document.createElement("canvas"),         // "frame buffer"
    fctx = frame.getContext("2d"),
    dlt = 0;

frame.width = video.width;
frame.height = video.height;

video.addEventListener("playing", sliceAndDice, false);
function sliceAndDice() {

  fctx.drawImage(video, 0, 0);   // video to frame buffer to make it smoother
  
  // some misc slicing
  for(var x = 0, y; x < frame.width; x++) {
      y = Math.sin(x*32+dlt) * 3 + 10;               // "random" y pos.
      ctx.drawImage(frame, x, 0, 1, frame.height,   // source slice
                           x, y, 1, frame.height);  // dest. slice
  }
  dlt += 0.2;
  requestAnimationFrame(sliceAndDice);
};

<canvas id="canvas" width=560 height=320></canvas>
<video style="display:none" id="video" width="500" height="280"
       preload="auto" autoplay="true">
<source src="//clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" type="video/mp4">
<source src="//clips.vorwaerts-gmbh.de/big_buck_bunny.webm"type="video/webm">
<source src="//clips.vorwaerts-gmbh.de/big_buck_bunny.ogv" type="video/ogg">
</video>

这篇关于Webgl动画纹理性能与canvas drawImage性能相比的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆