Files
bansonic_beta_main/Assets/Shaders/BansonicSpriteGlow.shader
2026-06-30 21:21:30 +08:00

275 lines
11 KiB
Plaintext

Shader "Bansonic/Sprite Glow"
{
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]_GlowColor ("Glow Color", Color) = (1,1,1,1)
_Threshold ("Glow Threshold", Range(0, 4)) = 0.9
_Intensity ("Glow Intensity", Range(0, 8)) = 1.5
_GlowRadius ("Glow Radius", Range(0, 32)) = 6
}
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 _GlowColor;
half _Threshold;
half _Intensity;
half _GlowRadius;
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 GetLuminance(half3 color)
{
return dot(color, half3(0.2126h, 0.7152h, 0.0722h));
}
half SampleGlowMask(float2 uv, half4 tint)
{
half4 tex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv) * tint;
half luminance = GetLuminance(tex.rgb);
half mask = smoothstep(_Threshold - 0.18h, _Threshold + 0.18h, luminance);
return mask * tex.a;
}
half ComputeGlow(float2 uv, half4 tint)
{
float2 texel = _MainTex_TexelSize.xy * max(_GlowRadius, 0.001h) * 1.5;
const half w0 = 0.180h;
const half w1 = 0.150h;
const half w2 = 0.120h;
const half w3 = 0.090h;
const half w4 = 0.060h;
half sum = SampleGlowMask(uv, tint) * w0;
sum += SampleGlowMask(uv + texel * float2( 0.65, 0.00), tint) * w1;
sum += SampleGlowMask(uv + texel * float2(-0.65, 0.00), tint) * w1;
sum += SampleGlowMask(uv + texel * float2( 0.00, 0.65), tint) * w1;
sum += SampleGlowMask(uv + texel * float2( 0.00, -0.65), tint) * w1;
sum += SampleGlowMask(uv + texel * float2( 0.50, 0.50), tint) * w2;
sum += SampleGlowMask(uv + texel * float2(-0.50, 0.50), tint) * w2;
sum += SampleGlowMask(uv + texel * float2( 0.50, -0.50), tint) * w2;
sum += SampleGlowMask(uv + texel * float2(-0.50, -0.50), tint) * w2;
sum += SampleGlowMask(uv + texel * float2( 1.35, 0.00), tint) * w3;
sum += SampleGlowMask(uv + texel * float2(-1.35, 0.00), tint) * w3;
sum += SampleGlowMask(uv + texel * float2( 0.00, 1.35), tint) * w3;
sum += SampleGlowMask(uv + texel * float2( 0.00, -1.35), tint) * w3;
sum += SampleGlowMask(uv + texel * float2( 1.00, 1.00), tint) * w4;
sum += SampleGlowMask(uv + texel * float2(-1.00, 1.00), tint) * w4;
sum += SampleGlowMask(uv + texel * float2( 1.00, -1.00), tint) * w4;
sum += SampleGlowMask(uv + texel * float2(-1.00, -1.00), tint) * w4;
return sum;
}
half4 SpriteFragment(Varyings input) : SV_Target
{
half4 baseSample = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv) * input.color;
half glowStrength = ComputeGlow(input.uv, input.color) * _Intensity * 1.75h;
half3 glow = _GlowColor.rgb * glowStrength * _GlowColor.a;
half4 color = baseSample;
color.rgb += glow;
color.a = saturate(baseSample.a + glowStrength * 0.55h);
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 _GlowColor;
half _Threshold;
half _Intensity;
half _GlowRadius;
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 GetLuminance(half3 color)
{
return dot(color, half3(0.2126h, 0.7152h, 0.0722h));
}
half SampleGlowMask(float2 uv, half4 tint)
{
half4 tex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv) * tint;
half luminance = GetLuminance(tex.rgb);
half mask = smoothstep(_Threshold - 0.18h, _Threshold + 0.18h, luminance);
return mask * tex.a;
}
half ComputeGlow(float2 uv, half4 tint)
{
float2 texel = _MainTex_TexelSize.xy * max(_GlowRadius, 0.001h) * 1.5;
const half w0 = 0.180h;
const half w1 = 0.150h;
const half w2 = 0.120h;
const half w3 = 0.090h;
const half w4 = 0.060h;
half sum = SampleGlowMask(uv, tint) * w0;
sum += SampleGlowMask(uv + texel * float2( 0.65, 0.00), tint) * w1;
sum += SampleGlowMask(uv + texel * float2(-0.65, 0.00), tint) * w1;
sum += SampleGlowMask(uv + texel * float2( 0.00, 0.65), tint) * w1;
sum += SampleGlowMask(uv + texel * float2( 0.00, -0.65), tint) * w1;
sum += SampleGlowMask(uv + texel * float2( 0.50, 0.50), tint) * w2;
sum += SampleGlowMask(uv + texel * float2(-0.50, 0.50), tint) * w2;
sum += SampleGlowMask(uv + texel * float2( 0.50, -0.50), tint) * w2;
sum += SampleGlowMask(uv + texel * float2(-0.50, -0.50), tint) * w2;
sum += SampleGlowMask(uv + texel * float2( 1.35, 0.00), tint) * w3;
sum += SampleGlowMask(uv + texel * float2(-1.35, 0.00), tint) * w3;
sum += SampleGlowMask(uv + texel * float2( 0.00, 1.35), tint) * w3;
sum += SampleGlowMask(uv + texel * float2( 0.00, -1.35), tint) * w3;
sum += SampleGlowMask(uv + texel * float2( 1.00, 1.00), tint) * w4;
sum += SampleGlowMask(uv + texel * float2(-1.00, 1.00), tint) * w4;
sum += SampleGlowMask(uv + texel * float2( 1.00, -1.00), tint) * w4;
sum += SampleGlowMask(uv + texel * float2(-1.00, -1.00), tint) * w4;
return sum;
}
half4 SpriteFragment(Varyings input) : SV_Target
{
half4 baseSample = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv) * input.color;
half glowStrength = ComputeGlow(input.uv, input.color) * _Intensity * 1.75h;
half3 glow = _GlowColor.rgb * glowStrength * _GlowColor.a;
half4 color = baseSample;
color.rgb += glow;
color.a = saturate(baseSample.a + glowStrength * 0.55h);
return color;
}
ENDHLSL
}
}
FallBack "Universal Render Pipeline/2D/Sprite-Unlit-Default"
}