Unity ReckMask2D 与 Mask 的一点小总结

写在最前:

1.工程环境:Unity 2017。

2.UI插件:UGUI。

3.本文章是个人的学习记录贴,如果有幸被翻阅,请不要吐槽排版。


先摘录一下 UI/Default 的相关关键代码,以下描述会用到(本人自己创建了一个Shader,并复制了UI/Default源码,所以可以更改!)

#pragma multi_compile __ UNITY_UI_CLIP_RECT   //-------------------------------------  a
#pragma multi_compile __ UNITY_UI_ALPHACLIP   //-------------------------------------  b

#ifdef UNITY_UI_CLIP_RECT
    color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);   //----------------c
#endif

#ifdef UNITY_UI_ALPHACLIP
    clip(color.a - 0.001);                                        //------------------d
#endif

正文:

1.Mask:

    ①.Mask原理是使用的模板缓冲区,来实现遮罩的功能。在绘制Mask下子物体时,与模板缓冲区的值进行比对来实现的裁剪效果,所以这种裁剪效果可以针对3D物体的。

    ②.实测表明 Mask与Image必须挂在同一GameObject下,否则Mask将失效。个人推测是如果没有Image组件,Mask将无法正确对模板缓冲区写入值,抑或是压根就不会去写入。

    ③.实测会发现,哪怕注释掉上面的 c,d行的代码,Mask依然会正常运作,这更加说明了,Mask的原理是模板缓冲。

    ④.实测发现,Mask会激活 UNITY_UI_CLIP_RECT 关键字 ,相关证据没有找到,但是表现出来的现象是这样。

2.RectMask2D:

    ①.RectMask2D针对2D同平面物体做裁剪,不会产生额外DC。

    ②.RectMask2D会有不完全裁剪的Bug,那种露一半的物体会不被裁剪,可能原因见下一条。

    ③.RectMask2D貌似不会激活 UNITY_UI_CLIP_RECT  关键字。

    ④.使用默认的UI/Default 去渲染Image发现可以被裁剪,复制粘贴官方的源码该下Shader名字发现无法被裁剪,真心坑爹,可能的原因参见第二条,深层原因暂不知道。

    ⑤.如果修改a行代码,将 __ 去掉,发现是可以正确裁剪的,让我更加相信是UNITY_UI_CLIP_RECT没有被激活,同样还是那个问题,为啥 Unity默认的Shader被激活了这个关键字,而我复制粘贴的代码缺没激活,可恶!

简单总结:

    1.简单的2D UI,如果使用到了ScrollRect组件,那么下面的遮罩组件可以用RectMask2D,这样不用写优化逻辑DC就会低很多。如果相关优化逻辑写的好,当然用什么都无所谓。

    2.如果涉及对3D物体进行遮罩,必须使用Mask + Image 的组合,当然你用Unity的选项创建的话,Unity会自动帮你创建好。但是这种涉及模板缓冲的功能比较消耗性能。

    3.表面上看到UI/Default 里面有相关像素裁剪代码(c,d行的代码),但是会发现,哪怕你注释掉了,无论是Mask还是RectMask2D,都能对完全超出视野的元素有裁剪功能,只不过RectMask2D会有不完全裁剪的Bug。

    4.如果你使用到了自己写的Shader遇到了相关裁剪的bug,可以尝试将 a 代码的 __ 去掉,或者 将 c 代码的 #ifdef条件注释掉。


你可能感兴趣的:(Unity3D)