Created
July 23, 2019 23:54
-
-
Save mob-sakai/9514d1e732f597ca77422b15882a1b8d to your computer and use it in GitHub Desktop.
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 "Unlit/VectorGradient (SoftMaskable)" | |
{ | |
Properties | |
{ | |
_MainTex ("Texture", 2D) = "white" {} | |
_Color ("Tint", Color) = (1,1,1,1) | |
[HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1) | |
// vvvv ADD FOR SOFTMASKABLE vvvv | |
_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 | |
// ^^^^ ADD FOR SOFTMASKABLE ^^^^ | |
} | |
SubShader | |
{ | |
Tags | |
{ | |
"RenderType" = "Transparent" | |
"Queue" = "Transparent" | |
"IgnoreProjector" = "True" | |
"PreviewType" = "Plane" | |
} | |
// vvvv ADD FOR SOFTMASKABLE vvvv | |
Stencil | |
{ | |
Ref [_Stencil] | |
Comp [_StencilComp] | |
Pass [_StencilOp] | |
ReadMask [_StencilReadMask] | |
WriteMask [_StencilWriteMask] | |
} | |
// ^^^^ ADD FOR SOFTMASKABLE ^^^^ | |
LOD 100 | |
Cull Off | |
Lighting Off | |
ZWrite Off | |
// vvvv CHANGE FOR SOFTMASKABLE vvvv | |
ZTest [unity_GUIZTestMode] | |
Blend SrcAlpha OneMinusSrcAlpha | |
ColorMask [_ColorMask] | |
// ^^^^ CHANGE FOR SOFTMASKABLE ^^^^ | |
Pass | |
{ | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
#pragma multi_compile_instancing | |
#include "UnityCG.cginc" | |
// vvvv ADD FOR SOFTMASKABLE vvvv | |
//#include "Assets/Coffee/UIExtensions/SoftMaskForUGUI/SoftMask.cginc" // If you installed using .unitypackage file | |
#include "Packages/com.coffee.softmask-for-ugui/SoftMask.cginc" // If you installed using package manager | |
#pragma shader_feature __ SOFTMASK_EDITOR | |
// ^^^^ ADD FOR SOFTMASKABLE ^^^^ | |
#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 | |
{ | |
fixed4 color : COLOR; | |
float2 uv : TEXCOORD0; // uv.z is used for setting index | |
float2 settingIndex : TEXCOORD2; | |
float4 vertex : SV_POSITION; | |
UNITY_VERTEX_OUTPUT_STEREO | |
// vvvv ADD FOR SOFTMASKABLE vvvv | |
float4 worldPosition : TEXCOORD1; | |
// ^^^^ ADD FOR SOFTMASKABLE ^^^^ | |
}; | |
sampler2D _MainTex; | |
float4 _MainTex_ST; | |
float4 _MainTex_TexelSize; | |
fixed4 _Color; | |
v2f vert (appdata IN) | |
{ | |
v2f OUT; | |
UNITY_SETUP_INSTANCE_ID (IN); | |
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT); | |
// vvvv ADD FOR SOFTMASKABLE vvvv | |
OUT.worldPosition = IN.vertex; | |
// ^^^^ ADD FOR SOFTMASKABLE ^^^^ | |
OUT.vertex = UnityObjectToClipPos(IN.vertex); | |
#ifdef UNITY_COLORSPACE_GAMMA | |
OUT.color = IN.color; | |
#else | |
OUT.color = fixed4(GammaToLinearSpace(IN.color.rgb), IN.color.a); | |
#endif | |
OUT.color *= _Color * _RendererColor; | |
OUT.uv = TRANSFORM_TEX(IN.uv, _MainTex); | |
OUT.settingIndex = IN.settingIndex; | |
return OUT; | |
} | |
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 | |
{ | |
// Gradient settings are stored in 3 consecutive texels: | |
// - texel 0: (float4, 1 byte per float) | |
// x = gradient type (0 = tex/linear, 1 = radial) | |
// y = address mode (0 = wrap, 1 = clamp, 2 = mirror) | |
// z = radialFocus.x | |
// w = radialFocus.y | |
// - texel 1: (float2, 2 bytes per float) atlas entry position | |
// xy = pos.x | |
// zw = pos.y | |
// - texel 2: (float2, 2 bytes per float) atlas entry size | |
// xy = size.x | |
// zw = size.y | |
int settingBase = ((int)(i.settingIndex.x + 0.5f)) * 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) | |
{ | |
// Radial texture case | |
float2 focus = (gradSettings.zw - float2(0.5f, 0.5f)) * 2.0f; // bring focus in the (-1,1) range | |
uv = float2(radialAddress(i.uv, focus), 0.0); | |
} | |
int addressing = gradSettings.y * 255; | |
uv.x = (addressing == 0) ? fmod(uv.x,1.0f) : uv.x; // Wrap | |
uv.x = (addressing == 1) ? max(min(uv.x,1.0f), 0.0f) : uv.x; // Clamp | |
float w = fmod(uv.x,2.0f); | |
uv.x = (addressing == 2) ? (w > 1.0f ? 1.0f-fmod(w,1.0f) : w) : uv.x; // Mirror | |
// Adjust UV to atlas position | |
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; | |
// vvvv ADD FOR SOFTMASKABLE vvvv | |
finalColor.a *= SoftMask(i.vertex, i.worldPosition); | |
// ^^^^ ADD FOR SOFTMASKABLE ^^^^ | |
return finalColor; | |
} | |
ENDCG | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment