Skip to content

Instantly share code, notes, and snippets.

@javier-games
Last active February 18, 2023 05:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save javier-games/768de5509af5485ffb8a33535d30a191 to your computer and use it in GitHub Desktop.
Save javier-games/768de5509af5485ffb8a33535d30a191 to your computer and use it in GitHub Desktop.
Vector graphics masked shader with jelly movement.

Vertor Jelly Shader

This shader is based in the UIDefault shader from the Vector Graphics package from Unity. Has been improved to suport the Mask UI component. The Jelly movement happens in line 104 to 106.

Unity Version

Shader "Vector Graphics/Jelly" {
// VectorJelly.shader
//
// This shader is based in the UIDefault shader from the vector graphics
// package in Unity.
// The jelly movement happens on lines 104 to 106 and to be able to be
// masked has the follow Stencil Properties.
//
// By Javier García | @jvrgms | 2019
Properties {
// Used to mask the vector graph.
_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
// Regular Vector Graph Parameters.
_MainTex ("Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
// Jelly Parameters
_Speed ("Velocidad",Range(-100,100)) = 5
_Frequency ("Frecuencia",Range(0,0.01)) = 0
_Amplitude ("Amplitud",Range(-100,100)) = 1
[HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1)
}
SubShader {
Tags {
"RenderType" = "Transparent"
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"PreviewType" = "Plane"
}
Stencil{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
LOD 100
Cull Off
Lighting Off
ZWrite Off
Blend One OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_instancing
#include "UnityCG.cginc"
#ifdef UNITY_INSTANCING_ENABLED
UNITY_INSTANCING_BUFFER_START(PerDrawSprite)
UNITY_DEFINE_INSTANCED_PROP(fixed4, unity_SpriteRendererColorArray)
UNITY_INSTANCING_BUFFER_END(PerDrawSprite)
#define _RendererColor UNITY_ACCESS_INSTANCED_PROP(PerDrawSprite, unity_SpriteRendererColorArray)
#endif
#ifndef UNITY_INSTANCING_ENABLED
fixed4 _RendererColor;
#endif
struct appdata {
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 uv : TEXCOORD0;
float2 settingIndex : TEXCOORD2;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
fixed4 color : COLOR;
float2 settingIndex : TEXCOORD2;
UNITY_VERTEX_OUTPUT_STEREO
};
sampler2D _MainTex;
fixed4 _Color;
float4 _MainTex_ST;
float4 _MainTex_TexelSize;
float _Speed;
float _Frequency;
float _Amplitude;
v2f vert (appdata v) {
float time = _Time * _Speed;
float wX = cos(time + v.vertex.x * _Frequency) * _Amplitude;
v.vertex.xyz = float3(v.vertex.x, v.vertex.y + wX, v.vertex.z);
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
#ifdef UNITY_COLORSPACE_GAMMA
o.color = v.color;
#else
o.color = fixed4(GammaToLinearSpace(v.color.rgb), v.color.a);
#endif
o.color *= _RendererColor;
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.settingIndex = v.settingIndex;
return o;
}
float2 unpackFloat2(fixed4 c) {
return float2(c.r*255 + c.g, c.b*255 + c.a);
}
float2 rayUnitCircleFirstHit(float2 rayStart, float2 rayDir) {
float tca = dot(-rayStart, rayDir);
float d2 = dot(rayStart, rayStart) - tca * tca;
float thc = sqrt(1.0f - d2);
float t0 = tca - thc;
float t1 = tca + thc;
float t = min(t0, t1);
if (t < 0.0f)
t = max(t0, t1);
return rayStart + rayDir * t;
}
float radialAddress(float2 uv, float2 focus) {
uv = (uv - float2(0.5f, 0.5f)) * 2.0f;
float2 pointOnPerimeter = rayUnitCircleFirstHit(focus, normalize(uv - focus));
float2 diff = pointOnPerimeter - focus;
if (abs(diff.x) > 0.0001f)
return (uv.x - focus.x) / diff.x;
if (abs(diff.y) > 0.0001f)
return (uv.y - focus.y) / diff.y;
return 0.0f;
}
fixed4 frag (v2f i) : SV_Target {
int settingBase = 3;
float2 texelSize = _MainTex_TexelSize.xy;
float2 settingUV = float2(settingBase + 0.5f, 0.5f) * texelSize;
float2 uv = i.uv;
fixed4 gradSettings = tex2D(_MainTex, settingUV);
if (gradSettings.x > 0.0f) {
float2 focus = (gradSettings.zw - float2(0.5f, 0.5f)) * 2.0f;
uv = float2(radialAddress(i.uv, focus), 0.0);
}
int addressing = gradSettings.y * 255;
uv.x = (addressing == 0) ? fmod(uv.x,1.0f) : uv.x;
uv.x = (addressing == 1) ? max(min(uv.x,1.0f), 0.0f) : uv.x;
float w = fmod(uv.x,2.0f);
uv.x = (addressing == 2) ? (w > 1.0f ? 1.0f-fmod(w,1.0f) : w) : uv.x;
float2 nextUV = float2(texelSize.x, 0);
float2 pos = (unpackFloat2(tex2D(_MainTex, settingUV+nextUV) * 255) + float2(0.5f, 0.5f)) * texelSize;
float2 size = unpackFloat2(tex2D(_MainTex, settingUV+nextUV*2) * 255) * texelSize;
uv = uv * size + pos;
fixed4 texColor = tex2D(_MainTex, uv);
#ifndef UNITY_COLORSPACE_GAMMA
texColor = fixed4(GammaToLinearSpace(texColor.rgb), texColor.a);
#endif
fixed4 finalColor = texColor * i.color;
finalColor.rgb *= finalColor.a;
return finalColor;
}
ENDCG
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment