251 lines
10 KiB
Plaintext
251 lines
10 KiB
Plaintext
Shader "AIBIS/EyeUnifiedSprite"
|
|
{
|
|
Properties
|
|
{
|
|
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
|
|
_Color ("Tint", Color) = (1, 1, 1, 1)
|
|
_SpriteFade ("Sprite Fade", Range(0, 1)) = 1
|
|
|
|
[Header(Eye State)]
|
|
_ColorReveal ("Color Reveal", Range(0, 1)) = 1
|
|
_GrayAmount ("Gray Amount", Range(0, 1)) = 0
|
|
_RevealWidth ("Reveal Width", Range(0.001, 1)) = 0.18
|
|
_RevealRotation ("Reveal Rotation", Range(0, 6.28318)) = 0
|
|
_RevealNoise ("Reveal Noise", Range(0, 1)) = 0.08
|
|
_WrongColor ("Wrong Color", Color) = (1, 0.16, 0.08, 1)
|
|
_WrongColorAmount ("Wrong Color Amount", Range(0, 1)) = 0
|
|
|
|
[Header(Texture Effects)]
|
|
_BlurAmount ("Blur Amount", Range(0, 1)) = 0
|
|
_BlurSize ("Blur Size", Range(0, 0.02)) = 0.004
|
|
_DistortAmount ("Distort Amount", Range(0, 0.08)) = 0
|
|
_GlitchAmount ("Glitch Amount", Range(0, 1)) = 0
|
|
_HsvShift ("Hue Shift", Range(0, 360)) = 0
|
|
_HsvSaturation ("HSV Saturation", Range(0, 2)) = 1
|
|
_RoundWaveStrength ("Round Wave Strength", Range(0, 1)) = 0
|
|
|
|
[Header(UF Sprite FX)]
|
|
_AsciiAmount ("Ascii Amount", Range(0, 1)) = 0
|
|
_AsciiCellSize ("Ascii Cell Size", Range(12, 160)) = 64
|
|
_DreamAmount ("Dream Amount", Range(0, 1)) = 0
|
|
_MemoryAmount ("Memory Amount", Range(0, 1)) = 0
|
|
_ScanlineAmount ("Scanline Amount", Range(0, 1)) = 0
|
|
_PixelSteps ("Posterize Steps", Range(2, 32)) = 8
|
|
}
|
|
|
|
SubShader
|
|
{
|
|
Tags
|
|
{
|
|
"Queue" = "Transparent"
|
|
"IgnoreProjector" = "True"
|
|
"RenderType" = "Transparent"
|
|
"PreviewType" = "Plane"
|
|
"CanUseSpriteAtlas" = "True"
|
|
}
|
|
|
|
Cull Off
|
|
Lighting Off
|
|
ZWrite Off
|
|
Blend SrcAlpha OneMinusSrcAlpha
|
|
|
|
Pass
|
|
{
|
|
CGPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment frag
|
|
#pragma target 2.0
|
|
#include "UnityCG.cginc"
|
|
|
|
struct appdata
|
|
{
|
|
float4 vertex : POSITION;
|
|
float4 color : COLOR;
|
|
float2 uv : TEXCOORD0;
|
|
};
|
|
|
|
struct v2f
|
|
{
|
|
float4 vertex : SV_POSITION;
|
|
fixed4 color : COLOR;
|
|
float2 uv : TEXCOORD0;
|
|
float4 screenPos : TEXCOORD1;
|
|
};
|
|
|
|
sampler2D _MainTex;
|
|
float4 _MainTex_TexelSize;
|
|
fixed4 _Color;
|
|
float _SpriteFade;
|
|
|
|
float _ColorReveal;
|
|
float _GrayAmount;
|
|
float _RevealWidth;
|
|
float _RevealRotation;
|
|
float _RevealNoise;
|
|
fixed4 _WrongColor;
|
|
float _WrongColorAmount;
|
|
|
|
float _BlurAmount;
|
|
float _BlurSize;
|
|
float _DistortAmount;
|
|
float _GlitchAmount;
|
|
float _HsvShift;
|
|
float _HsvSaturation;
|
|
float _RoundWaveStrength;
|
|
|
|
float _AsciiAmount;
|
|
float _AsciiCellSize;
|
|
float _DreamAmount;
|
|
float _MemoryAmount;
|
|
float _ScanlineAmount;
|
|
float _PixelSteps;
|
|
|
|
v2f vert(appdata v)
|
|
{
|
|
v2f o;
|
|
o.vertex = UnityObjectToClipPos(v.vertex);
|
|
o.color = v.color * _Color;
|
|
o.uv = v.uv;
|
|
o.screenPos = ComputeScreenPos(o.vertex);
|
|
return o;
|
|
}
|
|
|
|
float hash21(float2 p)
|
|
{
|
|
p = frac(p * float2(123.34, 456.21));
|
|
p += dot(p, p + 45.32);
|
|
return frac(p.x * p.y);
|
|
}
|
|
|
|
float3 hueShift(float3 color, float shiftDegrees)
|
|
{
|
|
float angle = shiftDegrees * 0.01745329252;
|
|
float s = sin(angle);
|
|
float c = cos(angle);
|
|
float3 weights = float3(0.299, 0.587, 0.114);
|
|
|
|
float3x3 mat = float3x3(
|
|
weights.x + (1 - weights.x) * c + 0.168 * s, weights.y - weights.y * c + 0.330 * s, weights.z - weights.z * c - 0.497 * s,
|
|
weights.x - weights.x * c - 0.328 * s, weights.y + (1 - weights.y) * c + 0.035 * s, weights.z - weights.z * c + 0.292 * s,
|
|
weights.x - weights.x * c + 1.250 * s, weights.y - weights.y * c - 1.050 * s, weights.z + (1 - weights.z) * c - 0.203 * s
|
|
);
|
|
|
|
return saturate(mul(mat, color));
|
|
}
|
|
|
|
half4 sampleMainTex(float2 uv)
|
|
{
|
|
return tex2D(_MainTex, saturate(uv));
|
|
}
|
|
|
|
half3 GaussianBlurRgb(float2 uv, float stepSize)
|
|
{
|
|
float angle = 1.937315; // ~111 deg, matches MemoryTuningSprite
|
|
float2 stepDir = float2(sin(angle), cos(angle));
|
|
float2 stepUv = stepDir * stepSize;
|
|
|
|
#if defined(SHADER_API_MOBILE)
|
|
half3 rgb = sampleMainTex(uv).rgb * 0.34;
|
|
rgb += sampleMainTex(uv + stepUv).rgb * 0.33;
|
|
rgb += sampleMainTex(uv - stepUv).rgb * 0.33;
|
|
#else
|
|
half3 rgb = sampleMainTex(uv).rgb * 0.18;
|
|
rgb += sampleMainTex(uv + stepUv * 1.0).rgb * 0.15;
|
|
rgb += sampleMainTex(uv - stepUv * 1.0).rgb * 0.15;
|
|
rgb += sampleMainTex(uv + stepUv * 2.0).rgb * 0.12;
|
|
rgb += sampleMainTex(uv - stepUv * 2.0).rgb * 0.12;
|
|
rgb += sampleMainTex(uv + stepUv * 3.0).rgb * 0.09;
|
|
rgb += sampleMainTex(uv - stepUv * 3.0).rgb * 0.09;
|
|
rgb += sampleMainTex(uv + stepUv * 4.0).rgb * 0.05;
|
|
rgb += sampleMainTex(uv - stepUv * 4.0).rgb * 0.05;
|
|
#endif
|
|
return rgb;
|
|
}
|
|
|
|
fixed4 sampleSprite(float2 uv, float2 screenUv)
|
|
{
|
|
float2 distortedUv = uv;
|
|
|
|
float2 centered = uv - 0.5;
|
|
float ripple = sin((length(centered) * 42.0) - (_Time.y * 8.0));
|
|
distortedUv += centered * ripple * _RoundWaveStrength * 0.018;
|
|
|
|
float glitchRow = floor(screenUv.y * 360.0);
|
|
float tear = (hash21(float2(glitchRow, floor(_Time.y * 20.0))) - 0.5) * _GlitchAmount * 0.012;
|
|
distortedUv.x += tear;
|
|
|
|
float noise = hash21(floor(uv * 42.0) + floor(_Time.y * 16.0));
|
|
distortedUv += (noise - 0.5) * _DistortAmount;
|
|
|
|
float2 texel = max(abs(_MainTex_TexelSize.xy), float2(1e-5, 1e-5));
|
|
float stepSize = length(texel) + _BlurSize;
|
|
fixed4 col = sampleMainTex(distortedUv);
|
|
fixed3 blurredRgb = GaussianBlurRgb(distortedUv, stepSize);
|
|
|
|
float blurStrength = pow(saturate(_BlurAmount), 0.75);
|
|
col.rgb = lerp(col.rgb, blurredRgb, blurStrength);
|
|
return col;
|
|
}
|
|
|
|
fixed4 frag(v2f i) : SV_Target
|
|
{
|
|
float2 screenUv = i.screenPos.xy / i.screenPos.w;
|
|
float2 uv = i.uv;
|
|
|
|
fixed4 col = sampleSprite(uv, screenUv) * i.color;
|
|
|
|
float gray = dot(col.rgb, float3(0.299, 0.587, 0.114));
|
|
float2 revealDir = float2(cos(_RevealRotation), sin(_RevealRotation));
|
|
float directional = dot(uv - 0.5, revealDir) + 0.5;
|
|
float dissolveNoise = (hash21(floor(uv * 96.0)) - 0.5) * _RevealNoise;
|
|
float revealMask = smoothstep(_ColorReveal - _RevealWidth, _ColorReveal + _RevealWidth, directional + dissolveNoise);
|
|
// Idle (_GrayAmount=1) or fully colored (_GrayAmount=0): uniform mix; sweep only mid-transition.
|
|
float inSweep = step(0.001, 1.0 - _GrayAmount) * step(0.001, _GrayAmount);
|
|
float sweepFactor = lerp(1.0, (1.0 - revealMask), inSweep);
|
|
float grayMix = saturate(_GrayAmount * sweepFactor);
|
|
|
|
col.rgb = lerp(col.rgb, gray.xxx, grayMix);
|
|
|
|
float sweepEdge = 1.0 - abs(directional + dissolveNoise - _ColorReveal);
|
|
float edgeGlow = smoothstep(_RevealWidth * 0.15, _RevealWidth * 0.55, sweepEdge) * inSweep * _GrayAmount * (1.0 - revealMask);
|
|
col.rgb += float3(1.0, 0.92, 0.78) * edgeGlow * 0.35;
|
|
col.rgb = lerp(col.rgb, _WrongColor.rgb * max(gray, 0.08), _WrongColorAmount * _WrongColor.a);
|
|
|
|
col.rgb = hueShift(col.rgb, _HsvShift);
|
|
float shiftedGray = dot(col.rgb, float3(0.299, 0.587, 0.114));
|
|
col.rgb = lerp(shiftedGray.xxx, col.rgb, _HsvSaturation);
|
|
|
|
float posterize = max(2.0, _PixelSteps);
|
|
float3 posterized = floor(col.rgb * posterize) / posterize;
|
|
col.rgb = lerp(col.rgb, posterized, saturate(_DreamAmount + _MemoryAmount * 0.5));
|
|
|
|
float scan = sin(screenUv.y * 900.0 + _Time.y * 18.0) * 0.5 + 0.5;
|
|
float scanAmount = saturate(_ScanlineAmount + _MemoryAmount * 0.5);
|
|
col.rgb *= lerp(1.0, 0.68 + scan * 0.38, scanAmount);
|
|
|
|
float2 asciiGrid = floor(screenUv * _AsciiCellSize);
|
|
float asciiNoise = hash21(asciiGrid + floor(_Time.y * 8.0));
|
|
float asciiShape = step(0.48, frac(screenUv.x * _AsciiCellSize * 2.0)) * step(0.25 + asciiNoise * 0.35, frac(screenUv.y * _AsciiCellSize));
|
|
float asciiBrightness = step(asciiNoise, gray);
|
|
float ascii = asciiShape * asciiBrightness;
|
|
col.rgb = lerp(col.rgb, ascii.xxx * lerp(float3(1, 1, 1), col.rgb, 0.35), _AsciiAmount);
|
|
|
|
float chromaOffset = _GlitchAmount * 0.004;
|
|
if (chromaOffset > 0.0001)
|
|
{
|
|
float red = tex2D(_MainTex, uv + float2(chromaOffset, 0)).r;
|
|
float blue = tex2D(_MainTex, uv - float2(chromaOffset, 0)).b;
|
|
col.r = lerp(col.r, red, _GlitchAmount);
|
|
col.b = lerp(col.b, blue, _GlitchAmount);
|
|
}
|
|
|
|
col.a *= _SpriteFade;
|
|
return col;
|
|
}
|
|
ENDCG
|
|
}
|
|
}
|
|
|
|
Fallback "Sprites/Default"
|
|
}
|