ui基本完毕,修了一大把的bug
This commit is contained in:
@@ -0,0 +1,284 @@
|
||||
Shader "Bansonic/Sprite Outline"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
|
||||
[HideInInspector] _Color ("Tint", Color) = (1,1,1,1)
|
||||
[HideInInspector] PixelSnap ("Pixel snap", Float) = 0
|
||||
[HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1)
|
||||
[HideInInspector] _AlphaTex ("External Alpha", 2D) = "white" {}
|
||||
[HideInInspector] _EnableExternalAlpha ("Enable External Alpha", Float) = 0
|
||||
|
||||
[HDR]_OutlineColor ("Outline Color", Color) = (1,1,1,1)
|
||||
_OutlineThickness ("Outline Thickness", Range(0, 12)) = 1
|
||||
_AlphaThreshold ("Alpha Threshold", Range(0, 1)) = 0.1
|
||||
_OutlineOpacity ("Outline Opacity", Range(0, 1)) = 1
|
||||
_InnerOutline ("Inner Outline Blend", Range(0, 1)) = 0
|
||||
_SpriteAlpha ("Sprite Alpha", Range(0, 1)) = 1
|
||||
}
|
||||
|
||||
SubShader
|
||||
{
|
||||
Tags
|
||||
{
|
||||
"Queue" = "Transparent"
|
||||
"RenderType" = "Transparent"
|
||||
"RenderPipeline" = "UniversalPipeline"
|
||||
"CanUseSpriteAtlas" = "True"
|
||||
}
|
||||
|
||||
Blend SrcAlpha OneMinusSrcAlpha, One OneMinusSrcAlpha
|
||||
Cull Off
|
||||
ZWrite Off
|
||||
|
||||
Pass
|
||||
{
|
||||
Tags { "LightMode" = "Universal2D" }
|
||||
|
||||
HLSLPROGRAM
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/Core2D.hlsl"
|
||||
|
||||
#pragma vertex SpriteVertex
|
||||
#pragma fragment SpriteFragment
|
||||
#pragma target 2.0
|
||||
#pragma multi_compile_instancing
|
||||
#pragma multi_compile _ SKINNED_SPRITE
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float3 positionOS : POSITION;
|
||||
float4 color : COLOR;
|
||||
float2 uv : TEXCOORD0;
|
||||
UNITY_SKINNED_VERTEX_INPUTS
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
half4 color : COLOR;
|
||||
float2 uv : TEXCOORD0;
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
TEXTURE2D(_MainTex);
|
||||
SAMPLER(sampler_MainTex);
|
||||
float4 _MainTex_TexelSize;
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
half4 _Color;
|
||||
half4 _OutlineColor;
|
||||
half _OutlineThickness;
|
||||
half _AlphaThreshold;
|
||||
half _OutlineOpacity;
|
||||
half _InnerOutline;
|
||||
half _SpriteAlpha;
|
||||
CBUFFER_END
|
||||
|
||||
Varyings SpriteVertex(Attributes input)
|
||||
{
|
||||
Varyings output = (Varyings)0;
|
||||
UNITY_SETUP_INSTANCE_ID(input);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
|
||||
UNITY_SKINNED_VERTEX_COMPUTE(input);
|
||||
|
||||
SetUpSpriteInstanceProperties();
|
||||
input.positionOS = UnityFlipSprite(input.positionOS, unity_SpriteProps.xy);
|
||||
output.positionCS = TransformObjectToHClip(input.positionOS);
|
||||
output.uv = input.uv;
|
||||
output.color = input.color * _Color * unity_SpriteColor;
|
||||
return output;
|
||||
}
|
||||
|
||||
half SampleAlpha(float2 uv, half4 tint)
|
||||
{
|
||||
half4 tex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv) * tint;
|
||||
return tex.a;
|
||||
}
|
||||
|
||||
half ComputeOuterMask(float2 uv, half4 tint)
|
||||
{
|
||||
float2 texel = _MainTex_TexelSize.xy * max(_OutlineThickness, 0.001h);
|
||||
half center = SampleAlpha(uv, tint);
|
||||
half maxNeighbor = 0h;
|
||||
|
||||
maxNeighbor = max(maxNeighbor, SampleAlpha(uv + texel * float2( 1.0, 0.0), tint));
|
||||
maxNeighbor = max(maxNeighbor, SampleAlpha(uv + texel * float2(-1.0, 0.0), tint));
|
||||
maxNeighbor = max(maxNeighbor, SampleAlpha(uv + texel * float2( 0.0, 1.0), tint));
|
||||
maxNeighbor = max(maxNeighbor, SampleAlpha(uv + texel * float2( 0.0, -1.0), tint));
|
||||
maxNeighbor = max(maxNeighbor, SampleAlpha(uv + texel * float2( 0.7071, 0.7071), tint));
|
||||
maxNeighbor = max(maxNeighbor, SampleAlpha(uv + texel * float2(-0.7071, 0.7071), tint));
|
||||
maxNeighbor = max(maxNeighbor, SampleAlpha(uv + texel * float2( 0.7071, -0.7071), tint));
|
||||
maxNeighbor = max(maxNeighbor, SampleAlpha(uv + texel * float2(-0.7071, -0.7071), tint));
|
||||
|
||||
half centerMask = step(_AlphaThreshold, center);
|
||||
half neighborMask = step(_AlphaThreshold, maxNeighbor);
|
||||
return saturate(neighborMask - centerMask);
|
||||
}
|
||||
|
||||
half ComputeInnerMask(float2 uv, half4 tint)
|
||||
{
|
||||
float2 texel = _MainTex_TexelSize.xy * max(_OutlineThickness, 0.001h);
|
||||
half center = SampleAlpha(uv, tint);
|
||||
half minNeighbor = 1h;
|
||||
|
||||
minNeighbor = min(minNeighbor, SampleAlpha(uv + texel * float2( 1.0, 0.0), tint));
|
||||
minNeighbor = min(minNeighbor, SampleAlpha(uv + texel * float2(-1.0, 0.0), tint));
|
||||
minNeighbor = min(minNeighbor, SampleAlpha(uv + texel * float2( 0.0, 1.0), tint));
|
||||
minNeighbor = min(minNeighbor, SampleAlpha(uv + texel * float2( 0.0, -1.0), tint));
|
||||
minNeighbor = min(minNeighbor, SampleAlpha(uv + texel * float2( 0.7071, 0.7071), tint));
|
||||
minNeighbor = min(minNeighbor, SampleAlpha(uv + texel * float2(-0.7071, 0.7071), tint));
|
||||
minNeighbor = min(minNeighbor, SampleAlpha(uv + texel * float2( 0.7071, -0.7071), tint));
|
||||
minNeighbor = min(minNeighbor, SampleAlpha(uv + texel * float2(-0.7071, -0.7071), tint));
|
||||
|
||||
half centerMask = step(_AlphaThreshold, center);
|
||||
half neighborMask = step(_AlphaThreshold, minNeighbor);
|
||||
return saturate(centerMask - neighborMask);
|
||||
}
|
||||
|
||||
half4 SpriteFragment(Varyings input) : SV_Target
|
||||
{
|
||||
half4 baseSample = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv) * input.color;
|
||||
half outerMask = ComputeOuterMask(input.uv, input.color);
|
||||
half innerMask = ComputeInnerMask(input.uv, input.color);
|
||||
half outlineMask = saturate(lerp(outerMask, max(outerMask, innerMask), _InnerOutline)) * _OutlineOpacity;
|
||||
|
||||
half4 color = baseSample;
|
||||
color.rgb *= _SpriteAlpha;
|
||||
color.a *= _SpriteAlpha;
|
||||
|
||||
color.rgb = lerp(color.rgb, _OutlineColor.rgb, outlineMask * _OutlineColor.a);
|
||||
color.a = saturate(color.a + outlineMask * _OutlineColor.a);
|
||||
return color;
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Tags { "LightMode" = "UniversalForward" }
|
||||
|
||||
HLSLPROGRAM
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/Core2D.hlsl"
|
||||
|
||||
#pragma vertex SpriteVertex
|
||||
#pragma fragment SpriteFragment
|
||||
#pragma target 2.0
|
||||
#pragma multi_compile_instancing
|
||||
#pragma multi_compile _ SKINNED_SPRITE
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float3 positionOS : POSITION;
|
||||
float4 color : COLOR;
|
||||
float2 uv : TEXCOORD0;
|
||||
UNITY_SKINNED_VERTEX_INPUTS
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
half4 color : COLOR;
|
||||
float2 uv : TEXCOORD0;
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
TEXTURE2D(_MainTex);
|
||||
SAMPLER(sampler_MainTex);
|
||||
float4 _MainTex_TexelSize;
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
half4 _Color;
|
||||
half4 _OutlineColor;
|
||||
half _OutlineThickness;
|
||||
half _AlphaThreshold;
|
||||
half _OutlineOpacity;
|
||||
half _InnerOutline;
|
||||
half _SpriteAlpha;
|
||||
CBUFFER_END
|
||||
|
||||
Varyings SpriteVertex(Attributes input)
|
||||
{
|
||||
Varyings output = (Varyings)0;
|
||||
UNITY_SETUP_INSTANCE_ID(input);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
|
||||
UNITY_SKINNED_VERTEX_COMPUTE(input);
|
||||
|
||||
SetUpSpriteInstanceProperties();
|
||||
input.positionOS = UnityFlipSprite(input.positionOS, unity_SpriteProps.xy);
|
||||
output.positionCS = TransformObjectToHClip(input.positionOS);
|
||||
output.uv = input.uv;
|
||||
output.color = input.color * _Color * unity_SpriteColor;
|
||||
return output;
|
||||
}
|
||||
|
||||
half SampleAlpha(float2 uv, half4 tint)
|
||||
{
|
||||
half4 tex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv) * tint;
|
||||
return tex.a;
|
||||
}
|
||||
|
||||
half ComputeOuterMask(float2 uv, half4 tint)
|
||||
{
|
||||
float2 texel = _MainTex_TexelSize.xy * max(_OutlineThickness, 0.001h);
|
||||
half center = SampleAlpha(uv, tint);
|
||||
half maxNeighbor = 0h;
|
||||
|
||||
maxNeighbor = max(maxNeighbor, SampleAlpha(uv + texel * float2( 1.0, 0.0), tint));
|
||||
maxNeighbor = max(maxNeighbor, SampleAlpha(uv + texel * float2(-1.0, 0.0), tint));
|
||||
maxNeighbor = max(maxNeighbor, SampleAlpha(uv + texel * float2( 0.0, 1.0), tint));
|
||||
maxNeighbor = max(maxNeighbor, SampleAlpha(uv + texel * float2( 0.0, -1.0), tint));
|
||||
maxNeighbor = max(maxNeighbor, SampleAlpha(uv + texel * float2( 0.7071, 0.7071), tint));
|
||||
maxNeighbor = max(maxNeighbor, SampleAlpha(uv + texel * float2(-0.7071, 0.7071), tint));
|
||||
maxNeighbor = max(maxNeighbor, SampleAlpha(uv + texel * float2( 0.7071, -0.7071), tint));
|
||||
maxNeighbor = max(maxNeighbor, SampleAlpha(uv + texel * float2(-0.7071, -0.7071), tint));
|
||||
|
||||
half centerMask = step(_AlphaThreshold, center);
|
||||
half neighborMask = step(_AlphaThreshold, maxNeighbor);
|
||||
return saturate(neighborMask - centerMask);
|
||||
}
|
||||
|
||||
half ComputeInnerMask(float2 uv, half4 tint)
|
||||
{
|
||||
float2 texel = _MainTex_TexelSize.xy * max(_OutlineThickness, 0.001h);
|
||||
half center = SampleAlpha(uv, tint);
|
||||
half minNeighbor = 1h;
|
||||
|
||||
minNeighbor = min(minNeighbor, SampleAlpha(uv + texel * float2( 1.0, 0.0), tint));
|
||||
minNeighbor = min(minNeighbor, SampleAlpha(uv + texel * float2(-1.0, 0.0), tint));
|
||||
minNeighbor = min(minNeighbor, SampleAlpha(uv + texel * float2( 0.0, 1.0), tint));
|
||||
minNeighbor = min(minNeighbor, SampleAlpha(uv + texel * float2( 0.0, -1.0), tint));
|
||||
minNeighbor = min(minNeighbor, SampleAlpha(uv + texel * float2( 0.7071, 0.7071), tint));
|
||||
minNeighbor = min(minNeighbor, SampleAlpha(uv + texel * float2(-0.7071, 0.7071), tint));
|
||||
minNeighbor = min(minNeighbor, SampleAlpha(uv + texel * float2( 0.7071, -0.7071), tint));
|
||||
minNeighbor = min(minNeighbor, SampleAlpha(uv + texel * float2(-0.7071, -0.7071), tint));
|
||||
|
||||
half centerMask = step(_AlphaThreshold, center);
|
||||
half neighborMask = step(_AlphaThreshold, minNeighbor);
|
||||
return saturate(centerMask - neighborMask);
|
||||
}
|
||||
|
||||
half4 SpriteFragment(Varyings input) : SV_Target
|
||||
{
|
||||
half4 baseSample = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv) * input.color;
|
||||
half outerMask = ComputeOuterMask(input.uv, input.color);
|
||||
half innerMask = ComputeInnerMask(input.uv, input.color);
|
||||
half outlineMask = saturate(lerp(outerMask, max(outerMask, innerMask), _InnerOutline)) * _OutlineOpacity;
|
||||
|
||||
half4 color = baseSample;
|
||||
color.rgb *= _SpriteAlpha;
|
||||
color.a *= _SpriteAlpha;
|
||||
|
||||
color.rgb = lerp(color.rgb, _OutlineColor.rgb, outlineMask * _OutlineColor.a);
|
||||
color.a = saturate(color.a + outlineMask * _OutlineColor.a);
|
||||
return color;
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
FallBack "Sprites/Default"
|
||||
}
|
||||
Reference in New Issue
Block a user