简体   繁体   English

Webgl动画纹理性能与画布drawImage性能

[英]Webgl animated texture performance versus canvas drawImage performance

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. 我知道我可以通过使用drawImage将视频的各部分重新绘制到canvas元素上来做到这一点。 In doing research, it appears that it would be possible to do the same thing with an animated texture in WebGL. 在进行研究时,似乎可以对WebGL中的动画纹理进行相同的操作。 Does anyone know if there would be any performance gains by using a WebGL animated texture to do this rather than drawImage? 有谁知道通过使用WebGL动画纹理而不是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. WebGL在2D画布性能方面具有优势,但是,由于您要处理视频,因此问题在于使用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. 考虑到NTSC世界中的视频很少会超过30 FPS(PAL 25 fps),因此您将有很好的时间预算来对视频进行切片和重新绘制。 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). 同样考虑到drawImage是一个非常快速的操作,并且还具有硬件支持(并且可以不使用),因此您可以权衡这些因素, drawImage被不适用于所有硬件(例如低端消费者和较旧的硬件)的WebGL所困扰,并支持它有所不同(在撰写本文时)。

I would initially stick with 2D canvas in this case. 在这种情况下,我最初会坚持使用2D画布。 If you need to do wrapping and projecting of the slices onto 3D objects then 2D canvas is not the best choice however. 如果需要将切片包装和投影到3D对象上,则2D画布不是最佳选择。 You could use CSS 3D transformation for some things directly on the canvas element like quadrilateral transform for example. 您可以直接在画布元素上对某些事物使用CSS 3D变换,例如四边形变换。 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: 一个具有320个切片的替代演示,您可以仅用2D画布将其推开很多:

 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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM