【Unity】UI Stencil遮罩自定义探索
【Unity】UI Stencil遮罩自定义探索

【Unity】UI Stencil遮罩自定义探索

【Unity】关于UIMask遮罩实现以及自定义Stencil Mask Shader实现的探索

前言

前段时间在制作一些UI需求时,需要对一个父节点下的几个子物体UI借助Canvas组件的OverrideSort属性来实现遮盖关系,本来这样已经完成了需求(在父节点有Layout限制下A需要在B的节点排序之前(SetSibling)但是渲染上A又要被B遮挡所以临时想到了利用Canvas这个字段来实现)。

紧接着就遇到了一个问题,原先他们的父节点是一个scroll,而Scroll是需要有Mask属性的,经过测试发现只要是被挂了canvas group组件的子物体都不再收到父节点(包括父节点往上的其他父节点)的Mask组件影响,这就导致了一些UI”穿模”了。为此我Debug花了不少时间,最后没办法借助FrameDebugger根据渲染次序排查发现那些单独挂了Canvas组件的UI物体都不在原先的Scroll从属的CanvasBatch下。然而看了UGUI源码中Mask组件实现后,我发现UGUI的Mask实际上也是一个类似MateialHelper的组件通过识别基类带有MaskableGrphic的物体(这也是为什么Image这些组件有个Maskable的Toggle可以选择),如果他们的父级不再有其他Mask便会根据层级关系(readMask和writeMask)算出对应的StencilValue最后正确的设置给各个组件UIdefault材质球上的Stencil参数里实现嵌套Mask。不过再上述过程中,Mask寻找的物体似乎都只是和他同层Canvas的所以前面遇到的问题应该就是没有被正确加入到Mask整体计算StencilValue。

参考文档:

https://www.cnblogs.com/iwiniwin/p/15131528.html
https://blog.csdn.net/qq826364410/article/details/85103488

查阅完上面两个文档后,我大概对Mask的实现原理有了一个初步的理解,但是距离能够实现自定义Mask根据StencilBuffer实现遮罩剔除还是有些距离,只能初步先手动建立了几个预先设定好stencilPass参数的嵌套Stencil材质球以及对应的Mask材质球和反向挖洞的Hole材质球,然后手动更换了之前项目中遇到挂了Canvas导致Scroll中子物体部分不受Mask影响的物体的材质球(算是半自动实现了嵌套Mask233),后面有机会在继续研究下Mask的源码魔改成可以动态选择是否要跨Canvas识别带MaskableGraphic的子物体进行StencilBuffer计算的脚本

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注