示例#1
0
        protected override void OnEnable()
        {
            base.OnEnable();

            m_ShouldRecalculateClipRects = true;
            ClipperRegistry.Register(this);
            MaskUtilities.Notify2DMaskStateChanged(this);
        }
示例#2
0
        protected override void OnDisable()
        {
            base.OnDisable();

            m_MaskableTargets.Clear();
            m_Clippers.Clear();
            ClipperRegistry.UnRegister(this);
            MaskUtilities.Notify2DMaskStateChanged(this);
        }
示例#3
0
        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);
        }
示例#4
0
        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);
            }
        }
示例#6
0
        /// <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;
        }
示例#7
0
        protected override void OnEnable()
        {
            base.OnEnable();

            if (graphic != null)
            {
                graphic.canvasRenderer.hasPopInstruction = true;
                // WG 这里会导致材质的创建
                graphic.SetMaterialDirty();
            }

            // WG 启用裁剪之后这个节点下面的字元素都需要重新计算材质的模板值
            // 由于所有的UI元素都继承与MaskableGraphic,所以这个重新计算写在里面
            MaskUtilities.NotifyStencilStateChanged(this);
        }
示例#8
0
        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;
        }
示例#10
0
        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);
        }