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" }