123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410 |
- Shader "MPUI/Basic Procedural Image"
- {
- Properties
- {
- [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" { }
- _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
-
-
- /* //SOFTMASK_HANDLE_START
- [PerRendererData] _SoftMask ("Mask", 2D) = "white" {}
- */ //SOFTMASK_HANDLE_END
-
- [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
-
- #include "UnityCG.cginc"
- #include "UnityUI.cginc"
- #include "2D_SDF.cginc"
- /* //SOFTMASK_HANDLE_START
- #include "Assets/SoftMask/Shaders/SoftMask.cginc" //SOFTMASK_INCLUDE_HANDLE
- */ //SOFTMASK_HANDLE_END
-
- #pragma multi_compile_local _ UNITY_UI_CLIP_RECT
- #pragma multi_compile_local _ UNITY_UI_ALPHACLIP
-
- #pragma multi_compile_local _ CIRCLE TRIANGLE RECTANGLE NSTAR_POLYGON
- #pragma multi_compile_local _ STROKE OUTLINED OUTLINED_STROKE
-
- /* //SOFTMASK_HANDLE_START
- #pragma multi_compile _ SOFTMASK_SIMPLE
- */ //SOFTMASK_HANDLE_END
-
-
- struct appdata_t
- {
- float4 vertex: POSITION;
- float4 color: COLOR;
- float2 uv0: TEXCOORD0;
- float2 uv1: TEXCOORD1;
- float2 uv2: TEXCOORD2;
- float2 uv3: TEXCOORD3;
- float3 normal: NORMAL;
- float4 tangent: TANGENT;
-
- UNITY_VERTEX_INPUT_INSTANCE_ID
- };
-
- struct v2f
- {
- float4 vertex: SV_POSITION;
- fixed4 color: COLOR;
- float2 uv0: TEXCOORD0;
- float4 sizeData: TEXCOORD1;
- float4 strokeOutlineCornerData: TEXCOORD2;
- fixed4 outlineColor: COLOR1;
- float4 shapeData: TEXCOORD3;
- float4 worldPosition: TEXCOORD4;
-
- /* //SOFTMASK_HANDLE_START
- SOFTMASK_COORDS(5)
- */ //SOFTMASK_HANDLE_END
-
- UNITY_VERTEX_OUTPUT_STEREO
- };
-
- sampler2D _MainTex;
- fixed4 _Color;
- fixed4 _TextureSampleAdd;
- float4 _ClipRect;
- float4 _MainTex_ST;
- #if RECTANGLE
- half rectangleScene(float4 _sizeData, float4 _shapeData, float _cornerStyle)
- {
- float2 _texcoord = _sizeData.xy;
- float2 _size = float2(_sizeData.z, _sizeData.w);
- float4 radius = _shapeData;
- half4 c = half4(_texcoord, _size - _texcoord);
- half rect = min(min(min(c.x, c.y), c.z), c.w);
- bool4 cornerRects;
- cornerRects.x = _texcoord.x < radius.x && _texcoord.y < radius.x;
- cornerRects.y = _texcoord.x > _size.x - radius.y && _texcoord.y < radius.y;
- cornerRects.z = _texcoord.x > _size.x - radius.z && _texcoord.y > _size.y - radius.z;
- cornerRects.w = _texcoord.x < radius.w && _texcoord.y > _size.y - radius.w;
- half cornerMask = any(cornerRects);
- half4 cornerCircles;
- cornerCircles.x = radius.x - length(_texcoord - radius.xx);//circle(_texcoord - radius.xx, radius.x);
- cornerCircles.y = radius.y - length(_texcoord - half2(_size.x - radius.y, radius.y));//circle(_texcoord - half2(_size.x - radius.y, radius.y), radius.y);
- cornerCircles.z = radius.z - length(_texcoord - (half2(_size.x, _size.y) - radius.zz));//circle(_texcoord - (half2(_size.x, _size.y) - radius.zz), radius.z);
- cornerCircles.w = radius.w - length(_texcoord - half2(radius.w, _size.y - radius.w)); //circle(_texcoord - half2(radius.w, _size.y - radius.w), radius.w);
- cornerCircles = min(max(cornerCircles, 0) * cornerRects, rect);
- //cornerCircles = max(cornerCircles, 0) * cornerRects;
- half corners = max(max(max(cornerCircles.x, cornerCircles.y), cornerCircles.z), cornerCircles.w);
- corners = max(corners, 0.0) * cornerMask;
- //return rect;
- return rect*(cornerMask-1) - corners;
- /*
- half rect = rectanlge(_texcoord - half2(_size.x / 2.0, _size.y / 2.0), _size.x, _size.y);
- half cornerCircle = circle(_texcoord - radius.xx, radius.x);
- rect = _texcoord.x < radius.x && _texcoord.y < radius.x ? cornerCircle: rect;
- cornerCircle = circle(_texcoord - half2(_size.x - radius.y, radius.y), radius.y);
- rect = _texcoord.x > _size.x - radius.y && _texcoord.y < radius.y ? cornerCircle: rect;
- cornerCircle = circle(_texcoord - (half2(_size.x, _size.y) - radius.zz), radius.z);
- rect = _texcoord.x > _size.x - radius.z && _texcoord.y > _size.y - radius.z ? cornerCircle: rect;
- cornerCircle = circle(_texcoord - half2(radius.w, _size.y - radius.w), radius.w);
- rect = _texcoord.x < radius.w && _texcoord.y > _size.y - radius.w ? cornerCircle: rect;
- */
-
- //max(max(max(cornerCircles.x, cornerCircles.y), cornerCircles.z), cornerCircles.w);
- }
- #endif
-
- #if CIRCLE
- float circleScene(float4 _sizeData, float4 _shapeData)
- {
- float2 _texcoord = _sizeData.xy;
- float2 _size = _sizeData.zw;
- float width = _size.x;
- float height = _size.y;
- float radius = lerp(_shapeData.x, min(width, height) / 2.0, _shapeData.y);
- float sdf = circle(_texcoord - float2(width / 2.0, height / 2.0), radius);
- return sdf;
- }
- #endif
-
- #if TRIANGLE
- half triangleScene(float4 _sizeData, float4 _shapeData)
- {
- float2 _texcoord = _sizeData.xy;
- float2 _size = _sizeData.zw;
- float width = _size.x;//_additionalData.z;
- float height = _size.y;//_additionalData.w;
-
- half sdf = sdTriangleIsosceles(_texcoord - half2(width / 2.0, height), half2(width / 2.0, -height));
- //return sdf;
-
- float3 _TriangleCornerRadius = max(_shapeData.xyz, float3(0.001, 0.001, 0.001));
- // Left Corner
- half halfWidth = width / 2.0;
- half m = height / halfWidth;
- half d = sqrt(1.0 + m * m);
- half c = 0.0;
- half k = -_TriangleCornerRadius.x * d + c;
- half x = (_TriangleCornerRadius.x - k) / m;
- half2 circlePivot = half2(x, _TriangleCornerRadius.x);
- half cornerCircle = circle(_texcoord - circlePivot, _TriangleCornerRadius.x);
- //sdf = sdfDifference(sdf, cornerCircle);
- //return sdf;
- x = (circlePivot.y + circlePivot.x / m - c) / (m + 1.0 / m);
- half y = m * x + c;
- half fy = map(_texcoord.x, x, circlePivot.x, y, circlePivot.y);
- sdf = _texcoord.y < fy && _texcoord.x < circlePivot.x ? cornerCircle: sdf;
- //return sdf;
- // Right Corner
- m = -m; c = 2.0 * height;
- k = -_TriangleCornerRadius.y * d + c;
- x = (_TriangleCornerRadius.y - k) / m;
- circlePivot = half2(x, _TriangleCornerRadius.y);
- cornerCircle = circle(_texcoord - circlePivot, _TriangleCornerRadius.y);
- x = (circlePivot.y + circlePivot.x / m - c) / (m + 1.0 / m); y = m * x + c;
- fy = map(_texcoord.x, circlePivot.x, x, circlePivot.y, y);
- sdf = _texcoord.x > circlePivot.x && _texcoord.y < fy ? cornerCircle: sdf;
-
- //Top Corner
- k = -_TriangleCornerRadius.z * sqrt(1.0 + m * m) + c;
- y = m * (width / 2.0) + k;
- circlePivot = half2(halfWidth, y);
- cornerCircle = circle(_texcoord - circlePivot, _TriangleCornerRadius.z);
- x = (circlePivot.y + circlePivot.x / m - c) / (m + 1.0 / m); y = m * x + c;
- fy = map(_texcoord.x, width - x, x, -1.0, 1.0);
- fy = lerp(circlePivot.y, y, abs(fy));
- sdf = _texcoord.y > fy ? cornerCircle: sdf;
-
- return sdf;
- }
- #endif
-
- #if NSTAR_POLYGON
- half nStarPolygonScene(float4 _sizeData, float4 _shapeData)
- {
- float2 _texcoord = _sizeData.xy;
- float width = _sizeData.z;
- float height = _sizeData.w;
- float size = height / 2 - _shapeData.y;
- half str = sdNStarPolygon(_texcoord - half2(width / 2, height / 2), size, _shapeData.x, _shapeData.z) - _shapeData.y;
- return str;
- }
- #endif
-
- float2 rotateUV(float2 uv, float rotation, float2 mid)
- {
- return float2(
- cos(rotation) * (uv.x - mid.x) + sin(rotation) * (uv.y - mid.y) + mid.x,
- cos(rotation) * (uv.y - mid.y) - sin(rotation) * (uv.x - mid.x) + mid.y
- );
- }
-
-
- float4 decode_0_1_16(float2 input){
- float m = 65535.0;
- float e = 256.0 / 255.0;
- float n = 1.0 / m;
-
- float4 c = float4(input.x, input.x, input.y, input.y);
- c.yw *= m;
- c = frac(c);
- c -= float4(c.y, 0.0, c.w, 0.0) * n;
- return clamp(c * e, 0.0, 1.0);
- }
-
-
- v2f vert(appdata_t v)
- {
- v2f OUT;
- UNITY_SETUP_INSTANCE_ID(v);
- UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
-
- OUT.vertex = UnityObjectToClipPos(v.vertex);
- OUT.worldPosition = v.vertex;
- OUT.color = v.color * _Color;
- OUT.uv0 = v.uv0;
-
-
- float2 size = v.uv1;
- half strokeWidth = v.normal.y;
- half falloff = v.normal.z;
-
- float rotationData = v.uv3.x;
- half cornerStyle = v.uv3.y;
-
- half outlineWidth = v.normal.x;
- half4 outlineColor = v.tangent;
- float4 shapeData;
- #if CIRCLE
- shapeData.xy = v.uv2.xy;
- #else
- shapeData = decode_0_1_16(v.uv2) * min(size.x, size.y);
- #endif
-
-
- OUT.strokeOutlineCornerData = float4(strokeWidth, falloff, outlineWidth, cornerStyle);
- OUT.outlineColor = outlineColor;
- OUT.shapeData = shapeData;
-
- // Rotation Values
- half sign = rotationData > 0.0 ? 1 : -1;
- float f = abs(rotationData);
- float shapeRotation = frac(f) * 360.0 * sign;
-
- // r.xyz -> constrainRotation, flipHorizontal, flipVertical
-
- f = floor(f);
- float p = f / 100.0;
- float z = round(p);
- p = frac(p) * 10.0;
- float y = round(p);
- p = frac(p) * 10.0;
- float x = round(p);
-
- half constrainRotation = x;
- half flipHorizontal = y;
- half flipVertical = z;
-
-
- shapeRotation = radians(shapeRotation);
- size = constrainRotation > 0.0 && frac(abs(shapeRotation) / 3.14159) > 0.1? float2(size.y, size.x) : size;
-
- float2 shapeUv = constrainRotation > 0 ? v.uv0 : v.uv0 * size;
- shapeUv = rotateUV(shapeUv, shapeRotation, constrainRotation > 0? float2(0.5, 0.5) : size * 0.5);
- shapeUv*= constrainRotation > 0.0? size : 1.0;
-
- shapeUv.x = lerp(shapeUv.x, abs(size.x - shapeUv.x), flipHorizontal);
- shapeUv.y = lerp(shapeUv.y, abs(size.y - shapeUv.y), flipVertical);
-
- OUT.sizeData = float4(shapeUv.x, shapeUv.y, size.x, size.y);
-
- #ifdef UNITY_HALF_TEXEL_OFFSET
- OUT.vertex.xy += (_ScreenParams.zw - 1.0) * float2(-1.0, 1.0);
- #endif
-
- /* //SOFTMASK_HANDLE_START
- SOFTMASK_CALCULATE_COORDS(OUT, v.vertex);
- */ //SOFTMASK_HANDLE_END
- return OUT;
- }
-
- fixed4 frag(v2f IN): SV_Target
- {
- half4 color = IN.color;
- half2 texcoord = IN.uv0;
- color = (tex2D(_MainTex, texcoord) + _TextureSampleAdd) * color;
-
- float4 sizeData = IN.sizeData;
- float strokeWidth = IN.strokeOutlineCornerData.x;
- float falloff = IN.strokeOutlineCornerData.y;
- float outlineWidth = IN.strokeOutlineCornerData.z;
- half4 outlineColor = IN.outlineColor;
- float cornerStyle = IN.strokeOutlineCornerData.w;
-
- float4 shapeData = IN.shapeData;
- half pixelScale = clamp(1.0/falloff, 1.0/2048.0, 2048.0);
-
- float sdfData = 0;
- #if RECTANGLE
- sdfData = rectangleScene(sizeData, shapeData, cornerStyle);
- #endif
-
- #if CIRCLE
- sdfData = circleScene(sizeData, shapeData);
- #endif
-
- #if TRIANGLE
- sdfData = triangleScene(sizeData, shapeData);
- #endif
-
- #if NSTAR_POLYGON
- sdfData = nStarPolygonScene(sizeData, shapeData);
- #endif
-
-
- #if !OUTLINED && !STROKE && !OUTLINED_STROKE
- half shape = sampleSdf(sdfData, pixelScale);
- color.a *= shape;
- //color.a = sdfData;
- #endif
- #if STROKE
- half shape = sampleSdfStrip(sdfData, strokeWidth, pixelScale);
- color.a *= shape;
- #endif
-
- #if OUTLINED
- float alpha = sampleSdf(sdfData, pixelScale);
- float lerpFac = sampleSdf(sdfData + outlineWidth, pixelScale);
- color = half4(lerp(outlineColor.rgb, color.rgb, lerpFac), lerp(outlineColor.a * color.a, color.a, lerpFac));
- color.a *= alpha;
- #endif
-
- #if OUTLINED_STROKE
- float alpha = sampleSdfStrip(sdfData, outlineWidth + strokeWidth, pixelScale);
- float lerpFac = sampleSdfStrip(sdfData + outlineWidth, strokeWidth + falloff, pixelScale);
- lerpFac = clamp(lerpFac, 0, 1);
- color = half4(lerp(outlineColor.rgb, color.rgb, lerpFac), lerp(outlineColor.a * color.a, color.a, lerpFac));
- color.a *= alpha;
- #endif
- /* //SOFTMASK_HANDLE_START
- color.a *= SOFTMASK_GET_MASK(IN);
- */ //SOFTMASK_HANDLE_END
-
- #ifdef UNITY_UI_CLIP_RECT
- color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
- #endif
-
- #ifdef UNITY_UI_ALPHACLIP
- clip(color.a - 0.001);
- #endif
-
- return fixed4(color);
- }
- ENDCG
-
- }
- }
- CustomEditor "MPUIKIT.Editor.MPImageShaderGUI"
- }
|