Android OpenGL ES實現簡單綠幕摳圖
正文
實現綠幕摳圖,其實想法很簡單。 這裡簡單粗暴的使用著色器替換。
OES Filter
直接實現在相機預覽上的Shader
#extension GL_OES_EGL_image_external : require precision mediump float; varying vec2 vTextureCoordinate; uniform samplerExternalOES uTexture; const float pixel = 30.0; void main() { vec4 tc = texture2D(uTexture, vTextureCoordinate); float r = tc.x * 255.0; float g = tc.y * 255.0; float b = tc.z * 255.0; if(g>140.0 && r<128.0 && b<128.0){ tc.x =1.0; tc.y =1.0; tc.z =1.0; tc.w =0.0; }else{ tc.w =1.0; } gl_FragColor = tc, 1.0; }
這裡的關鍵是,判斷顏色的范圍。這裡簡單的認定 g>140.0 && r<128.0 && b<128.0 時為綠色。當是綠色的時候,就將其顏色換成白色。同時alpha值設置為0.0
BlendShader Filter
這個Shader是將背景的紋理,進行貼圖,貼到我們扣的這部分圖上。
precision mediump float; varying vec2 vTextureCoord; varying vec2 vExtraTextureCoord; uniform sampler2D uTexture; uniform sampler2D uExtraTexture; void main() { vec4 base = texture2D(uTexture, vTextureCoord); vec4 overlay = texture2D(uExtraTexture, vExtraTextureCoord); vec4 outputColor; if(base.r==1.0 && base.g==1.0 && base.b==1.0 && base.a==0.0){ outputColor.r = base.a*base.r + overlay.r * (1.0 - base.a); outputColor.g = base.a*base.g + overlay.g * (1.0 - base.a); outputColor.b = base.a*base.b + overlay.b * (1.0 - base.a); outputColor.a = base.a; }else{ outputColor.r = base.r; outputColor.g = base.g; outputColor.b = base.b; outputColor.a = base.a; } gl_FragColor = outputColor; }
這個shader就是加載瞭兩個貼圖。一個是來自上面相機的FBO的OffscreenTextureId,一個是來自我們另外的背景貼圖。 這段代碼就算,如果是辨認到之前我們處理的區域的話,就將兩個圖片貼加到一起,如果是范圍內,就用原來的圖片。
簡單的綠幕摳圖很簡單,隻是判斷到對應的顏色,然後將對應的貼圖貼到這個部分上,就可以瞭。
最後的效果
- 屏幕中的原圖
最後的效果
缺陷
邊緣情況比較明顯。顯示比較突兀。 我們可以做的更好嗎?
更多關於Android OpenGL ES綠幕摳圖的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- OpenGL Shader實現物件材料效果詳解
- OpenGL Shader實現陰影遮罩效果
- 如何用threejs實現實時多邊形折射
- OpenGL Shader實現簡單轉場效果詳解
- three.js 實現露珠滴落動畫效果的示例代碼