UI上ScrollRect裁剪粒子系统

https://www.cnblogs.com/devgl/p/6598781.html
关于unity的ui优化之mask,可以参考这篇文章
https://zhuanlan.zhihu.com/p/32561155
Mask组件原理是stencil先渲染一遍蒙版,写入一个值,然后再渲染子物体,对比stencil的buffer,没写入值的区域才渲染。多一遍dc,
RectMask2D原理则是,UnityGet2DClipping这个函数实现了判断2D空间中的一点是否在一个矩形区域中,将不在矩形区域里的像素裁剪掉。
下面文章自定义了一个CircleImage组件:http://www.cnblogs.com/leoin2012/p/6425089.html,重置了组件的mesh、顶点等,也重新定义了判断相交的算法,否则点击事件的定位会不精准。原理见https://www.zhihu.com/question/26551754。
上面有了圆形物体生成,那么对于不规则形状的物体怎么优化呢。MeshMask组件:http://www.cnblogs.com/leoin2012/p/6822859.html。
不同于CircleImage,只需要简单的对圆形进行顶点,面片计算;MeshMask要考虑几个点:

需要能对所有可能的图形进行顶点,面片计算。
考虑顶点,面片计算需要读取Image,且有一定性能开销,所以不能在Run-time中实时计算数据,需要预先计算好vertices,triangle数据,并序列化存放在GameObject中,运行时读取。
保证MeshMask灵活性,除了根据Image进行顶点,面片计算,希望像PS一样,提供路径工具,让开发可以可视化地新增、修改Mask形状。
对所有图形支持像素级点击判断。
面片计算比较麻烦,涉及以下几个知识点:
1. 图片标记,非透明区域设为某种颜色(因为只要考虑最外侧的边缘);
2. 找到图片非透明区域的轮廓边缘(边缘检测算法,比如sobel算法);
3. 离散化:将轮廓边缘转成有序顶点集,得到顶点数据(剔除冗余信息,并将边缘信息以有序集合的形式表示。这个有序集合,就是渲染底层需要的顶点数据。冗余节点:对于边缘的直线,除直线的首尾两点外,其他点都是冗余的。有序集合,集合点依次连接起来,就如同按逆时针或顺时针方向画出来的边缘图形);
笔者挑选了边缘点集中x最小的点作为起始点,以顺时针顺序查找邻接点的方法来计算有序顶点集。
算法步骤:

选择边缘点集x最小的点为起始点,当前点
查找当前点周边8个像素点是否有边缘点,如都没有就继续向外围一圈,直到找到边缘点。
当找到多个边缘点情况下,比较当前点与各边缘点所呈夹角,选夹角最小的边缘点作为邻接点。
若邻接点即为起始点,则算法结束,否则继续
判断邻接点与有序顶点集最后一个点是否共边,若共边则删除最后一个点
将邻接点加入有序顶点集
设置邻接点为当前点,重复步骤2
4. 三角化:有序顶点集做三角化,得出面片数据。
三角化(Triangulation)也是图形学应用较多的算法了,特别是在3D建模、游戏领域。三角化是指从一组已知点集中,构建出三角形网格。随着构建条件不同,三角化算法也不同。像最近LowPoly绘画风格比较热门,一些滤镜软件会支持LowPoly转换。软件在将一张普通图像转换位LowPoly图像的过程中,除了一样要做边缘检测,离散化外,在三角化这一步,需要生成显示质量较高的三角形,不能有过于狭长的三角形,就需要用Delaunay算法。在我们这个场景下,对生成的三角形并没有特殊要求,不需要用上复杂的Delaunay算法,Unity3d wiki社区上提供了一个简单的三角化算法,刚好适用。
算法原理
从点集中随机挑选三点组成三角形,然后遍历其他点,看是否有点落在三角形内,如果三角形内无点则为合格三角形。循环此过程直到所有点都被处理。

你可能感兴趣的:(Unity)