为UnityARKitPlugin添加OpenGLES2的支持

    在产品刚刚立项的时候我就一直有过一个担忧,就是在未来产品不断迭代,添加功能,集成了各种SDK与库的过程中很可能会由于某些SDK互相依赖的库不一致导致冲突,如今一年多过去,这个问题还是像一颗定时炸弹一样爆炸了。起因是我们现在用到的一个SDK依赖的底层渲染库是OpenGLES2的,虽然对于Metal它也有支持,但是就目前的最新版本,还存在Bug,这就不得不使用OpenGLES2,而我们的AR产品是基于ARKit开发的,ARKit本身是基于Metal渲染的,这就产生了冲突,于是我们需要将ARKit改造为支持OpenGLES2渲染的。
    我最初想的是如果是基于ARKit做重度App开发的人,一定也会遇到同样的问题,事实也确实如我所料,经过搜索,找到了UnityARKitPlugin的官方托管库中找到了一位同样有此需求的开发者,并且它fork了工程做了一个分支,地址是https://bitbucket.org/Unity-Technologies/unity-arkit-plugin/pull-requests/ 里Support OpenGLES2的需求,本以为问题已经迎刃而解了,但是事情似乎总没那么简单,正是由于我们使用UnityARKitPlugin过早,现在的官方库中的版本早已升级改变了很多,而由于我们要做美颜,滤镜等需求时,本身就对ARKit进行了改造,那么解决这个问题要么升级到新的SDK,然后参照我所找到的那个地址里修改,但这显然是不行的,因为升级SDK而导致的更多不可控因素完全无法评估,所以只能去看那位作者具体修改了什么,然后将有用的代码提取到我们现有的SDK中,经过了多次尝试,终于成功了,如果你是使用最新UnityARKitPlugin的开发者,那么你看到这里该感到十分幸运,你可以直接使用那个地址里的修改方式,而如果你是和我一样属于早期UnityARkitPlugin的使用者,那么我会告诉你要修改的注意点具体有哪些。
    最主要修改的是两个文件,一个是Unity里用于渲染摄像头画面的Shader,名字是YUVShader.shader,主要是对他的frag着色器函数里ycbcr的改动,默认是 float4 ycbcr = float4(y, tex2D(_textureCbCr, texcoord).rg, 1.0); 将其改为
#if SHADER_API_GLES
                float4 ycbcr = float4(y, tex2D(_textureCbCr, texcoord).ra, 1.0);
#elif SHADER_API_GLES3
                float4 ycbcr = float4(y, tex2D(_textureCbCr, texcoord).ra, 1.0);
#else
                float4 ycbcr = float4(y, tex2D(_textureCbCr, texcoord).rg, 1.0);
#endif
来判断不同的渲染库使用不同的计算
    第二个要改的就是ARSessionNative.mm,在

static id <MTLTexture> s_CapturedImageTextureY;

static id <MTLTexture> s_CapturedImageTextureCbCr;
后面加上

static GLuint s_OpenGLYTexture = 0;

static GLuint s_OpenGLUVTexture = 0;
再就是didUpdateFrame这个函数里的修改,具体代码有些长,我不在此贴出,可以参照给出的链接里的diff结果做具体的修改
如此回到Unity中将渲染的API改为OpenGLES2,就会发觉ARKit可以正常工作了

fantasycoding.net 2016-2024 © All rights Reserved京ICP备2020039454号-1