So I have a Unity plugin for an Android app split into two parts written in c++ (generating two separate .so files ). For discussion purposes I'm going to redact and simplify what they do: first what my c# script does: Code (CSharp): colorTexture = new Texture2D(width, height, TextureFormat.ARGB32, false); externalPluginA.sendID(colorTexture.GetNativeTextureID()); alphaTexture = new Texture2D(width, height, TextureFormat.Alpha8, false); externalPluginB.sendID(alphaTexture.GetNativeTextureID()); now for what externalPluginA does with the first pointer: Code (C++): glBindTexture(GL_TEXTURE_2D, textureID); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, glPixFormat, glPixType, frameBuffer->buff); (frameBuffer->buffer is the raw output of the camera, but we can just assume it's a colored image. I can't check what glPixFormat and glPixFormat are at runtime but that should be irrelevant as you will soon see.) and what externalPluginB does with the second pointer: Code (C++): static std::vector<unsigned char> emptyPixelsAlpha(height * width, 0); glBindTexture(GL_TEXTURE_2D, alphaID); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, emptyPixelsAlpha.data()); this just fills the alpha channel of this texture with zeros, interpretable as a fully transparent alpha channel. colorTexture and alphaTexture are then fed to a material that has this shader: Code (shader): Shader "alphaMaskShader" { Properties{ _MainTex("Base (RGB)", 2D) = "white" {} _Alpha("Alpha (A)", 2D) = "white" {} } SubShader{ Tags{ "RenderType" = "Transparent" "Queue" = "Overlay" } ZWrite Off ZTest Off Blend SrcAlpha OneMinusSrcAlpha ColorMask RGB Pass{ SetTexture[_MainTex]{ Combine texture } SetTexture[_Alpha]{ Combine previous, texture } } } } what this does is simply use alphatexture as the alpha channel for colorTexture, and given that we filled alphaTexture with black it will give as output a fully transparent texture. The fact is this worked perfectly well up until I decided to switch from OpenGL ES 2 to OpenGL ES 3. To transition from one to the other I set OpenGL ES 3 as my Graphics API on Unity and in my two plugins I included GLES/gl3.h headers instead of GLES/gl2.h. The device I'm building on is a OnePlus 3 which supports OpenGL ES 3. what it does now is show the colorTexture fully opaque, as if the alphaTexture were set to opaque. I don't see any particular errors in the log any it isn't crashing or anything. The funny thing is that I decided to open up GAPID and record a trace, and lo and behold the frames shown in GAPID when analyzing the trace are displaying correct functioning, with the texture being completely transparent. I have no clue how this is possible and therefore ask for your help in figuring this out.