diff --git a/Assets/Render/KiteFocusSprite.shader b/Assets/Render/KiteFocusSprite.shader index fa0175d49..87bfc7025 100644 --- a/Assets/Render/KiteFocusSprite.shader +++ b/Assets/Render/KiteFocusSprite.shader @@ -8,7 +8,7 @@ Shader "AIBIS/KiteFocusSprite" [Header(Focus Blur)] _BlurAmount ("Blur Amount", Range(0, 1)) = 0 _BlurSize ("Blur Size", Range(0, 0.05)) = 0.012 - [HideInInspector] _UseSoftFocus ("Use Soft Focus", Float) = 0 + [HideInInspector] _UseGaussianBlur ("Use Gaussian Blur", Float) = 0 _DefocusBloom ("Defocus Highlight Bloom", Range(0, 1)) = 0.32 _HaloStrength ("Large Circle Halo", Range(0, 0.6)) = 0.22 _ChromaticFringe ("Lens Color Fringe", Range(0, 0.6)) = 0.14 @@ -76,7 +76,7 @@ Shader "AIBIS/KiteFocusSprite" fixed4 _Color; float _BlurAmount; float _BlurSize; - float _UseSoftFocus; + float _UseGaussianBlur; float _DefocusBloom; float _HaloStrength; float _ChromaticFringe; @@ -152,31 +152,30 @@ Shader "AIBIS/KiteFocusSprite" return result * 0.125; } - half4 SoftFocusBlur(float2 uv, float radius) + // Same directional Gaussian kernel used by EyeUnifiedSprite in the + // Peipei eye module, including its lower-cost mobile fallback. + half3 EyeGaussianBlurRgb(float2 uv, float stepSize) { - float nearRadius = radius * 0.48; - half4 result = samplePremultiplied(uv) * 0.20; + float angle = 1.937315; + float2 stepDir = float2(sin(angle), cos(angle)); + float2 stepUv = stepDir * stepSize; - result += samplePremultiplied(uv + float2( nearRadius, 0)) * 0.08; - result += samplePremultiplied(uv + float2(-nearRadius, 0)) * 0.08; - result += samplePremultiplied(uv + float2(0, nearRadius)) * 0.08; - result += samplePremultiplied(uv + float2(0, -nearRadius)) * 0.08; - - result += samplePremultiplied(uv + float2( nearRadius, nearRadius)) * 0.055; - result += samplePremultiplied(uv + float2(-nearRadius, nearRadius)) * 0.055; - result += samplePremultiplied(uv + float2( nearRadius, -nearRadius)) * 0.055; - result += samplePremultiplied(uv + float2(-nearRadius, -nearRadius)) * 0.055; - - result += samplePremultiplied(uv + float2( radius, 0)) * 0.04; - result += samplePremultiplied(uv + float2(-radius, 0)) * 0.04; - result += samplePremultiplied(uv + float2(0, radius)) * 0.04; - result += samplePremultiplied(uv + float2(0, -radius)) * 0.04; - - result += samplePremultiplied(uv + float2( radius, radius)) * 0.025; - result += samplePremultiplied(uv + float2(-radius, radius)) * 0.025; - result += samplePremultiplied(uv + float2( radius, -radius)) * 0.025; - result += samplePremultiplied(uv + float2(-radius, -radius)) * 0.025; - return result; +#if defined(SHADER_API_MOBILE) + half3 rgb = tex2D(_MainTex, saturate(uv)).rgb * 0.34; + rgb += tex2D(_MainTex, saturate(uv + stepUv)).rgb * 0.33; + rgb += tex2D(_MainTex, saturate(uv - stepUv)).rgb * 0.33; +#else + half3 rgb = tex2D(_MainTex, saturate(uv)).rgb * 0.18; + rgb += tex2D(_MainTex, saturate(uv + stepUv * 1.0)).rgb * 0.15; + rgb += tex2D(_MainTex, saturate(uv - stepUv * 1.0)).rgb * 0.15; + rgb += tex2D(_MainTex, saturate(uv + stepUv * 2.0)).rgb * 0.12; + rgb += tex2D(_MainTex, saturate(uv - stepUv * 2.0)).rgb * 0.12; + rgb += tex2D(_MainTex, saturate(uv + stepUv * 3.0)).rgb * 0.09; + rgb += tex2D(_MainTex, saturate(uv - stepUv * 3.0)).rgb * 0.09; + rgb += tex2D(_MainTex, saturate(uv + stepUv * 4.0)).rgb * 0.05; + rgb += tex2D(_MainTex, saturate(uv - stepUv * 4.0)).rgb * 0.05; +#endif + return rgb; } fixed4 frag(v2f i) : SV_Target @@ -194,15 +193,18 @@ Shader "AIBIS/KiteFocusSprite" float2 texel = max(abs(_MainTex_TexelSize.xy), float2(1e-5, 1e-5)); float radius = (length(texel) * 0.5 + _BlurSize) * (0.28 + blurAmt * 1.72); - if (_UseSoftFocus > 0.5) + if (_UseGaussianBlur > 0.5) { - half4 softBlurred = SoftFocusBlur(i.uv, radius); - half4 softSharp = sharp; - softSharp.rgb *= softSharp.a; - half4 softColor = lerp(softSharp, softBlurred, smoothstep(0.0, 1.0, blurAmt)); - softColor.rgb *= i.color.rgb * i.color.a; - softColor.a *= i.color.a; - return softColor; + float stepSize = length(texel) + _BlurSize; + half3 blurredRgb = EyeGaussianBlurRgb(i.uv, stepSize); + float blurStrength = pow(blurAmt, 0.75); + half4 sharpPremul = sharp; + sharpPremul.rgb *= sharpPremul.a; + half4 gaussianColor = half4(blurredRgb * sharp.a, sharp.a); + gaussianColor = lerp(sharpPremul, gaussianColor, blurStrength); + gaussianColor.rgb *= i.color.rgb * i.color.a; + gaussianColor.a *= i.color.a; + return gaussianColor; } half4 disc = ApertureDisc(i.uv, radius); diff --git a/Assets/Scenes/梦境.unity b/Assets/Scenes/梦境.unity index 52020e336..ab91f0c68 100644 --- a/Assets/Scenes/梦境.unity +++ b/Assets/Scenes/梦境.unity @@ -424,19 +424,18 @@ MonoBehaviour: initialBlur: 0.58 blurSize: 0.0045 firstAttemptStart: 0.45 - firstFocusDuration: 0.72 + firstFocusDuration: 0.82 firstNearFocusBlur: 0.16 - firstHoldDuration: 0.1 - firstSlipDuration: 0.42 + firstHoldDuration: 0.12 + firstSlipDuration: 0.48 firstSlipBlur: 0.52 - secondAttemptStart: 1.85 - secondFocusDuration: 0.82 + secondAttemptStart: 2 + secondFocusDuration: 0.92 secondNearFocusBlur: 0.08 - secondHoldDuration: 0.12 - secondSlipDuration: 0.5 + secondHoldDuration: 0.14 + secondSlipDuration: 0.58 unresolvedBlur: 0.44 - blurFadeStart: 4 - blurFadeDuration: 3.2 + descentStart: 4 --- !u!1 &218986882 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/SceneManagement/TimelineKit/StarfieldDefocusController.cs b/Assets/Scripts/SceneManagement/TimelineKit/StarfieldDefocusController.cs index 747efc7e9..389fc9f00 100644 --- a/Assets/Scripts/SceneManagement/TimelineKit/StarfieldDefocusController.cs +++ b/Assets/Scripts/SceneManagement/TimelineKit/StarfieldDefocusController.cs @@ -7,14 +7,14 @@ namespace AibisDream { /// /// Drives the deliberately unsuccessful focus pulls at the start of the - /// starfield-to-sea Timeline. The effect is evaluated from Timeline time so - /// pausing, frame drops and repeated playback remain deterministic. + /// starfield-to-sea Timeline and keeps the starfield defocused until the + /// Timeline reaches the sea. /// public sealed class StarfieldDefocusController : MonoBehaviour { private static readonly int BlurAmountId = Shader.PropertyToID("_BlurAmount"); private static readonly int BlurSizeId = Shader.PropertyToID("_BlurSize"); - private static readonly int UseSoftFocusId = Shader.PropertyToID("_UseSoftFocus"); + private static readonly int UseGaussianBlurId = Shader.PropertyToID("_UseGaussianBlur"); [Header("References")] [SerializeField] private PlayableDirector director; @@ -30,36 +30,34 @@ namespace AibisDream [Min(0f)] [SerializeField] private float firstAttemptStart = 0.45f; [Min(0.01f)] - [SerializeField] private float firstFocusDuration = 0.48f; + [SerializeField] private float firstFocusDuration = 0.82f; [Range(0f, 1f)] [SerializeField] private float firstNearFocusBlur = 0.38f; [Min(0f)] - [SerializeField] private float firstHoldDuration = 0.14f; + [SerializeField] private float firstHoldDuration = 0.12f; [Min(0.01f)] - [SerializeField] private float firstSlipDuration = 0.38f; + [SerializeField] private float firstSlipDuration = 0.48f; [Range(0f, 1f)] [SerializeField] private float firstSlipBlur = 0.72f; [Header("Focus Attempt 2")] [Min(0f)] - [SerializeField] private float secondAttemptStart = 1.72f; + [SerializeField] private float secondAttemptStart = 2f; [Min(0.01f)] - [SerializeField] private float secondFocusDuration = 0.55f; + [SerializeField] private float secondFocusDuration = 0.92f; [Range(0f, 1f)] [SerializeField] private float secondNearFocusBlur = 0.28f; [Min(0f)] - [SerializeField] private float secondHoldDuration = 0.18f; + [SerializeField] private float secondHoldDuration = 0.14f; [Min(0.01f)] - [SerializeField] private float secondSlipDuration = 0.46f; + [SerializeField] private float secondSlipDuration = 0.58f; [Range(0f, 1f)] [SerializeField] private float unresolvedBlur = 0.62f; [Header("Downward Pan")] [Tooltip("Timeline time at which the starfield starts moving down toward the sea.")] [Min(0f)] - [SerializeField] private float blurFadeStart = 4f; - [Min(0.01f)] - [SerializeField] private float blurFadeDuration = 3.2f; + [SerializeField] private float descentStart = 4f; private MaterialPropertyBlock propertyBlock; @@ -160,7 +158,7 @@ namespace AibisDream } director.Pause(); - SetTimelineTime(blurFadeStart); + SetTimelineTime(descentStart); director.Play(); while (director.state == PlayState.Playing) @@ -248,7 +246,7 @@ namespace AibisDream starfieldRenderer.GetPropertyBlock(propertyBlock); propertyBlock.SetFloat(BlurAmountId, EvaluateBlur(time)); propertyBlock.SetFloat(BlurSizeId, blurSize); - propertyBlock.SetFloat(UseSoftFocusId, 1f); + propertyBlock.SetFloat(UseGaussianBlurId, 1f); starfieldRenderer.SetPropertyBlock(propertyBlock); } @@ -308,12 +306,7 @@ namespace AibisDream return SmoothLerp(secondNearFocusBlur, unresolvedBlur, InverseLerp(secondHoldEnd, secondSlipEnd, time)); } - if (time < blurFadeStart) - { - return unresolvedBlur; - } - - return SmoothLerp(unresolvedBlur, 0f, InverseLerp(blurFadeStart, blurFadeStart + blurFadeDuration, time)); + return unresolvedBlur; } ///