在项目中使用ScrollView来滑动Item,然后item上挂着特效,这个时候如果滑动区域到达mask区域外,item里的图片信息被裁切隐藏,但是特效不会就想做一个把特效一起裁切掉的方法。
首先我们要知道图片信息是怎么被mask裁切掉的。
图片被裁切主要是Material信息里增加了Stencil信息。
这样在UI绘制的时候就会进行模板测试。这里就不具体介绍模板测试了,就只是简单讲述一下。
模板测试就好比一个画出一个矩形,渲染的时候会对矩形里的像素点进行测试,只有满足模板条件的像素点才能保留,不满足的像素点将被抛弃掉。
现在我们只需要按照裁切图片信息的想法去让特效也被裁切掉就好了。
当我们的特效加上上来后,先是获取Canvas,在获取他的StencilDepth,当StencilDepth大于0,修改特效原本的Material成我们特制的就好啦。
public Material m_stancilmaterial; //(全局的)
var renderer = this.gameObject.GetComponent<Renderer>();
var rootCanvas = MaskUtilities.FindRootSortOverrideCanvas(this.transform);
var m_stencilDepth = MaskUtilities.GetStencilDepth(this.transform, rootCanvas);
var toUse = renderer.sharedMaterial;
if (m_stencilDepth > 0)
{
var maskMat_ = StencilMaterial.Add(toUse, (1 << m_stencilDepth) - 1, StencilOp.Keep,
CompareFunction.Equal, ColorWriteMask.All, (1 << m_stencilDepth) - 1, 0);
StencilMaterial.Remove(m_stancilmaterial);
m_stancilmaterial = maskMat_;
toUse = m_stancilmaterial;
}
renderer.material = toUse;
将上面的脚本加载在我们的粒子上,运行游戏的时候有可能会出现下面的情况
这个提示是因为我们这个粒子的shader上缺少stencil方面的变量,只需要在对应的shader里添加就可以了。
添加完后可以查看shader变量里会有这个几个,这样才可以成功的添加Stencil信息。
如果你做到这步你的粒子还是没有正确的被裁切,需要在粒子中选择Render里的Masking选择 Visible inside Mask
如果上一步操作后你还是没有看到你的粒子显示在正确的区域内,你可以设置粒子的sort值。
renderers.sortingOrder = Value; (这里的value 要比父节点的canvas sortoder值大)
本质上其实这里的裁切就是让特效去参与模板测试从而达到我们想要的裁切效果。