抖音特效在 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棧】唄~

相關文章
相關標籤/搜索