zoukankan      html  css  js  c++  java
  • (六)Graphic与MaskableGraphic详解

    1.前言

    此篇将对UGUI系统中图像显示的核心Graphic类进行详细分析

    2.重点方法分析

    基本流程已经在CanvasUpdate一文中的2.1和2.2节分析过了。即每帧在进行Canvas渲染前通过CanvasRenderer更新mesh和材质等信息,渲染时根据这些信息进行相应渲染。所以UI渲染的基本模块是Canvas。本文对一些核心方法进行详解。

    2.1 GraphicRegistry

    此类有别与GraphicUpdateRegistry,一个只是纯粹用来存储本Canvas下Graphic对象。另一个则是用来更新Canvas,设置Canvas的渲染问题。GraphicReigstry目前只在射线检测中(GraphicRaycaster)使用,即用来获取特定Canvas下的Graphic列表。

    2.2 标记Graphic重建

    标记Graphic重建是通过SetMaterialDirty和SetMeshDirty来标记的。两者均是与Graphic渲染相关的。Layout布局重建相关的则是SetLayoutDirty来标记的。

    2.2 材质Material

    材质分为三个默认材质、材质和渲染材质。优先使用渲染材质,如果没有mask组件则渲染材质和材质相同,最后是默认材质。如果没有指定材质,则使用默认材质。

    默认材质:defaultGraphicMaterial是最备选方案,备胎材质。
    材质:material是指定的材质,一般情况下使用的是此材质。
    渲染材质:materialForRendering一般情况下此材质与material相同,如果存在Mask或者继承IMaterialModifier的组件,则会进行材质修改以达到遮罩的效果。

     

    2.3 重构Rebuild

    Rebuild是Graphic的核心,即通过Rebuild来实现材质、网格等的修改,其流程如下:
    1)剔除,如果CanvasRenderer.cull,则直接退出。
    2)如果标记几何(mesh)更新,则进行网格更新(DoMeshGeneration),通过OnPopulateMesh来更新mesh,这也是自定义网格时经常用到的。可以自定义组件继承Graphic,然后重写OnPopulateMesh来自定义网格形状,结合VertexHelper可进行UIMesh的各种样式定制,比如游戏角色的属性图、饼状图、柱状图以及各种函数曲线。
    3)如果标记材质更新,则更新Material以及贴图等信息。

    2.3.1几种OnPopulateMesh

    1)Graphic默认方法

            protected virtual void OnPopulateMesh(VertexHelper vh)
            {
                var r = GetPixelAdjustedRect();
                var v = new Vector4(r.x, r.y, r.x + r.width, r.y + r.height);
    
                Color32 color32 = color;
                vh.Clear();
                vh.AddVert(new Vector3(v.x, v.y), color32, new Vector2(0f, 0f));
                vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(0f, 1f));
                vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(1f, 1f));
                vh.AddVert(new Vector3(v.z, v.y), color32, new Vector2(1f, 0f));
    
                vh.AddTriangle(0, 1, 2);
                vh.AddTriangle(2, 3, 0);
            }
    

    2)RawImage重写mesh方法

            protected override void OnPopulateMesh(VertexHelper vh)
            {
                Texture tex = mainTexture;
                vh.Clear();
                if (tex != null)
                {
                    var r = GetPixelAdjustedRect();
                    var v = new Vector4(r.x, r.y, r.x + r.width, r.y + r.height);
                    var scaleX = tex.width * tex.texelSize.x;
                    var scaleY = tex.height * tex.texelSize.y;
                    {
                        var color32 = color;
                        vh.AddVert(new Vector3(v.x, v.y), color32, new Vector2(m_UVRect.xMin * scaleX, m_UVRect.yMin * scaleY));
                        vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(m_UVRect.xMin * scaleX, m_UVRect.yMax * scaleY));
                        vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(m_UVRect.xMax * scaleX, m_UVRect.yMax * scaleY));
                        vh.AddVert(new Vector3(v.z, v.y), color32, new Vector2(m_UVRect.xMax * scaleX, m_UVRect.yMin * scaleY));
    
                        vh.AddTriangle(0, 1, 2);
                        vh.AddTriangle(2, 3, 0);
                    }
                }
            }
    

    3)Image方法
    image由于涉及到许多不同的表现形式,所以比较复杂,此处就不贴代码了。

    2.4 遮罩效果

    UGUI可以通过遮罩只显示部分图像(遮罩详细流程参考此文2.3节),这之中分为Mask和RectMask2D,前者使用像素级别的检测,原理是根据GPU模板检测实现的,后者只能实现Rect遮罩,通过CanvasRenderer实现,所以Mask能达到更多的效果,但是性能消耗更高。如果想了解Mask的原理,可参考(一)(二)(三)个文献。

    2.4.1 Mask

    Mask的实现流程比较简单,只要Graphic继承IMaskable, IMaterialModifier两个接口即可(Mask以及MaskableGraphic)。IMaterialModifier的作用是通过修改该材质来达到模板检测剔除的功能。而IMaskable则是上层逻辑接口。即当Mask生效时,会通知所有的的子游戏物体的IMaskable组件RecalculateMasking,来实现所有子游戏物体的遮罩功能。

    2.4.2 RectMask2D

    Rect遮罩则比较麻烦,需要Graphic继承实现IClippable接口。当RectMask2D生效时,会通知所有的子游戏物体的IClippable组件进行RecalculateClipping,然后通过SetClipRect设置EnableRectClipping,通过Cull方法进行操作。

    3.结语

    以上为Graphic类重点方法的详细分析。

  • 相关阅读:
    琴生(Jensen)不等式
    基本不等式
    集成学习之梯度提升树(GBDT)
    EM 算法原理
    FSMC驱动8位TFT
    GitHub 上有什么嵌入式方面的项目?
    在SPI_FLASH上建立文件系统
    百为STM32开发板教程——从LED流水灯到UCGUI手机界面
    STM32F1_外部NorFlash存储程序代码
    nor flash之擦除和写入
  • 原文地址:https://www.cnblogs.com/llstart-new0201/p/12640928.html
Copyright © 2011-2022 走看看