Created
February 15, 2023 20:16
-
-
Save khadzhynov/2cecbec59f4933864c4bc9863c327bf6 to your computer and use it in GitHub Desktop.
A simple shader to apply distortion (normal map) to UI Image in unity. Featured with map UV scrolling and blend mask.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Shader "GG/UiDistortion" | |
{ | |
Properties | |
{ | |
[NoScaleOffset] [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} | |
[NoScaleOffset] _DistortionMask ("Distortion mask", 2D) = "white" {} | |
[Normal] _Distortion ("Distortion", 2D) = "white" {} | |
_DistortionAmount ("Distortion Amount", Range(-1, 1)) = 0.05 | |
_DistortionScrollH ("Distortion Horizontal scroll", Range(-0.5, 0.5)) = 0.5 | |
_DistortionScrollV ("Distortion Vertical scroll", Range(-0.5, 0.5)) = 0.5 | |
_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] | |
Pass | |
{ | |
Name "Default" | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
#pragma target 2.0 | |
#include "UnityCG.cginc" | |
#include "UnityUI.cginc" | |
#pragma multi_compile_local _ UNITY_UI_CLIP_RECT | |
#pragma multi_compile_local _ UNITY_UI_ALPHACLIP | |
struct appdata_t | |
{ | |
float4 vertex : POSITION; | |
float4 color : COLOR; | |
float2 texcoord : TEXCOORD0; | |
UNITY_VERTEX_INPUT_INSTANCE_ID | |
}; | |
struct v2f | |
{ | |
float4 vertex : SV_POSITION; | |
fixed4 color : COLOR; | |
float2 texcoord : TEXCOORD0; | |
float4 worldPosition : TEXCOORD1; | |
UNITY_VERTEX_OUTPUT_STEREO | |
}; | |
sampler2D _MainTex; | |
sampler2D _Distortion; | |
float4 _Distortion_ST; | |
fixed _DistortionScrollH; | |
fixed _DistortionScrollV; | |
sampler2D _DistortionMask; | |
float _DistortionAmount; | |
fixed4 _Color; | |
fixed4 _TextureSampleAdd; | |
float4 _ClipRect; | |
float4 _MainTex_ST; | |
v2f vert(appdata_t v) | |
{ | |
v2f OUT; | |
UNITY_SETUP_INSTANCE_ID(v); | |
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT); | |
OUT.worldPosition = v.vertex; | |
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition); | |
OUT.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); | |
OUT.color = v.color * _Color; | |
return OUT; | |
} | |
fixed4 frag(v2f IN) : SV_Target | |
{ | |
fixed mask = tex2D(_DistortionMask, IN.texcoord).r; | |
fixed2 offset = _Distortion_ST.zw; | |
offset += fixed2(_Time.w * _DistortionScrollH, _Time.w * _DistortionScrollV); | |
fixed2 distortion = tex2D(_Distortion, IN.texcoord * _Distortion_ST.xy + offset) * mask * _DistortionAmount; | |
fixed2 shiftCompensation = fixed2(1, 0.5) * -_DistortionAmount; | |
shiftCompensation *= mask; | |
distortion += shiftCompensation; | |
half4 color = (tex2D(_MainTex, IN.texcoord + distortion) + _TextureSampleAdd) * IN.color; | |
#ifdef UNITY_UI_CLIP_RECT | |
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect); | |
#endif | |
#ifdef UNITY_UI_ALPHACLIP | |
clip (color.a - 0.001); | |
#endif | |
return color; | |
} | |
ENDCG | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See demo on YouTube