Find a root Canvas.
/// <summary> /// See IMaterialModifier.GetModifiedMaterial /// </summary> public virtual Material GetModifiedMaterial(Material baseMaterial) { var toUse = baseMaterial; if (m_ShouldRecalculateStencil) { var rootCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform); m_StencilValue = maskable ? MaskUtilities.GetStencilDepth(transform, rootCanvas) : 0; m_ShouldRecalculateStencil = false; } // if we have a enabled Mask component then it will // generate the mask material. This is an optimisation // it adds some coupling between components though :( Mask maskComponent = GetComponent <Mask>(); if (m_StencilValue > 0 && (maskComponent == null || !maskComponent.IsActive())) { var maskMat = StencilMaterial.Add(toUse, (1 << m_StencilValue) - 1, StencilOp.Keep, CompareFunction.Equal, ColorWriteMask.All, (1 << m_StencilValue) - 1, 0); StencilMaterial.Remove(m_MaskMaterial); m_MaskMaterial = maskMat; toUse = m_MaskMaterial; } return(toUse); }
public Material GetModifiedMaterial(Material baseMaterial) { if (!MaskEnabled()) { return(baseMaterial); } var rootSortCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform); var stencilDepth = MaskUtilities.GetStencilDepth(transform, rootSortCanvas); if (stencilDepth >= 8) { Debug.LogError("Attempting to use a stencil mask with depth > 8", gameObject); return(baseMaterial); } int desiredStencilBit = 1 << stencilDepth; if (desiredStencilBit == 1) { var maskMaterial = StencilMaterial.Add(baseMaterial, 1, StencilOp.Replace, CompareFunction.Always, m_ShowMaskGraphic ? ColorWriteMask.All : 0); StencilMaterial.Remove(m_MaskMaterial); m_MaskMaterial = maskMaterial; var unmaskMaterial = StencilMaterial.Add(baseMaterial, 1, StencilOp.Zero, CompareFunction.Always, 0); StencilMaterial.Remove(m_UnmaskMaterial); m_UnmaskMaterial = unmaskMaterial; graphic.canvasRenderer.popMaterialCount = 1; //todo 这里怎么理解? graphic.canvasRenderer.SetPopMaterial(m_UnmaskMaterial, 0); return(m_MaskMaterial); } //todo stencilID, write/read mask liuhao var maskMaterial2 = StencilMaterial.Add(baseMaterial, desiredStencilBit | (desiredStencilBit - 1), StencilOp.Replace, CompareFunction.Equal, m_ShowMaskGraphic ? ColorWriteMask.All : 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1)); StencilMaterial.Remove(m_MaskMaterial); m_MaskMaterial = maskMaterial2; graphic.canvasRenderer.hasPopInstruction = true; var unmaskMaterial2 = StencilMaterial.Add(baseMaterial, desiredStencilBit - 1, StencilOp.Replace, CompareFunction.Equal, 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1)); StencilMaterial.Remove(m_UnmaskMaterial); m_UnmaskMaterial = unmaskMaterial2; graphic.canvasRenderer.popMaterialCount = 1; graphic.canvasRenderer.SetPopMaterial(m_UnmaskMaterial, 0); return(m_MaskMaterial); }
/// Stencil calculation time! public virtual Material GetModifiedMaterial(Material baseMaterial) { if (!MaskEnabled()) { return(baseMaterial); } var rootSortCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform); var stencilDepth = MaskUtilities.GetStencilDepth(transform, rootSortCanvas); if (stencilDepth >= 8) { Debug.LogError("Attempting to use a stencil mask with depth > 8", gameObject); return(baseMaterial); } int desiredStencilBit = 1 << stencilDepth; // if we are at the first level... // we want to destroy what is there if (desiredStencilBit == 1) { var maskMaterial = StencilMaterial.Add(baseMaterial, 1, StencilOp.Replace, CompareFunction.Always, m_ShowMaskGraphic ? ColorWriteMask.All : 0); StencilMaterial.Remove(m_MaskMaterial); m_MaskMaterial = maskMaterial; var unmaskMaterial = StencilMaterial.Add(baseMaterial, 1, StencilOp.Zero, CompareFunction.Always, 0); StencilMaterial.Remove(m_UnmaskMaterial); m_UnmaskMaterial = unmaskMaterial; graphic.canvasRenderer.popMaterialCount = 1; graphic.canvasRenderer.SetPopMaterial(m_UnmaskMaterial, 0); return(m_MaskMaterial); } //otherwise we need to be a bit smarter and set some read / write masks var maskMaterial2 = StencilMaterial.Add(baseMaterial, desiredStencilBit | (desiredStencilBit - 1), StencilOp.Replace, CompareFunction.Equal, m_ShowMaskGraphic ? ColorWriteMask.All : 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1)); StencilMaterial.Remove(m_MaskMaterial); m_MaskMaterial = maskMaterial2; graphic.canvasRenderer.hasPopInstruction = true; var unmaskMaterial2 = StencilMaterial.Add(baseMaterial, desiredStencilBit - 1, StencilOp.Replace, CompareFunction.Equal, 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1)); StencilMaterial.Remove(m_UnmaskMaterial); m_UnmaskMaterial = unmaskMaterial2; graphic.canvasRenderer.popMaterialCount = 1; graphic.canvasRenderer.SetPopMaterial(m_UnmaskMaterial, 0); return(m_MaskMaterial); }
/// Stencil calculation time! public virtual Material GetModifiedMaterial(Material baseMaterial) { if (!MaskEnabled()) { return(baseMaterial); } var rootSortCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform); var stencilDepth = MaskUtilities.GetStencilDepth(transform, rootSortCanvas); if (stencilDepth >= 8) { Debug.LogWarning("Attempting to use a stencil mask with depth > 8", gameObject); return(baseMaterial); } int desiredStencilBit = 1 << stencilDepth; // if we are at the first level... // we want to destroy what is there if (desiredStencilBit == 1) { var maskMaterial = StencilMaterial.Add(baseMaterial, 1, StencilOp.Replace, CompareFunction.Always, m_ShowMaskGraphic ? ColorWriteMask.All : 0); StencilMaterial.Remove(m_MaskMaterial); m_MaskMaterial = maskMaterial; var unmaskMaterial = StencilMaterial.Add(baseMaterial, 1, StencilOp.Zero, CompareFunction.Always, 0); StencilMaterial.Remove(m_UnmaskMaterial); m_UnmaskMaterial = unmaskMaterial; graphic.canvasRenderer.popMaterialCount = 1; graphic.canvasRenderer.SetPopMaterial(m_UnmaskMaterial, 0); return(m_MaskMaterial); } // 会产生两种材质,Mask自身使用maskMaterial,而非遮罩的材质会交给canvasRenderer。 //otherwise we need to be a bit smarter and set some read / write masks // Mask用于遮罩的材质的模板值计算方法为desiredStencilBit | (desiredStencilBit - 1), // 这意味着模板深度为x的MaskableGraphic,与模板深度为x-1的Mask,有相同的模板值。 // 绘制Mask时会将模板值以replace的操作形式写入模板缓冲区,从而实现被遮罩图像的绘制。 var maskMaterial2 = StencilMaterial.Add(baseMaterial, desiredStencilBit | (desiredStencilBit - 1), StencilOp.Replace, CompareFunction.Equal, m_ShowMaskGraphic ? ColorWriteMask.All : 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1)); StencilMaterial.Remove(m_MaskMaterial); m_MaskMaterial = maskMaterial2; graphic.canvasRenderer.hasPopInstruction = true; var unmaskMaterial2 = StencilMaterial.Add(baseMaterial, desiredStencilBit - 1, StencilOp.Replace, CompareFunction.Equal, 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1)); StencilMaterial.Remove(m_UnmaskMaterial); m_UnmaskMaterial = unmaskMaterial2; graphic.canvasRenderer.popMaterialCount = 1; graphic.canvasRenderer.SetPopMaterial(m_UnmaskMaterial, 0); return(m_MaskMaterial); }
/// <summary> /// See IMaterialModifier.GetModifiedMaterial /// </summary> public virtual Material GetModifiedMaterial(Material baseMaterial) { var toUse = baseMaterial; if (m_ShouldRecalculateStencil) { var rootCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform); m_StencilValue = maskable ? MaskUtilities.GetStencilDepth(transform, rootCanvas) : 0; m_ShouldRecalculateStencil = false; } // if we have a enabled Mask component then it will // generate the mask material. This is an optimisation // it adds some coupling between components though :( // StencilMaterial.Add(...)方法向传入的材质添加了一些模板信息(即后边的一长串参数), // 返回设置好了模板参数的新的材质(StencilMaterial内部做了一些优化, // 对于相同的模板参数会共用同一个材质对象)这个m_StencilValue通过一个简单的变换1 << m_StencilValue) - 1得到一个新的整数值, // 这个值在后续的使用中称为stencilID,在StencilMaterial.Add(...)中我们看到有以下代码: /*newEnt.customMat.SetInt("_Stencil", stencilID); * newEnt.customMat.SetInt("_StencilOp", (int)operation); * newEnt.customMat.SetInt("_StencilComp", (int)compareFunction); * newEnt.customMat.SetInt("_StencilReadMask", readMask); * newEnt.customMat.SetInt("_StencilWriteMask", writeMask); * newEnt.customMat.SetInt("_ColorMask", (int)colorWriteMask); * 对应的,在UI默认的shader中有: * Stencil * { * Ref [_Stencil] * Comp [_StencilComp] * Pass [_StencilOp] * ReadMask [_StencilReadMask] * WriteMask [_StencilWriteMask] * } * * ColorMask [_ColorMask]*/ Mask maskComponent = GetComponent <Mask>(); if (m_StencilValue > 0 && (maskComponent == null || !maskComponent.IsActive())) { var maskMat = StencilMaterial.Add(toUse, (1 << m_StencilValue) - 1, StencilOp.Keep, CompareFunction.Equal, ColorWriteMask.All, (1 << m_StencilValue) - 1, 0); StencilMaterial.Remove(m_MaskMaterial); m_MaskMaterial = maskMat; toUse = m_MaskMaterial; } return(toUse); }
public virtual Material GetModifiedMaterial(Material baseMaterial) { Material result; if (!this.MaskEnabled()) { result = baseMaterial; } else { Transform stopAfter = MaskUtilities.FindRootSortOverrideCanvas(base.transform); int stencilDepth = MaskUtilities.GetStencilDepth(base.transform, stopAfter); if (stencilDepth >= 8) { Debug.LogError("Attempting to use a stencil mask with depth > 8", base.gameObject); result = baseMaterial; } else { int num = 1 << stencilDepth; if (num == 1) { Material maskMaterial = StencilMaterial.Add(baseMaterial, 1, StencilOp.Replace, CompareFunction.Always, (!this.m_ShowMaskGraphic) ? ((ColorWriteMask)0) : ColorWriteMask.All); StencilMaterial.Remove(this.m_MaskMaterial); this.m_MaskMaterial = maskMaterial; Material unmaskMaterial = StencilMaterial.Add(baseMaterial, 1, StencilOp.Zero, CompareFunction.Always, (ColorWriteMask)0); StencilMaterial.Remove(this.m_UnmaskMaterial); this.m_UnmaskMaterial = unmaskMaterial; this.graphic.canvasRenderer.popMaterialCount = 1; this.graphic.canvasRenderer.SetPopMaterial(this.m_UnmaskMaterial, 0); result = this.m_MaskMaterial; } else { Material maskMaterial2 = StencilMaterial.Add(baseMaterial, num | num - 1, StencilOp.Replace, CompareFunction.Equal, (!this.m_ShowMaskGraphic) ? ((ColorWriteMask)0) : ColorWriteMask.All, num - 1, num | num - 1); StencilMaterial.Remove(this.m_MaskMaterial); this.m_MaskMaterial = maskMaterial2; this.graphic.canvasRenderer.hasPopInstruction = true; Material unmaskMaterial2 = StencilMaterial.Add(baseMaterial, num - 1, StencilOp.Replace, CompareFunction.Equal, (ColorWriteMask)0, num - 1, num | num - 1); StencilMaterial.Remove(this.m_UnmaskMaterial); this.m_UnmaskMaterial = unmaskMaterial2; this.graphic.canvasRenderer.popMaterialCount = 1; this.graphic.canvasRenderer.SetPopMaterial(this.m_UnmaskMaterial, 0); result = this.m_MaskMaterial; } } } return(result); }
public virtual Material GetModifiedMaterial(Material baseMaterial) { Material material = baseMaterial; if (m_ShouldRecalculateStencil) { Transform stopAfter = MaskUtilities.FindRootSortOverrideCanvas(base.transform); m_StencilValue = (maskable ? MaskUtilities.GetStencilDepth(base.transform, stopAfter) : 0); m_ShouldRecalculateStencil = false; } if (m_StencilValue > 0 && GetComponent <Mask>() == null) { Material maskMaterial = StencilMaterial.Add(material, (1 << m_StencilValue) - 1, StencilOp.Keep, CompareFunction.Equal, ColorWriteMask.All, (1 << m_StencilValue) - 1, 0); StencilMaterial.Remove(m_MaskMaterial); m_MaskMaterial = maskMaterial; material = m_MaskMaterial; } return(material); }
public virtual Material GetModifiedMaterial(Material baseMaterial) { Material baseMat = baseMaterial; if (this.m_ShouldRecalculateStencil) { Transform stopAfter = MaskUtilities.FindRootSortOverrideCanvas(base.transform); this.m_StencilValue = !this.maskable ? 0 : MaskUtilities.GetStencilDepth(base.transform, stopAfter); this.m_ShouldRecalculateStencil = false; } if ((this.m_StencilValue > 0) && (base.GetComponent <Mask>() == null)) { Material material2 = StencilMaterial.Add(baseMat, (((int)1) << this.m_StencilValue) - 1, StencilOp.Keep, CompareFunction.Equal, ColorWriteMask.All, (((int)1) << this.m_StencilValue) - 1, 0); StencilMaterial.Remove(this.m_MaskMaterial); this.m_MaskMaterial = material2; baseMat = this.m_MaskMaterial; } return(baseMat); }
public virtual Material GetModifiedMaterial(Material baseMaterial) { if (this.graphic == null) { return(baseMaterial); } Transform stopAfter = MaskUtilities.FindRootSortOverrideCanvas(base.transform); int stencilDepth = MaskUtilities.GetStencilDepth(base.transform, stopAfter); if (stencilDepth >= 8) { Debug.LogError("Attempting to use a stencil mask with depth > 8", base.gameObject); return(baseMaterial); } int num2 = ((int)1) << stencilDepth; if (num2 == 1) { Material material = StencilMaterial.Add(baseMaterial, 1, StencilOp.Replace, CompareFunction.Always, !this.m_ShowMaskGraphic ? ((ColorWriteMask)0) : ColorWriteMask.All); StencilMaterial.Remove(this.m_MaskMaterial); this.m_MaskMaterial = material; Material material2 = StencilMaterial.Add(baseMaterial, 1, StencilOp.Zero, CompareFunction.Always, 0); StencilMaterial.Remove(this.m_UnmaskMaterial); this.m_UnmaskMaterial = material2; this.graphic.canvasRenderer.popMaterialCount = 1; this.graphic.canvasRenderer.SetPopMaterial(this.m_UnmaskMaterial, 0); return(this.m_MaskMaterial); } Material material3 = StencilMaterial.Add(baseMaterial, num2 | (num2 - 1), StencilOp.Replace, CompareFunction.Equal, !this.m_ShowMaskGraphic ? ((ColorWriteMask)0) : ColorWriteMask.All, num2 - 1, num2 | (num2 - 1)); StencilMaterial.Remove(this.m_MaskMaterial); this.m_MaskMaterial = material3; this.graphic.canvasRenderer.hasPopInstruction = true; Material material4 = StencilMaterial.Add(baseMaterial, num2 - 1, StencilOp.Replace, CompareFunction.Equal, 0, num2 - 1, num2 | (num2 - 1)); StencilMaterial.Remove(this.m_UnmaskMaterial); this.m_UnmaskMaterial = material4; this.graphic.canvasRenderer.popMaterialCount = 1; this.graphic.canvasRenderer.SetPopMaterial(this.m_UnmaskMaterial, 0); return(this.m_MaskMaterial); }
public virtual Material GetModifiedMaterial(Material baseMaterial) { Material material = baseMaterial; if (this.m_ShouldRecalculateStencil) { Transform stopAfter = MaskUtilities.FindRootSortOverrideCanvas(base.transform); this.m_StencilValue = ((!this.maskable) ? 0 : MaskUtilities.GetStencilDepth(base.transform, stopAfter)); this.m_ShouldRecalculateStencil = false; } Mask component = base.GetComponent <Mask>(); if (this.m_StencilValue > 0 && (component == null || !component.IsActive())) { Material maskMaterial = StencilMaterial.Add(material, (1 << this.m_StencilValue) - 1, StencilOp.Keep, CompareFunction.Equal, ColorWriteMask.All, (1 << this.m_StencilValue) - 1, 0); StencilMaterial.Remove(this.m_MaskMaterial); this.m_MaskMaterial = maskMaterial; material = this.m_MaskMaterial; } return(material); }
/// <summary> /// /// <para> /// See: IMaterialModifier. /// </para> /// /// </summary> /// <param name="baseMaterial"/> public virtual Material GetModifiedMaterial(Material baseMaterial) { if ((UnityEngine.Object) this.graphic == (UnityEngine.Object)null) { return(baseMaterial); } int stencilDepth = MaskUtilities.GetStencilDepth(this.transform, MaskUtilities.FindRootSortOverrideCanvas(this.transform)); if (stencilDepth >= 8) { Debug.LogError((object)"Attempting to use a stencil mask with depth > 8", (UnityEngine.Object) this.gameObject); return(baseMaterial); } int num = 1 << stencilDepth; if (num == 1) { Material material1 = StencilMaterial.Add(baseMaterial, 1, StencilOp.Replace, CompareFunction.Always, !this.m_ShowMaskGraphic ? (ColorWriteMask)0 : ColorWriteMask.All); StencilMaterial.Remove(this.m_MaskMaterial); this.m_MaskMaterial = material1; Material material2 = StencilMaterial.Add(baseMaterial, 1, StencilOp.Zero, CompareFunction.Always, (ColorWriteMask)0); StencilMaterial.Remove(this.m_UnmaskMaterial); this.m_UnmaskMaterial = material2; this.graphic.canvasRenderer.popMaterialCount = 1; this.graphic.canvasRenderer.SetPopMaterial(this.m_UnmaskMaterial, 0); return(this.m_MaskMaterial); } Material material3 = StencilMaterial.Add(baseMaterial, num | num - 1, StencilOp.Replace, CompareFunction.Equal, !this.m_ShowMaskGraphic ? (ColorWriteMask)0 : ColorWriteMask.All, num - 1, num | num - 1); StencilMaterial.Remove(this.m_MaskMaterial); this.m_MaskMaterial = material3; this.graphic.canvasRenderer.hasPopInstruction = true; Material material4 = StencilMaterial.Add(baseMaterial, num - 1, StencilOp.Replace, CompareFunction.Equal, (ColorWriteMask)0, num - 1, num | num - 1); StencilMaterial.Remove(this.m_UnmaskMaterial); this.m_UnmaskMaterial = material4; this.graphic.canvasRenderer.popMaterialCount = 1; this.graphic.canvasRenderer.SetPopMaterial(this.m_UnmaskMaterial, 0); return(this.m_MaskMaterial); }
/// Stencil calculation time! public override Material GetModifiedMaterial(Material baseMaterial) { if (graphic == null) { return(baseMaterial); } var rootSortCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform); var stencilDepth = MaskUtilities.GetStencilDepth(transform, rootSortCanvas); if (stencilDepth >= 8) { Debug.LogError("Attempting to use a stencil mask with depth > 8", gameObject); return(baseMaterial); } int desiredStencilBit = 1 << stencilDepth; // if we are at the first level... // we want to destroy what is there if (desiredStencilBit == 1) { var maskMaterial = StencilMaterial.Add(baseMaterial, 1, StencilOp.Replace, CompareFunction.Always, showMaskGraphic ? ColorWriteMask.All : 0); StencilMaterial.Remove(m_MaskMaterial); m_MaskMaterial = maskMaterial; return(m_MaskMaterial); } //otherwise we need to be a bit smarter and set some read / write masks var maskMaterial2 = StencilMaterial.Add(baseMaterial, desiredStencilBit | (desiredStencilBit - 1), StencilOp.Replace, CompareFunction.Equal, showMaskGraphic ? ColorWriteMask.All : 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1)); StencilMaterial.Remove(m_MaskMaterial); m_MaskMaterial = maskMaterial2; return(m_MaskMaterial); }
/// <summary> /// /// <para> /// See IMaterialModifier.GetModifiedMaterial. /// </para> /// /// </summary> /// <param name="baseMaterial"/> public virtual Material GetModifiedMaterial(Material baseMaterial) { Material baseMat = baseMaterial; if (this.m_ShouldRecalculateStencil) { this.m_StencilValue = !this.maskable ? 0 : MaskUtilities.GetStencilDepth(this.transform, MaskUtilities.FindRootSortOverrideCanvas(this.transform)); this.m_ShouldRecalculateStencil = false; } if (this.m_StencilValue > 0 && (UnityEngine.Object) this.GetComponent <Mask>() == (UnityEngine.Object)null) { Material material = StencilMaterial.Add(baseMat, (1 << this.m_StencilValue) - 1, StencilOp.Keep, CompareFunction.Equal, ColorWriteMask.All, (1 << this.m_StencilValue) - 1, 0); StencilMaterial.Remove(this.m_MaskMaterial); this.m_MaskMaterial = material; baseMat = this.m_MaskMaterial; } return(baseMat); }