参照http://blog.csdn.net/tkokof1/article/details/52107736 这一篇博客
但是他只实现了单层panel的裁剪,虽然他的算法和NGUI的思路是一致的,但是由于传入Shader的值不同,所以不太好移植成多层Panel裁剪。我重新对他的思路进行整理了,并且将值统一为NGUI的规则,传入的值都用_ClipRange0和_ClipArgs0表示。首先是C#端代码
void UpdateClip(UIPanel panel)
{
if (mCam == null) return;
UIPanel currentPanel = panel;
Vector4 cr = new Vector4();
//计算距离最近的父Panel的中心点 这个点存着 如果有多层的话 就可以用panelCenter,这样不需要重复计算了
var panelWorldCorners1 = panel.worldCorners;
var leftBottom1 = mCam.WorldToViewportPoint(panelWorldCorners1[0]);
var topRight1 = mCam.WorldToViewportPoint(panelWorldCorners1[2]);
var panelCenter = Vector3.Lerp(leftBottom1, topRight1, 0.5f);
//遍历所有的父Panel(所以支持嵌套的Soft Clip)
for (int i = 0; currentPanel != null;)
{
//如果父Panel节点有裁剪
if (currentPanel.hasClipping)
{
//这个里面计算裁剪范围和父Panel和当前DrawCall所属的Panel的角度
float angle = 0f;
//Vector4 cr = currentPanel.drawCallClipRange;
// 与NGUI逻辑不同的第一处 这里将坐标统一为ViewPort坐标系
var panelWorldCorners = currentPanel.worldCorners;
var leftBottom = mCam.WorldToViewportPoint(panelWorldCorners[0]);
var topRight = mCam.WorldToViewportPoint(panelWorldCorners[2]);
var center = Vector3.Lerp(leftBottom, topRight, 0.5f);
cr.x = panelCenter.x;
cr.y = panelCenter.y;
cr.z = (topRight.x - leftBottom.x) / 2;
cr.w = (topRight.y - leftBottom.y) / 2;
//如果有多重Soft Clip的话 就会走到这里