抖音特效在 Web 端的實現


當下最火的短視頻應用莫過於抖音了,憑借着豐富的視頻特效,抖音吸引了很多年輕用戶的青睞,今天我們來看一下,抖音特效如何在 Web 端實現。

核心原理

實現原理比較簡單,總結起來有如下三個步驟:

  • 1、使用預渲染 canvas 繪制 video 的每一幀畫面。
  • 2、將預渲染 canvas 作為紋理傳到顯存中。
  • 3、着色器程序對紋理進行后期處理。

步驟看似簡單,但是第二、三步驟牽扯到一些 WebGL 和着色器的相關知識,所以大家看不懂的地方不要着急,可以稍微補充一下相關知識。

主要實現

每一個特效都需要 JS 程序和着色器程序的支持,我會分別從 JS 程序和着色器程序兩方面講解。

下面的特效旨在演示着色器程序的能力和魅力,所以特效主要在着色器端實現,那么JS 程序做了哪些事情呢?

JS 主要是實現讀取視頻的每一幀畫面,渲染到一個臨時 Canvas 中,並將臨時 Canvas 作為紋理傳到顯存中,以下特效的 JS 部分基本一樣,所以我們先看下 JS 邏輯。

1、首先看下 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 用來繪制視頻幀畫面,比較簡單。

2、接着看下 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); } 復制代碼

3、真正實現特效的部分是在着色器程序上,當然着色器源碼也是從 JS 中傳到顯存中,這部分代碼我們按下不表,只帶大家感受一下各個特效。

圖像有些虛,大家可能看不太清楚,不過可以去示例網頁上去感受一下~

  • 縮放

 

 

  • 閃白

 

 

  • 殘影

 

 

  • 靈魂出竅

 

 

  • 毛刺

 

 

結語

以上示例的代碼實現中包含一些 WebGL 的基本操作,比較冗長,想看示例的同學可以移步到我的 github去查看。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM