protected override void OnEnable() { base.OnEnable(); m_ShouldRecalculateClipRects = true; ClipperRegistry.Register(this); MaskUtilities.Notify2DMaskStateChanged(this); }
protected override void OnDisable() { base.OnDisable(); m_MaskableTargets.Clear(); m_Clippers.Clear(); ClipperRegistry.UnRegister(this); MaskUtilities.Notify2DMaskStateChanged(this); }
public Material GetModifiedMaterial(Material baseMaterial) { if (!MaskEnabled()) { return(baseMaterial); } var rootSortCanvas = MaskUtilities.FindRootSortOverriedCanvas(transform); var stencilDepth = MaskUtilities.GetStencilDepth(transform, rootSortCanvas); if (stencilDepth > 8) { Debug.LogWarning("Mask 层级不能超过8层,在同一个canvas下"); return(baseMaterial); } int desiredStencilBit = 1 << stencilDepth; // 第一个Mask if (desiredStencilBit == 0) { // 重新创建一个裁剪材质 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; // TODO WG 不清楚具体现实逻辑 graphic.canvasRenderer.popMaterialCount = 1; graphic.canvasRenderer.SetPopMaterial(m_UnmaskMaterial, 0); return(m_MaskMaterial); } // 不是第一个Mask 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; // TODO WG 不清楚具体现实逻辑 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); }
protected override void OnValidate() { base.OnValidate(); m_ShouldRecalculateClipRects = true; if (!IsActive()) { return; } MaskUtilities.Notify2DMaskStateChanged(this); }
protected override void OnEnable() { base.OnEnable(); m_ShouldRecalculateStencil = true; UpdateClipParent(); SetMaterialDirty(); if (GetComponent <Mask>() != null) { MaskUtilities.NotifyStencilStateChanged(this); } }
/// <summary> /// Update中计算 /// </summary> // TODO 简单实现 public void PerformClipping() { if (ReferenceEquals(Canvas, null)) { return; } if (m_ShouldRecalculateClipRects) { MaskUtilities.GetRectMasksForClip(this, m_Clippers); m_ShouldRecalculateClipRects = false; } bool validRect = true; // 相交区域 Rect clipRect = Clipping.FindCullAndClipWorldRect(m_Clippers, out validRect); RenderMode renderMode = Canvas.rootCanvas.renderMode; // 已经被裁剪 bool maskIsCulled = (renderMode == RenderMode.ScreenSpaceCamera || renderMode == RenderMode.ScreenSpaceOverlay) && !clipRect.Overlaps(rootCanvasRect); if (maskIsCulled) { clipRect = Rect.zero; validRect = false; } if (clipRect != m_LastClipRectCanvasSpace) { foreach (var maskTarget in m_MaskableTargets) { maskTarget.SetClipRect(clipRect, validRect); maskTarget.Cull(clipRect, validRect); } } else if (m_ForceClip) { foreach (var maskTarget in m_MaskableTargets) { maskTarget.SetClipRect(clipRect, validRect); if (maskTarget.canvasRenderer.hasMoved) { maskTarget.Cull(clipRect, validRect); } } } m_LastClipRectCanvasSpace = clipRect; m_ForceClip = false; }
protected override void OnEnable() { base.OnEnable(); if (graphic != null) { graphic.canvasRenderer.hasPopInstruction = true; // WG 这里会导致材质的创建 graphic.SetMaterialDirty(); } // WG 启用裁剪之后这个节点下面的字元素都需要重新计算材质的模板值 // 由于所有的UI元素都继承与MaskableGraphic,所以这个重新计算写在里面 MaskUtilities.NotifyStencilStateChanged(this); }
protected override void OnValidate() { base.OnValidate(); if (!IsActive()) { return; } if (graphic != null) { graphic.SetMaterialDirty(); } MaskUtilities.NotifyStencilStateChanged(this); }
private void UpdateClipParent() { var newParent = (maskable && IsActive()) ? MaskUtilities.GetRectMaskForClippable(this) : null; if (m_ParentMask != null && (newParent != m_Maskable || !newParent.IsActive())) { m_ParentMask.RemoveClippable(this); UpdateCull(false); } if (newParent != null && newParent.IsActive()) { newParent.AddClippable(this); } m_ParentMask = newParent; }
protected override void OnDisable() { base.OnDisable(); if (graphic != null) { graphic.SetMaterialDirty(); graphic.canvasRenderer.hasPopInstruction = false; graphic.canvasRenderer.popMaterialCount = 0; } StencilMaterial.Remove(m_MaskMaterial); m_MaskMaterial = null; StencilMaterial.Remove(m_UnmaskMaterial); m_UnmaskMaterial = null; MaskUtilities.NotifyStencilStateChanged(this); }
public Material GetModifiedMaterial(Material baseMaterial) { var toUse = baseMaterial; if (m_ShouldRecalculateStencil) { var rootCanvas = MaskUtilities.FindRootSortOverriedCanvas(transform); m_StencilValue = MaskUtilities.GetStencilDepth(transform, rootCanvas); m_ShouldRecalculateStencil = false; } 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); }