这一块我之前一直看得不是很懂,前几个月有一次做粒子裁剪的时候想模仿做,没有做出来,只能靠着很挫的if来判断。这几天又有一个需求想实现图片的裁剪,不可能一个图片一个panel吧,所以就想到了自己实现Clip Sprite。
在这里先分析一下Ngui Panel的软裁剪是怎么实现的。我之前没有看懂的原因是,NGUI对这块做了大量的优化,单独看一行代码,或者一个公式是看不出什么的,单独看shader也会云里雾里,所以这里我们要结合shader和代码一起看,才能真正了解ngui的设计精巧之处。
首先,我们知道,所有的NGUI渲染都是通过UIDrawCall这个类实现的,所以我们主要分析这个类。
NGUI考虑到了嵌套Soft Clip的情况,设计了一套支持多重嵌套的Soft Clip架构,目前最多支持到三重嵌套。不同嵌套对应的Shader是不一样的,具体设置函数在这(分析也贴在上面了)
void CreateMaterial ()
{
mTextureClip = false;
mLegacyShader = false;
mClipCount = panel.clipCount;
string shaderName = (mShader != null) ? mShader.name :
((mMaterial != null) ? mMaterial.shader.name : "Unlit/Transparent Colored");
// Figure out the normal shader's name
shaderName = shaderName.Replace("GUI/Text Shader", "Unlit/Text");
if (shaderName.Length > 2)
{
if (shaderName[shaderName.Length - 2] == ' ')
{
int index = shaderName[shaderName.Length - 1];
if (index > '0' && index <= '9') shaderName = shaderName.Substring(0, shaderName.Length - 2);
}
}
shaderName = shaderName.Replace(TEXTURE_CLIP, "");
var newShader = shader;
//如果是Mask裁剪,就直接寻找 Unlit/Transparent Colored(TextureClip)这样 或者 Unlit/Text(TextureClip)这样的shader
if (panel.clipping == Clipping.TextureMask)
{
mTextureClip = true;
newShader = Shader.Find(shaderName + TEXTURE_CLIP);
}
else if (mClipCount != 0) //如果父节点有多个裁剪panel 就设置成Soft Clip的形式
{
//寻找的Shader格式为 Unlit/Transparent Colored 1 或者 Unlit/Transparent Colored 2 这样的 ,后缀就是有多少层,最大ngui写到了3,一般够用了
var shaderPath = shaderName + " " + mClipCount;
newShader = Shader.Find(shaderPath);
}
else newShader = Shader.Find(shaderName);
// Always fallback to the default shader 如果找不到 就用默认的shader 一般设置成这个shader,就是达不到你需要的效果了
if (newShader == null) newShader = Shader.Find("Unlit/Transparent Colored");
if (mMaterial != null)
{
mDynamicMat = new Material(mMater