关于Unity UI-Default Shader

2018-12-12  本文已影响0人  LosJun

之前写功能对ui的default shader做了修改,然后遇到一些问题,记录一下(代码可以在下载unity自选的built-in shaders 里面找到)

如何去写自定义shader

想要重写unity的ui材质必须要包含一些固有的参数类型

1.模板缓冲的一堆参数,对unity的mask生效,(我觉得既然作为ui就要遵守ui的模板,不加没有问题,但是我看到过使用自定义材质导致的奇怪的问题,都是不注意细节,比如z-Test默认是开启的,等等)
 Properties
    {
        [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
        _Color ("Tint", Color) = (1,1,1,1)
        _StencilComp ("Stencil Comparison", Float) = 8
        _Stencil ("Stencil ID", Float) = 0
        _StencilOp ("Stencil Operation", Float) = 0
        _StencilWriteMask ("Stencil Write Mask", Float) = 255
        _StencilReadMask ("Stencil Read Mask", Float) = 255

        _ColorMask ("Color Mask", Float) = 15

        [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
    }

    SubShader
    {
        Tags
        {
            "Queue"="Transparent"
            "IgnoreProjector"="True"
            "RenderType"="Transparent"
            "PreviewType"="Plane"
            "CanUseSpriteAtlas"="True"
        }

        Stencil
        {
            Ref [_Stencil]
            Comp [_StencilComp]
            Pass [_StencilOp]
            ReadMask [_StencilReadMask]
            WriteMask [_StencilWriteMask]
        }

        Cull Off
        Lighting Off
        ZWrite Off
        ZTest [unity_GUIZTestMode]
        Blend SrcAlpha OneMinusSrcAlpha
        ColorMask [_ColorMask]

2.默认的shader会有两个宏
      #pragma multi_compile __ UNITY_UI_CLIP_RECT
      #pragma multi_compile __ UNITY_UI_ALPHACLIP

目的是对unity的rect mask 2d 裁剪生效

     #ifdef UNITY_UI_CLIP_RECT
     color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
     #endif

     #ifdef UNITY_UI_ALPHACLIP
     clip (color.a - 0.001);
     #endif

实现原理其实很简单

inline float UnityGet2DClipping (in float2 position, in float4 clipRect)
{
    // 判断当前点是否在矩形中,返回inside.x * inside.y 如果有任意一点不在那么返回值为0
    float2 inside = step(clipRect.xy, position.xy) * step(position.xy, clipRect.zw);
    return inside.x * inside.y;
}

clip对gpu并行化处理影响比较大,所以一般都不勾上这个UNITY_UI_ALPHACLIP宏

所以看你的需求,如果需要rectMask2d的矩形裁剪 ,那么就加上,如果不需要,就删掉,~宏我觉得是没必要加上了,没有必要为你重写的这个shader增加3个变体,是吧

3.关于gpu instancing

你会发现默认的shader带了两个函数接口

       UNITY_SETUP_INSTANCE_ID(v);
       UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);

第一个就是我想解释一下的gpu instancing,听起来还蛮高大上的
GPU Instancing是指由GPU和图形API支持的,用一个Draw Call同时绘制多个Geometry相同的物体的技术。
通过降低dc来降低gpu的开销
第2个是给vr用的,3dxxxx 所以一般游戏也不需要

比较 dynamic batch和 gpu instancing 区别

降低dc的办法嘛,各有

dynamic batch:

unity自己合并网格的一种方式,是合并顶点数,vertex buffer合并传递一个比较大的顶点数量来解决问题的(没有法线uv的情况下应该支持900一下顶点数的object),cpu处做的优化,条件:mesh可以不同,但材质必须相同(同一份)。

gpu instancing:

是基于图形api来实现的,传递相同的vertex buffer, mesh必须是相同的,但是一些(比如位置信息,旋转,颜色等等)是可以通过property block传递给gpu去改变的
附上很不错的教程链接供参考

没有他写得好 就不多废话了 = =

上一篇 下一篇

猜你喜欢

热点阅读