• 如何修改 GUI 默认 shader 实现自定义 UI 表现


    大伙开发中可能会遇到 GUI中的组件默认表现行为需要修改的情况,比如Image需要加UV动画,去色,或则需要做特殊处理等等,这些需求完全可以通过下载并编辑buildin shader 来实现,这样既不会破坏GUI的整体行为,也能扩展出各种表现。步骤如下

    1.前往 “Unity 2019.x Unity官方下载_Unity最新版_从Unity Hub下载安装 | Unity中国官网”下载 ,你当前使用unity版本对应的 buildin shader 包。

    2.解压并打开包可以看到 如下目录结构

    3.我们打开unity 看看 Image 用的是什么shader 

    看来unity使用的默认材质用的shader叫 UI/Default

    4.我们在UI目录下找到这个shader 

     

     5.现在我们就可以打开编辑这个shader了,我们在这里给它加一张输入贴图 "Sprite Texture2" 对应到采样器 _MainTex2 ,并修改shader的名称为 "UI/DefaultEx" 避免和unity原有的冲突。

    1. // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
    2. Shader "UI/DefaultEx"
    3. {
    4. Properties
    5. {
    6. [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    7. _MainTex2 ("Sprite Texture2", 2D) = "white" {}
    8. _Color ("Tint", Color) = (1,1,1,1)
    9. _StencilComp ("Stencil Comparison", Float) = 8
    10. _Stencil ("Stencil ID", Float) = 0
    11. _StencilOp ("Stencil Operation", Float) = 0
    12. _StencilWriteMask ("Stencil Write Mask", Float) = 255
    13. _StencilReadMask ("Stencil Read Mask", Float) = 255
    14. _ColorMask ("Color Mask", Float) = 15
    15. [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
    16. }
    17. SubShader
    18. {
    19. Tags
    20. {
    21. "Queue"="Transparent"
    22. "IgnoreProjector"="True"
    23. "RenderType"="Transparent"
    24. "PreviewType"="Plane"
    25. "CanUseSpriteAtlas"="True"
    26. }
    27. Stencil
    28. {
    29. Ref [_Stencil]
    30. Comp [_StencilComp]
    31. Pass [_StencilOp]
    32. ReadMask [_StencilReadMask]
    33. WriteMask [_StencilWriteMask]
    34. }
    35. Cull Off
    36. Lighting Off
    37. ZWrite Off
    38. ZTest [unity_GUIZTestMode]
    39. Blend SrcAlpha OneMinusSrcAlpha
    40. ColorMask [_ColorMask]
    41. Pass
    42. {
    43. Name "Default"
    44. CGPROGRAM
    45. #pragma vertex vert
    46. #pragma fragment frag
    47. #pragma target 2.0
    48. #include "UnityCG.cginc"
    49. #include "UnityUI.cginc"
    50. #pragma multi_compile_local _ UNITY_UI_CLIP_RECT
    51. #pragma multi_compile_local _ UNITY_UI_ALPHACLIP
    52. struct appdata_t
    53. {
    54. float4 vertex : POSITION;
    55. float4 color : COLOR;
    56. float2 texcoord : TEXCOORD0;
    57. UNITY_VERTEX_INPUT_INSTANCE_ID
    58. };
    59. struct v2f
    60. {
    61. float4 vertex : SV_POSITION;
    62. fixed4 color : COLOR;
    63. float2 texcoord : TEXCOORD0;
    64. float2 texcoord2 : TEXCOORD3;
    65. float4 worldPosition : TEXCOORD1;
    66. half4 mask : TEXCOORD2;
    67. UNITY_VERTEX_OUTPUT_STEREO
    68. };
    69. sampler2D _MainTex2;
    70. float4 _MainTex2_ST;
    71. sampler2D _MainTex;
    72. fixed4 _Color;
    73. fixed4 _TextureSampleAdd;
    74. float4 _ClipRect;
    75. float4 _MainTex_ST;
    76. float _UIMaskSoftnessX;
    77. float _UIMaskSoftnessY;
    78. v2f vert(appdata_t v)
    79. {
    80. v2f OUT;
    81. UNITY_SETUP_INSTANCE_ID(v);
    82. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
    83. float4 vPosition = UnityObjectToClipPos(v.vertex);
    84. OUT.worldPosition = v.vertex;
    85. OUT.vertex = vPosition;
    86. float2 pixelSize = vPosition.w;
    87. pixelSize /= float2(1, 1) * abs(mul((float2x2)UNITY_MATRIX_P, _ScreenParams.xy));
    88. float4 clampedRect = clamp(_ClipRect, -2e10, 2e10);
    89. float2 maskUV = (v.vertex.xy - clampedRect.xy) / (clampedRect.zw - clampedRect.xy);
    90. OUT.texcoord = TRANSFORM_TEX(v.texcoord.xy, _MainTex);
    91. OUT.texcoord2 = TRANSFORM_TEX(v.texcoord.xy, _MainTex2);
    92. OUT.mask = half4(v.vertex.xy * 2 - clampedRect.xy - clampedRect.zw, 0.25 / (0.25 * half2(_UIMaskSoftnessX, _UIMaskSoftnessY) + abs(pixelSize.xy)));
    93. OUT.color = v.color * _Color;
    94. return OUT;
    95. }
    96. fixed4 frag(v2f IN) : SV_Target
    97. {
    98. half4 _mainTexColor = tex2D(_MainTex, IN.texcoord);
    99. half4 _mainTex2Color = tex2D(_MainTex2, IN.texcoord2);
    100. half4 color = IN.color * (_mainTexColor* _mainTexColor.a + _mainTex2Color*(1.0- _mainTexColor.a) + _TextureSampleAdd);
    101. #ifdef UNITY_UI_CLIP_RECT
    102. half2 m = saturate((_ClipRect.zw - _ClipRect.xy - abs(IN.mask.xy)) * IN.mask.zw);
    103. color.a *= m.x * m.y;
    104. #endif
    105. #ifdef UNITY_UI_ALPHACLIP
    106. clip (color.a - 0.001);
    107. #endif
    108. return color;
    109. }
    110. ENDCG
    111. }
    112. }
    113. }

    6.写好shader我们放入unity资源中,并创建一个材质 UIDefaultEx 并设置材质使用我们自己的UI/DefaultEx shader,可以看到材质相对于Unity默认的多出了一个贴图属性

     7.我们把材质给 Image ,并分别设置 Sprite属性,和材质中新增加的贴图为不同的 图片。可以看到我们的一个 Image 组件这个时候可以叠加显示两张图片了。

     总结,我们可以通过修改Unity 提供的Buildin shader 在不破坏Unity 自身UI表现规则的情况下,来增加各种效果,但是切记,第一当你使用图集的时候需要做额外处理,应为图集会改变Image的顶点uv坐标,需要做额外的处理来规避这个问题,第二我们修改的时候尽量不要修改Unity默认的shader行为,比如模板参数等等,否则容易引起各种问题。好了希望对你有帮助,谢谢。

  • 相关阅读:
    [c++学习]-类的成员函数可以直接调用其他成员
    QT数据库,实现数据库增删改查
    Centos - 虚拟机初始化网络配置
    【工程师整活】Ai-WB1-A1S实现离线语音+APP+天猫精灵控制风扇
    JAVA成都某4S店销售管理系统计算机毕业设计Mybatis+系统+数据库+调试部署
    身价翻 300 倍!4GB 的初代 iPhone 拍出 136 万天价!
    [附源码]计算机毕业设计springboot财务管理系统
    centeros7系统安装指定版本的mongodb数据库
    容联七陌携手岚时科技,解决医美机构回访3大痛点
    DP1332E多协议高度集成非接触式读写芯片
  • 原文地址:https://blog.csdn.net/u012149999/article/details/126153085