unity UI shader 之Overlay Mode

在这里插入图片描述

// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)

Shader "UI/PS-Overlay_Mode" {
Properties {
	[KeywordEnum(None,Darken,Multiply,ColorBurn,LinearBurn,Lighten,Screen,ColorDodge,LinearDodge)] _Overlay ("Overlay mode 1", Float) = 0
	[KeywordEnum(None, Overlay,SoftLight,HardLight,VividLight,LinearLight,PinLight,Difference,Exclusion)] _Overlay2 ("Overlay mode 2", Float) = 0
	_TintColor1("Color1",Color) = (1,1,1,1)
	_TintColor2("Color2",Color) = (1,1,1,1)
    _MainTex ("Particle Texture", 2D) = "white" {}
}

Category {
    Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" }
    Blend One OneMinusSrcColor
//    Blend OneMinusSrcColor One
//	Blend SrcAlpha OneMinusSrcColor
//	Blend SrcAlpha One
//    Blend One One
//    Blend One Zero
//    Blend Zero One
//    ColorMask RGB
//    Cull Off 
    Lighting Off 
    ZWrite Off

    SubShader {
        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 2.0
            #pragma multi_compile _OVERLAY_NONE _OVERLAY_DARKEN _OVERLAY_MULTIPLY _OVERLAY_COLORBURN _OVERLAY_LINEARBURN _OVERLAY_LIGHTEN _OVERLAY_SCREEN _OVERLAY_COLORDODGE _OVERLAY_LINEARDODGE 
			#pragma multi_compile _OVERLAY2_NONE _OVERLAY2_OVERLAY _OVERLAY2_SOFTLIGHT _OVERLAY2_HARDLIGHT _OVERLAY2_VIVIDLIGHT _OVERLAY2_LINEARLIGHT _OVERLAY2_PINLIGHT _OVERLAY2_DIFFERENCE _OVERLAY2_EXCLUSION
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _TintColor1;
			fixed4 _TintColor2;
            struct appdata_t {
                float4 vertex : POSITION;
                fixed4 color : COLOR;
                float2 texcoord : TEXCOORD0;
            };

            struct v2f {
                float4 vertex : SV_POSITION;
                fixed4 color : COLOR;
                float2 texcoord : TEXCOORD0;
            };

            v2f vert (appdata_t v)
            {
                v2f o = (v2f)0;
                o.vertex =mul(UNITY_MATRIX_MVP, v.vertex);// UnityObjectToClipPos(v.vertex);
                o.color = v.color;
                o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                half4 tex = tex2D(_MainTex, i.texcoord);
                half4 col = i.color * tex * _TintColor2;
//                col.rgb *= col.a;

                //Darken 变暗
				#if _OVERLAY_DARKEN
					col.rgb = min(col.rgb,col.rgb);
				#endif
					
				//Multiply 正片叠底
				#if _OVERLAY_MULTIPLY
					col.rgb = col.rgb * col.rgb; 
					col.rgb *=col.rgb*2;
	                
				#endif
				
				//ColorBurn 颜色加深
				#if _OVERLAY_COLORBURN
					col.rgb = 1.0 - (1.0 - col.rgb) / col.rgb; 
				#endif
				
				//LinearBurn 线性加深
				#if _OVERLAY_LINEARBURN
					col.rgb = col.rgb + col.rgb - 1.0; 
				#endif
				
				//Lighten 变亮
				#if _OVERLAY_LIGHTEN
					col.rgb = max(col.rgb,col.rgb);
					//col = col*_TintColor1;
				#endif
				
				//Screen 滤色
				#if _OVERLAY_SCREEN
					col.rgb = 1.0 - (1.0 - col.rgb) * (1.0 - col.rgb);
				#endif
				
				//ColorDodge 颜色减淡
				#if _OVERLAY_COLORDODGE
					col.rgb = col.rgb / (1.0 - col.rgb);
				#endif
				
				//LinearDodge(Add) 线性减淡(添加)
				#if _OVERLAY_LINEARDODGE
					col.rgb = col.rgb + col.rgb;
				#endif
				
				//Overlay 叠加
				#if _OVERLAY2_OVERLAY
					col.rgb = step(0.5, col.rgb);				
					col.rgb = lerp((col.rgb*col.rgb*2), (1.0-(2.0*(1.0-col.rgb)*(1.0-col.rgb))), col.rgb);
				#endif
				
				//Soft Light 柔光
				#if _OVERLAY2_SOFTLIGHT
					if(col.r > .5){col.r = col.r * (1.0-(1.0-col.r)*(1.0-2*col.r));}
					else{col.r = 1.0-(1.0-col.r)*(1.0-(col.r*2.0*col.r));}
					
					if(col.g > .5){col.g = col.g * (1.0-(1.0-col.g)*(1.0-2*col.g));}
					else{col.g = 1.0-(1.0-col.g)*(1.0-(col.g*2.0*col.g));}
					
					if(col.b > .5){col.b = col.b * (1.0-(1.0-col.b)*(1.0-2*col.b));}
					else{col.b = 1.0-(1.0-col.b)*(1.0-(col.b*2.0*col.b));}
				#endif
							
				//Hard Light 强光
				#if _OVERLAY2_HARDLIGHT
					if(col.r > .5){col.r = 1.0-(1.0-col.r)*(1-2*col.r);}
					else{col.r = col.r*2*col.r;}
					
					if(col.g > .5){col.g = 1.0-(1.0-col.g)*(1-2*col.g);}
					else{col.g = col.g*2*col.g;}
					
					if(col.b > .5){col.b = 1.0-(1.0-col.b)*(1-2*col.b);}
					else{col.b = col.b*2*col.b;}
				#endif
				
				//Vivid Light 亮光
				#if _OVERLAY2_VIVIDLIGHT
					if(col.r > .5){col.r = 1.0-(1.0-col.r)/(2*(col.r-.5));}
					else{col.r = col.r/(1-2*col.r);}
					
					if(col.g > .5){col.g = 1.0-(1.0-col.g)/(2*(col.g-.5));}
					else{col.g = col.g/(1-2*col.g);}
					
					if(col.b > .5){col.b = 1.0-(1.0-col.b)/(2*(col.b-.5));}
					else{col.b = col.b/(1-2*col.b);}
				#endif			
				
				//Linear Light 线性光
				#if _OVERLAY2_LINEARLIGHT
					if(col.r > .5){col.r = col.r + 2.0*(col.r - .5);}
					else{col.r = col.r + 2 * col.r - 1;}
					
					if(col.g > .5){col.g = col.g + 2.0*(col.g - .5);}
					else{col.g = col.g + 2 * col.g - 1;}
					
					if(col.b > .5){col.b = col.b + 2.0*(col.b - .5);}
					else{col.b = col.b + 2 * col.b - 1;}
				#endif
				
				//Pin Light 点光
				#if _OVERLAY2_PINLIGHT
					if(col.r > .5){col.r = max(col.r,2*(col.r-.5));}
					else{col.r = min(col.r,2*col.r);}
					
					if(col.g > .5){col.g = max(col.g,2*(col.g-.5));}
					else{col.g = min(col.g,2*col.g);}
					
					if(col.b > .5){col.b = max(col.b,2*(col.b-.5));}
					else{col.b = min(col.b,2*col.b);}
				#endif
				
				//Difference 差值	
				#if _OVERLAY2_DIFFERENCE
					col.rgb = abs(col.rgb - col.rgb);
				#endif
				
				//Exclusion 排除	
				#if _OVERLAY2_EXCLUSION
					col.rgb = .5 - 2*(col.rgb - 0.5) * (col.rgb - 0.5);
				#endif

                return col+_TintColor1;
            }
            ENDCG
        }
    }
}
}

