In FairyGUI, the simplest way to change the Shader for a component is to find the Shader field in the component and assign it. It should be noted that for custom shader effects, the target image needs to be published separately, that is, one target image occupies one atlas. (There should be a better solution, but this is the way it is for now)
The Shader source code in this article comes from the modification of the official "FairyGUI/Image", and the modified part of the source code comes from the Internet.
Example: Load Shader
Load custom Shader in the code:
local logoImg = this.GetChild("n2").asImage
logoImg.shader = "FairyGUI/Image-Light"
1: Sweep Shader
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "FairyGUI/Image-Light"
{
Properties
{
_MainTex ("Base (RGB), Alpha (A)", 2D) = "black" {}
_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
_BlendSrcFactor ("Blend SrcFactor", Float) = 5
_BlendDstFactor ("Blend DstFactor", Float) = 10
[Header(Light)]
//扫光时间
_LightTime("Light Time", Float) = 1
//扫光厚度
_LightThick("Light Thick", Float) = 0.2
//循环时间
_LightInterval("Light Interval", Float) = 2
//扫光角度
_LightAngle("Light Angle", int) = 60
//亮度
_Brightness("Light Brightness",float) = 1
//扫光颜色
_LightColor ("Light Color", Color) = (1,1,1,1)
}
SubShader
{
LOD 100
Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
Fog
{
Mode Off
}
Blend [_BlendSrcFactor] [_BlendDstFactor], One One
ColorMask [_ColorMask]
Pass
{
CGPROGRAM
#pragma multi_compile NOT_COMBINED COMBINED
#pragma multi_compile NOT_GRAYED GRAYED COLOR_FILTER
#pragma multi_compile NOT_CLIPPED CLIPPED SOFT_CLIPPED ALPHA_MASK
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
fixed4 color : COLOR;
float4 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float4 texcoord : TEXCOORD0;
#ifdef CLIPPED
float2 clipPos : TEXCOORD1;
#endif
#ifdef SOFT_CLIPPED
float2 clipPos : TEXCOORD1;
#endif
};
sampler2D _MainTex;
half _LightTime;
float _LightThick;
float _LightInterval;
int _LightAngle;
float _Brightness;
float4 _LightColor;
#ifdef COMBINED
sampler2D _AlphaTex;
#endif
CBUFFER_START(UnityPerMaterial)
#ifdef CLIPPED
float4 _ClipBox = float4(-2, -2, 0, 0);
#endif
#ifdef SOFT_CLIPPED
float4 _ClipBox = float4(-2, -2, 0, 0);
float4 _ClipSoftness = float4(0, 0, 0, 0);
#endif
CBUFFER_END
#ifdef COLOR_FILTER
float4x4 _ColorMatrix;
float4 _ColorOffset;
float _ColorOption = 0;
#endif
v2f vert(appdata_t v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.texcoord = v.texcoord;
#if !defined(UNITY_COLORSPACE_GAMMA) && (UNITY_VERSION >= 550)
o.color.rgb = GammaToLinearSpace(v.color.rgb);
o.color.a = v.color.a;
#else
o.color = v.color;
#endif
#ifdef CLIPPED
o.clipPos = mul(unity_ObjectToWorld, v.vertex).xy * _ClipBox.zw + _ClipBox.xy;
#endif
#ifdef SOFT_CLIPPED
o.clipPos = mul(unity_ObjectToWorld, v.vertex).xy * _ClipBox.zw + _ClipBox.xy;
#endif
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.texcoord.xy / i.texcoord.w) * i.color;
//扫光代码来源 https://blog.csdn.net/u014621871/article/details/122685044
//光照的流逝时间
fixed currentTimePassed = fmod(_Time.y, _LightTime + _LightInterval);
fixed x = currentTimePassed / _LightTime;
//倾斜角 1°≈0.0174444
float angleInRad = 0.0174444 * _LightAngle;
fixed tanX = tan(angleInRad);
x += (x - 1) / tanX;
fixed x1 = i.texcoord.y / tanX + x;
fixed x2 = x1 + _LightThick;
if (i.texcoord.x > x1 && i.texcoord.x < x2)
{
//差值计算,根据与中心的距离的比例来计算亮度
float xMid = 0.5 * (x1 + x2);
fixed dis = 1 - abs(i.texcoord.x - xMid) * 2 / _LightThick;
half colorA = col.a;
//扫光的颜色*强度+默认颜色输出
col += col + _LightColor * (_Brightness * dis);
col.a = colorA;
}
#ifdef COMBINED
col.a *= tex2D(_AlphaTex, i.texcoord.xy / i.texcoord.w).g;
#endif
#ifdef GRAYED
fixed grey = dot(col.rgb, fixed3(0.299, 0.587, 0.114));
col.rgb = fixed3(grey, grey, grey);
#endif
#ifdef SOFT_CLIPPED
float2 factor = float2(0,0);
if(i.clipPos.x<0)
factor.x = (1.0-abs(i.clipPos.x)) * _ClipSoftness.x;
else
factor.x = (1.0-i.clipPos.x) * _ClipSoftness.z;
if(i.clipPos.y<0)
factor.y = (1.0-abs(i.clipPos.y)) * _ClipSoftness.w;
else
factor.y = (1.0-i.clipPos.y) * _ClipSoftness.y;
col.a *= clamp(min(factor.x, factor.y), 0.0, 1.0);
#endif
#ifdef CLIPPED
float2 factor = abs(i.clipPos);
col.a *= step(max(factor.x, factor.y), 1);
#endif
#ifdef COLOR_FILTER
if (_ColorOption == 0)
{
fixed4 col2 = col;
col2.r = dot(col, _ColorMatrix[0]) + _ColorOffset.x;
col2.g = dot(col, _ColorMatrix[1]) + _ColorOffset.y;
col2.b = dot(col, _ColorMatrix[2]) + _ColorOffset.z;
col2.a = dot(col, _ColorMatrix[3]) + _ColorOffset.w;
col = col2;
}
else //premultiply alpha
col.rgb *= col.a;
#endif
#ifdef ALPHA_MASK
clip(col.a - 0.001);
#endif
return col;
}
ENDCG
}
}
}
2: Loop background image
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "FairyGUI/Image-Loop"
{
Properties
{
_MainTex ("Base (RGB), Alpha (A)", 2D) = "black" {}
_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
_BlendSrcFactor ("Blend SrcFactor", Float) = 5
_BlendDstFactor ("Blend DstFactor", Float) = 10
_Speed("Speed", Range(0,3)) = 0.1
_Rotation("Rotation", Range(0,360)) = 225 //为了方便直观,角度的值使用了0~360范围
}
SubShader
{
LOD 100
Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
Fog
{
Mode Off
}
Blend [_BlendSrcFactor] [_BlendDstFactor], One One
ColorMask [_ColorMask]
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma multi_compile NOT_COMBINED COMBINED
#pragma multi_compile NOT_GRAYED GRAYED COLOR_FILTER
#pragma multi_compile NOT_CLIPPED CLIPPED SOFT_CLIPPED ALPHA_MASK
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature _FlipY
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
fixed4 color : COLOR;
float4 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float4 texcoord : TEXCOORD0;
half2 uvTA: TEXCOORD2;
#ifdef CLIPPED
float2 clipPos : TEXCOORD1;
#endif
#ifdef SOFT_CLIPPED
float2 clipPos : TEXCOORD1;
#endif
};
sampler2D _MainTex;
float _Speed;
float _Rotation;
uniform half4 _MainTex_ST;
#ifdef COMBINED
sampler2D _AlphaTex;
#endif
CBUFFER_START(UnityPerMaterial)
#ifdef CLIPPED
float4 _ClipBox = float4(-2, -2, 0, 0);
#endif
#ifdef SOFT_CLIPPED
float4 _ClipBox = float4(-2, -2, 0, 0);
float4 _ClipSoftness = float4(0, 0, 0, 0);
#endif
CBUFFER_END
#ifdef COLOR_FILTER
float4x4 _ColorMatrix;
float4 _ColorOffset;
float _ColorOption = 0;
#endif
v2f vert(appdata_t v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
#if !defined(UNITY_COLORSPACE_GAMMA) && (UNITY_VERSION >= 550)
o.color.rgb = GammaToLinearSpace(v.color.rgb);
o.color.a = v.color.a;
#else
o.color = v.color;
#endif
#ifdef CLIPPED
o.clipPos = mul(unity_ObjectToWorld, v.vertex).xy * _ClipBox.zw + _ClipBox.xy;
#endif
#ifdef SOFT_CLIPPED
o.clipPos = mul(unity_ObjectToWorld, v.vertex).xy * _ClipBox.zw + _ClipBox.xy;
#endif
float Rot = _Rotation * (3.1415926f / 180.0f);
float s = sin(Rot);
float c = cos(Rot);
o.texcoord = v.texcoord;
o.uvTA = (v.texcoord) * _MainTex_ST.xy + fixed2(s, c) * (_Time.y * _Speed) - _MainTex_ST.zw;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uvTA).rgba * i.color;
#ifdef COMBINED
col.a *= tex2D(_AlphaTex, i.texcoord.xy / i.texcoord.w).g;
#endif
#ifdef GRAYED
fixed grey = dot(col.rgb, fixed3(0.299, 0.587, 0.114));
col.rgb = fixed3(grey, grey, grey);
#endif
#ifdef SOFT_CLIPPED
float2 factor = float2(0,0);
if(i.clipPos.x<0)
factor.x = (1.0-abs(i.clipPos.x)) * _ClipSoftness.x;
else
factor.x = (1.0-i.clipPos.x) * _ClipSoftness.z;
if(i.clipPos.y<0)
factor.y = (1.0-abs(i.clipPos.y)) * _ClipSoftness.w;
else
factor.y = (1.0-i.clipPos.y) * _ClipSoftness.y;
col.a *= clamp(min(factor.x, factor.y), 0.0, 1.0);
#endif
#ifdef CLIPPED
float2 factor = abs(i.clipPos);
col.a *= step(max(factor.x, factor.y), 1);
#endif
#ifdef COLOR_FILTER
if (_ColorOption == 0)
{
fixed4 col2 = col;
col2.r = dot(col, _ColorMatrix[0]) + _ColorOffset.x;
col2.g = dot(col, _ColorMatrix[1]) + _ColorOffset.y;
col2.b = dot(col, _ColorMatrix[2]) + _ColorOffset.z;
col2.a = dot(col, _ColorMatrix[3]) + _ColorOffset.w;
col = col2;
}
else //premultiply alpha
col.rgb *= col.a;
#endif
#ifdef ALPHA_MASK
clip(col.a - 0.001);
#endif
return col;
}
ENDCG
}
}
}
reference:
2. Production of infinite loop background
If you have any questions, please leave a message! grateful!