diff --git a/Assets/Materials/EyeMaterials/EyeUnifiedSprite.mat b/Assets/Materials/EyeMaterials/EyeUnifiedSprite.mat new file mode 100644 index 000000000..0578d7206 --- /dev/null +++ b/Assets/Materials/EyeMaterials/EyeUnifiedSprite.mat @@ -0,0 +1,55 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: EyeUnifiedSprite + m_Shader: {fileID: 4800000, guid: f7f1f0a7430f4f44fa1d7af89e1e013f, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AsciiAmount: 0 + - _AsciiCellSize: 64 + - _BlurAmount: 0.627 + - _BlurSize: 0.00279 + - _ColorReveal: 0 + - _DistortAmount: 0 + - _DreamAmount: 0 + - _GlitchAmount: 0 + - _GrayAmount: 1 + - _HsvSaturation: 1 + - _HsvShift: 0 + - _MemoryAmount: 0 + - _PixelSteps: 8 + - _RevealNoise: 0.08 + - _RevealRotation: 0 + - _RevealWidth: 0.18 + - _RoundWaveStrength: 0 + - _ScanlineAmount: 0 + - _SpriteFade: 1 + - _WrongColorAmount: 0 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _WrongColor: {r: 1, g: 0.16, b: 0.08, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/EyeMaterials/EyeUnifiedSprite.mat.meta b/Assets/Materials/EyeMaterials/EyeUnifiedSprite.mat.meta new file mode 100644 index 000000000..32ec70827 --- /dev/null +++ b/Assets/Materials/EyeMaterials/EyeUnifiedSprite.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e8f4a2b1c3d5476980abcdef01234567 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Render/EyeUnifiedSprite.shader b/Assets/Render/EyeUnifiedSprite.shader new file mode 100644 index 000000000..860b2a5e5 --- /dev/null +++ b/Assets/Render/EyeUnifiedSprite.shader @@ -0,0 +1,217 @@ +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)); + } + + 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 * 240.0); + float tear = (hash21(float2(glitchRow, floor(_Time.y * 18.0))) - 0.5) * _GlitchAmount * 0.04; + distortedUv.x += tear; + + float noise = hash21(floor(uv * 42.0) + floor(_Time.y * 16.0)); + distortedUv += (noise - 0.5) * _DistortAmount; + + float2 blur = _MainTex_TexelSize.xy + _BlurSize; + fixed4 col = tex2D(_MainTex, distortedUv); + fixed4 blurCol = col; + blurCol += tex2D(_MainTex, distortedUv + float2(blur.x, 0)); + blurCol += tex2D(_MainTex, distortedUv - float2(blur.x, 0)); + blurCol += tex2D(_MainTex, distortedUv + float2(0, blur.y)); + blurCol += tex2D(_MainTex, distortedUv - float2(0, blur.y)); + blurCol *= 0.2; + + return lerp(col, blurCol, _BlurAmount); + } + + 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); + // Sweep only applies while the target is still desaturated; full color when _GrayAmount reaches 0. + float grayMix = saturate(max(_GrayAmount, (1.0 - revealMask) * _GrayAmount)); + + col.rgb = lerp(col.rgb, gray.xxx, grayMix); + 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.006; + 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" +} diff --git a/Assets/Render/EyeUnifiedSprite.shader.meta b/Assets/Render/EyeUnifiedSprite.shader.meta new file mode 100644 index 000000000..9b762ccf2 --- /dev/null +++ b/Assets/Render/EyeUnifiedSprite.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f7f1f0a7430f4f44fa1d7af89e1e013f +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + shaderImporterVersion: 1 + userData: + assetBundleName: + assetBundleVariant: