art(huoshan): 调整记忆shader表现

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-25 15:57:10 +08:00
co-authored by Cursor
parent 2c6ac3e142
commit 042785e3dc
2 changed files with 73 additions and 13 deletions
+3
View File
@@ -29,6 +29,9 @@ Material:
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AnalogChroma: 0.5
- _AnalogGlitch: 0.25
- _AnalogScale: 1.6
- _Brightness: 1
- _CalmFeather: 0.2
- _CalmRadius: 0
+70 -13
View File
@@ -21,6 +21,12 @@ Shader "AibisDream/HuoshanMemory"
_CalmFeather("Calm Feather", Range(0.001, 1)) = 0.2
_EffectStrength("Effect Strength", Range(0, 1)) = 0
_Opacity("Opacity", Range(0, 1)) = 0
// 屏幕故障(HuoshanScreenGlitch)的减弱版,只有三个旋钮,其余系数内部推导。
[Header(Analog Signal Layer)]
_AnalogGlitch("Analog Layer Amount", Range(0, 1)) = 0.25
_AnalogScale("Analog Scale", Range(0.25, 6)) = 1.6
_AnalogChroma("Analog Chroma Tint", Range(0, 2)) = 0.5
}
SubShader
@@ -87,6 +93,9 @@ Shader "AibisDream/HuoshanMemory"
float _CalmFeather;
float _EffectStrength;
float _Opacity;
float _AnalogGlitch;
float _AnalogScale;
float _AnalogChroma;
CBUFFER_END
float hash21(float2 p)
@@ -148,24 +157,24 @@ Shader "AibisDream/HuoshanMemory"
overdrive * 0.082;
sampleUV.x += tearDirection * tearGate * tearAmount * distortion;
// Subtle continuous UV wobble plus an occasional narrow-row slip.
sampleUV.x += sin((input.uv.y * 18.0 + _Time.y * 0.8) * 6.28318) * 0.0012 * sim;
sampleUV.y += sin((input.uv.x * 13.0 - _Time.y * 0.55) * 6.28318) * 0.0007 * sim;
float simSlot = floor(_Time.y * 0.9 + _TearSeed * 7.0);
float simGate = step(0.62, hash21(float2(simSlot, 3.7)));
// Persistent simulation wobble: light enough for ambient, readable on still frames.
sampleUV.x += sin((input.uv.y * 18.0 + _Time.y * 0.8) * 6.28318) * 0.0024 * sim;
sampleUV.y += sin((input.uv.x * 13.0 - _Time.y * 0.55) * 6.28318) * 0.0014 * sim;
float simSlot = floor(_Time.y * 1.15 + _TearSeed * 7.0);
float simGate = step(0.55, hash21(float2(simSlot, 3.7)));
float simRow = floor(input.uv.y * 34.0);
float simRowPick = step(0.90, hash21(float2(simRow + simSlot * 13.0, 11.3)));
float simRowPick = step(0.86, hash21(float2(simRow + simSlot * 13.0, 11.3)));
float simJitterDir = hash21(float2(simSlot * 1.37, simRow)) * 2.0 - 1.0;
sampleUV.x += simJitterDir * simGate * simRowPick * 0.0035 * sim;
sampleUV.x += simJitterDir * simGate * simRowPick * 0.0065 * sim;
sampleUV.y = (sampleUV.y - 0.5) *
(1.0 + impact * 0.016 + overdrive * 0.025) + 0.5;
(1.0 + impact * 0.016 + overdrive * 0.025 + sim * 0.008) + 0.5;
sampleUV = saturate(sampleUV);
half4 original = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv);
float chromaOffset =
(damage * 0.0035 + impact * 0.009 + overdrive * 0.016) *
lerp(0.35, 1.0, tearGate);
(damage * 0.0035 + impact * 0.009 + overdrive * 0.016 + sim * 0.0028) *
lerp(0.35, 1.0, max(tearGate, sim * 0.55));
half red = SAMPLE_TEXTURE2D(
_MainTex,
sampler_MainTex,
@@ -196,7 +205,7 @@ Shader "AibisDream/HuoshanMemory"
float noiseValue = hash21(floor(input.uv * float2(640, 360)) + floor(_Time.y * 24.0));
float signedNoise = (noiseValue - 0.5) *
(_Noise * effect + damage * 0.08 + overdrive * 0.16);
(_Noise * effect + damage * 0.08 + overdrive * 0.16 + sim * 0.045);
graded += signedNoise.xxx;
float dropoutRow = floor(input.uv.y * lerp(9.0, 21.0, overdrive));
@@ -210,8 +219,56 @@ Shader "AibisDream/HuoshanMemory"
hash21(float2(dropoutRow * 3.17, timeStep)));
graded *= lerp(1.0, dropoutLevel, dropoutGate * overdrive * 0.72);
// The simulation path only opens a light amount of grading/distortion.
float3 finalColor = lerp(original.rgb, graded, max(distortion, sim * 0.45));
// Simulation stays on the memory sprite itself — no external noise overlay.
float3 finalColor = lerp(original.rgb, graded, max(distortion, sim * 0.62));
// ── 轻量模拟信号层:和屏幕故障(HuoshanScreenGlitch)同源的减弱版,
// 只做轻微色偏 + 扫描线 + 颗粒,不改变画面结构。密度按屏幕像素计,
// 记忆图缩放到多大都是同一种颗粒度。Calm 区(要读字的地方)自动让位。
float analog = saturate(_AnalogGlitch) * (1.0 - calmMask * 0.85);
if (analog > 0.001)
{
float analogScale = max(0.25, _AnalogScale);
float analogRibbonPx = 90.0 * analogScale;
float analogScanPx = 8.0 * analogScale;
float analogGrainPx = 3.0 * analogScale;
float analogRowPx = 14.0 * analogScale;
float2 analogTexel = float2(
max(fwidth(input.uv.x), 1e-7),
max(fwidth(input.uv.y), 1e-7));
float2 analogPixel = input.uv / analogTexel;
float analogLuma = dot(finalColor, float3(0.299, 0.587, 0.114));
float analogRow = floor(analogPixel.y / analogRowPx);
float analogRowPhase =
(hash21(float2(analogRow, floor(_Time.y * 12.0))) - 0.5) * 1.4;
float analogRibbon =
analogPixel.x * 6.2831853 / analogRibbonPx
+ sin(input.uv.y * 12.0 + _Time.y * 1.3) * 1.8
+ analogRowPhase
- _Time.y * 1.6;
// 以 0 为中心:只染色不提亮,保证"轻轻叠一点点"。
float3 analogPhase = 6.2831853 * (
(analogLuma + sin(analogRibbon) * 0.35) * 1.1
+ float3(0.0, 1.0, 2.0) * 0.14
+ 0.62);
finalColor += 0.5 * cos(analogPhase)
* analog * _AnalogChroma * (0.5 + analogLuma);
float analogScanFade = saturate((analogScanPx - 1.6) / 1.4);
float analogScanWave =
0.5 + 0.5 * sin(analogPixel.y * 6.2831853 / analogScanPx);
finalColor *= lerp(1.0, analogScanWave,
saturate(0.35 * analog * analogScanFade));
float analogGrain = hash21(
floor(analogPixel / analogGrainPx)
+ floor(_Time.y * 24.0) * 0.137) - 0.5;
finalColor += analogGrain * 0.09 * analog;
}
return half4(
finalColor * input.color.rgb,