### Unity UI 性能优化方法和技术 #### 减少不必要的UI组件更新 频繁的UI组件更新会带来显著的性能开销。为了减少这种影响,应当确保只在必要时才触发UI元素的重新绘制或布局计算[^1]。 ```csharp // 避免每帧调用LayoutRebuilder.ForceRebuildLayoutImmediate if (needsUpdate) { LayoutRebuilder.ForceRebuildLayoutImmediate(rectTransform); } ``` #### 使用Canvas Group管理可见性和交互状态 通过`CanvasGroup`来控制多个UI对象的同时显示隐藏以及响应输入的状态切换,而不是单独操作每一个控件,这样可以提高效率并简化逻辑处理流程[^2]。 #### 合理设置Render Mode 对于不需要参与场景渲染的UI界面(如HUD),可以选择Screen Space - Overlay模式;而对于需要与3D世界互动或者有遮挡关系的情况,则采用World Space 或 Screen Space - Camera 模式。这有助于降低GPU负担并改善整体表现效果[^3]。 #### 尽量复用预制体而非销毁重建 当涉及到动态创建大量相似类型的UI实例时,应该考虑预先加载一定数量的对象池(pool),并在实际需求发生时从中取出已存在的成员进行参数调整后投入使用,从而避免反复new/delete带来的额外成本[^4]。 #### 优化Shader和材质资源 如果自定义了特殊的视觉样式,务必遵循最佳实践对所使用的着色器程序加以精炼,去除冗余指令,并尝试利用硬件加速特性以达到更好的运行速度。此外,在不影响最终呈现质量的前提下适当压缩纹理尺寸也能有效减轻图形处理器的工作压力。 #### 缓存常用字符串标签比较结果 为了避免每次执行碰撞检测或其他条件判断过程中都重复查询相同的tag名称而导致GC分配内存碎片化的问题,建议提前声明静态变量保存这些常数值以便快速检索匹配。 ```csharp private static readonly string PlayerTag = "Player"; void OnTriggerEnter(Collider other) { bool isPlayer = other.gameObject.CompareTag(PlayerTag); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值