opengl轉場效果

  • 前提
    上一篇文章說到ffmpeg合成轉場效果,后來發現這樣的方案行不通的,一是合成時間太慢,而是需要實時的查看轉場的效果,所以應該要動態查看轉場的效果。所以用opengl實現轉場方案最合適不過了

  • 實現步驟:
    圖片轉場:兩個圖片進行切換是,傳入前一張和當前張圖片的紋理到轉場的(transitionfilter)濾鏡中,在圖片切換的時候,展示transitionfilter
    視頻轉場:截取當前視頻的第一幀和上一視頻的最后一幀圖片,同樣給transitionfilter賦值,在視頻切換的時候,顯示transitionfilter

  • 搭建環境注意點
    因為用到opengl,所以得要用glsurfaview去承載渲染,對于視頻而言,根據相機用glsurfaview顯示一個道理

SurfaceTexture surfaceTexture = mOpenglDrawer.getSurfaceTexture();
surfaceTexture.setOnFrameAvailableListener(new SurfaceTexture.
OnFrameAvailableListener() {
    @Override
    public void onFrameAvailable(SurfaceTexture surfaceTexture) {
        requestRender();
    }
});
Surface surface = new Surface(surfaceTexture);
mMediaPlayer.setSurface(surface);
if (isCurrentVideo()) {
    mMediaPlayer.prepare();
    mOpenglDrawer.setInputTextureVideo();
}

對于圖片,則手動去推動,按照一秒25幀默認,那么就是40ms推動一次渲染
剩下就是編寫opengl的fragment片段的事情了,不過對于視頻幀的轉場而言,需要對紋理進行轉化一下,因為最開始視頻進來的fragment定義的紋理對象是uniform samplerExternalOES vTexture;
所以需要創建一層FBO:

   GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height,
                    0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);

然后從FBO刷新出來的紋理便是sampler2D了,在用這個紋理去做transitionfilter的轉場

  • 代碼演示
    放一個最簡單的移動切換的fragment代碼:
varying vec2 textureCoordinate;
uniform float progress;
uniform sampler2D vTexture;
uniform sampler2D vTexture1;
uniform vec2 direction;
void main(){
vec2 p = textureCoordinate +  progress*sign(direction);
float m =step(0.0, p.y) * step(p.y, 1.0) * step(0.0, p.x) * step(p.x, 1.0);
vec4 color = mix(texture2D(vTexture, textureCoordinate),
texture2D(vTexture1, textureCoordinate), m);
gl_FragColor = vec4(color);
}

豐富的轉場案例可以從這里得到:
https://gl-transitions.com/gallery
這個網站中,uv轉化成自己的紋理坐標, getFromColor(uv)換成自己的紋理:比如上面的我第一張紋理是texture2D(vTexture, textureCoordinate)
getToColor(uv)換成第二張紋理:對應我自己的是texture2D(vTexture1, textureCoordinate)

下篇文章介紹帶轉場效果、濾鏡的多視頻多圖片的視頻合成

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。