抖音特效在 Web 端的实现

当下最火的短视频应用莫过于抖音了,凭借着丰富的视频特效,抖音吸引了不少年轻用户的青睐,今天咱们来看一下,抖音特效如何在 Web 端实现。javascript

核心原理

实现原理比较简单,总结起来有以下三个步骤:html

  • 一、使用预渲染 canvas 绘制 video 的每一帧画面。
  • 二、将预渲染 canvas 做为纹理传到显存中。
  • 三、着色器程序对纹理进行后期处理。

步骤看似简单,可是第2、三步骤牵扯到一些 WebGL 和着色器的相关知识,因此你们看不懂的地方不要着急,能够稍微补充一下相关知识。前端

主要实现

每个特效都须要 JS 程序和着色器程序的支持,我会分别从 JS 程序和着色器程序两方面讲解。java

下面的特效旨在演示着色器程序的能力和魅力,因此特效主要在着色器端实现,那么JS 程序作了哪些事情呢?git

JS 主要是实现读取视频的每一帧画面,渲染到一个临时 Canvas 中,并将临时 Canvas 做为纹理传到显存中,如下特效的 JS 部分基本同样,因此咱们先看下 JS 逻辑。github

一、首先看下 html 的结构

<canvas id="canvas"></canvas>
  <canvas id="canvasBg" width="256" height="256"></canvas>
  <video id="video" src="../img/movie.mp4" controls></video>
复制代码

咱们放置了两个 Canvas ,其中第一个 Canvas 用来展现特效,第二个 Canvas 用来绘制视频帧画面,比较简单。web

二、接着看下 JS 逻辑的核心代码

  • 读取视频帧画面,将其渲染到临时 Canvas 上,并将临时 Canvas 做为纹理传送到显存中。
ctxBg.drawImage(video, 0, 0, 256, 256);
  gl.activeTexture(gl.TEXTURE0);
  gl.bindTexture(gl.TEXTURE_2D, texture);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvasBg);
  gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  gl.uniform1i(u_Texture, 0);
复制代码
  • 启动一个定时器,每次传送一个时间变量到显存。
function loop() {
      if (video.ended) {
        return;
      }
      computeFrame();
      time = time + interval;
      gl.uniform1f(u_Time, time);
      // 清除画布
      gl.clear(gl.COLOR_BUFFER_BIT);
      if (positions.length <= 0) {
        return;
      }
      //绘制图元设置为三角形。
      var primitiveType = gl.TRIANGLES;
      //由于咱们要绘制6个点,因此执行6次顶点绘制操做。
      gl.drawArrays(gl.TRIANGLES, 0, positions.length / 3);
      timer = requestAnimationFrame(loop);
    }
复制代码

三、真正实现特效的部分是在着色器程序上,固然着色器源码也是从 JS 中传到显存中,这部分代码咱们按下不表,只带你们感觉一下各个特效。

图像有些虚,你们可能看不太清楚,不过能够去示例网页上去感觉一下~canvas

  • 缩放

  • 闪白

  • 残影

  • 灵魂出窍

  • 毛刺

结语less

以上示例的代码实现中包含一些 WebGL 的基本操做,比较冗长,想看示例的同窗能够移步到个人 github去查看。ide

友情提示:最好在 PC 端查看,移动端浏览仍是有一些体验问题~

最后的最后,小手点一点,关注一下公众号【前端E栈】呗~

相关文章
相关标签/搜索