public void UpdateMaterial(UpdateContext context)
{
NMaterial nm = null;
if (_manager != null && !_customMatarial)
{
nm = _manager.GetMaterial(this, context);
_material = nm.material;
if ((object)_material != (object)meshRenderer.sharedMaterial && (object)_material.mainTexture != null)
{
meshRenderer.sharedMaterial = _material;
}
if (nm.combined)
{
_material.SetTexture("_AlphaTex", _manager.texture.alphaTexture.nativeTexture);
}
}
if (maskFrameId != 0 && maskFrameId != UpdateContext.frameId)
{
//曾经是遮罩对象,现在不是了
if (_stencilEraser != null)
{
_stencilEraser.enabled = false;
}
}
if (_material != null)
{
if (blendMode != BlendMode.Normal) //GetMateria已经保证了不同的blendMode会返回不同的共享材质,所以这里可以放心设置
{
BlendModeUtils.Apply(_material, blendMode);
}
if (context.clipped)
{
if (maskFrameId != UpdateContext.frameId && context.rectMaskDepth > 0) //在矩形剪裁下,且不是遮罩对象
{
_material.SetVector("_ClipBox", context.clipInfo.clipBox);
if (context.clipInfo.soft)
{
_material.SetVector("_ClipSoftness", context.clipInfo.softness);
}
}
if (context.stencilReferenceValue > 0)
{
if (maskFrameId == UpdateContext.frameId) //是遮罩
{
if (context.stencilReferenceValue == 1)
{
_material.SetInt("_StencilComp", (int)UnityEngine.Rendering.CompareFunction.Always);
_material.SetInt("_Stencil", 1);
_material.SetInt("_StencilOp", (int)UnityEngine.Rendering.StencilOp.Replace);
_material.SetInt("_StencilReadMask", 255);
_material.SetInt("_ColorMask", 0);
}
else
{
_material.SetInt("_StencilComp", (int)UnityEngine.Rendering.CompareFunction.Equal);
_material.SetInt("_Stencil", context.stencilReferenceValue | (context.stencilReferenceValue - 1));
_material.SetInt("_StencilOp", (int)UnityEngine.Rendering.StencilOp.Replace);
_material.SetInt("_StencilReadMask", context.stencilReferenceValue - 1);
_material.SetInt("_ColorMask", 0);
}
//设置擦除stencil的drawcall
if (_stencilEraser == null)
{
_stencilEraser = new StencilEraser(gameObject.transform);
_stencilEraser.meshFilter.mesh = mesh;
}
else
{
_stencilEraser.enabled = true;
}
if (nm != null)
{
NMaterial eraserNm = _manager.GetMaterial(this, context);
eraserNm.stencilSet = true;
Material eraserMat = eraserNm.material;
if ((object)eraserMat != (object)_stencilEraser.meshRenderer.sharedMaterial)
{
_stencilEraser.meshRenderer.sharedMaterial = eraserMat;
}
int refValue = context.stencilReferenceValue - 1;
eraserMat.SetInt("_StencilComp", (int)UnityEngine.Rendering.CompareFunction.Equal);
eraserMat.SetInt("_Stencil", refValue);
eraserMat.SetInt("_StencilOp", (int)UnityEngine.Rendering.StencilOp.Replace);
eraserMat.SetInt("_StencilReadMask", refValue);
eraserMat.SetInt("_ColorMask", 0);
}
}
else
{
int refValue = context.stencilReferenceValue | (context.stencilReferenceValue - 1);
_material.SetInt("_StencilComp", (int)UnityEngine.Rendering.CompareFunction.Equal);
_material.SetInt("_Stencil", refValue);
_material.SetInt("_StencilOp", (int)UnityEngine.Rendering.StencilOp.Keep);
_material.SetInt("_StencilReadMask", refValue);
_material.SetInt("_ColorMask", 15);
}
if (nm != null)
{
nm.stencilSet = true;
}
}
else if (nm != null && nm.stencilSet)
{
_material.SetInt("_StencilComp", (int)UnityEngine.Rendering.CompareFunction.Always);
_material.SetInt("_Stencil", 0);
_material.SetInt("_StencilOp", (int)UnityEngine.Rendering.StencilOp.Keep);
_material.SetInt("_StencilReadMask", 255);
_material.SetInt("_ColorMask", 15);
nm.stencilSet = false;
}
else
{
_material.SetInt("_StencilComp", (int)UnityEngine.Rendering.CompareFunction.Always);
_material.SetInt("_Stencil", 0);
_material.SetInt("_StencilOp", (int)UnityEngine.Rendering.StencilOp.Keep);
_material.SetInt("_StencilReadMask", 255);
_material.SetInt("_ColorMask", 15);
}
}
}
}