Shader "SLS/Postprocessing/AdvancedChromaticAberration" { SubShader { Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" } ZWrite Off Cull Off HLSLINCLUDE #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl" // --- 参数定义 --- float4 _ACA_Params1; // x: Intensity (总强度) // y: Center X // z: Center Y // w: Mask Radius (中心保留半径) float4 _ACA_Params2; // x: Jitter Intensity // y: Jitter Speed // z: Dispersion Map Strength (贴图影响力度) // w: Mask Hardness (边缘硬度) float4 _ACA_Split; // x: R权重, y: G权重, z: B权重 // 纹理 TEXTURE2D(_DispersionMap); SAMPLER(sampler_DispersionMap); // 建议设置为 Repeat 模式 // --- 辅助函数 --- // 简单的伪随机函数 (0-1) float random(float2 uv) { return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453123); } half4 Frag(Varyings input) : SV_Target { float2 uv = input.texcoord; // 1. 参数解包 float intensity = _ACA_Params1.x; float2 center = _ACA_Params1.yz; float maskRadius = _ACA_Params1.w; float jitterAmount = _ACA_Params2.x; float jitterSpeed = _ACA_Params2.y; float mapStrength = _ACA_Params2.z; float maskHardness = _ACA_Params2.w; float3 splitWeights = _ACA_Split.rgb; // 2. 计算基础方向向量 (径向) float2 dir = uv - center; float dist = length(dir); // 3. 计算中心遮罩 (Vignette Mask) // 距离小于 Radius 的地方强度为 0,向外渐变 float mask = smoothstep(maskRadius, maskRadius + maskHardness, dist); // 如果在遮罩内,直接返回原图,节省性能 // (为了 Jitter 的连贯性,这里我们只把 mask 乘到 offset 上,不直接 return) // 4. 计算 Jitter (采样抖动) // 利用 Time 和 UV 做随机,模拟不稳定的信号 float timeVal = _Time.y * jitterSpeed; // 这里的 floor 模拟“跳动”的帧率感,如果想要平滑 jitter 可以去掉 floor float2 jitterUV = uv + float2(random(uv + timeVal), random(uv - timeVal)) * 0.1; float2 jitterOffset = (float2(random(jitterUV), random(jitterUV * 1.5)) - 0.5) * 2.0; // -1 ~ 1 jitterOffset *= jitterAmount * 0.05; // 缩放幅度 // 5. 采样 Dispersion Map (破碎感) // 让贴图随时间缓慢流动一点点,或者固定 float4 noiseTex = SAMPLE_TEXTURE2D(_DispersionMap, sampler_DispersionMap, uv * 3.0 + jitterOffset); // 缩放 UV float noiseFactor = noiseTex.r * 2.0 - 1.0; // -1 ~ 1 // 混合 Map 影响 // 如果 mapStrength 为 0,则 noiseFactor 为 0 (不影响),我们希望默认为 1 float finalNoise = lerp(1.0, noiseFactor, mapStrength); // 6. 组合最终偏移量 // 基础方向 * (1 + 噪声) + 抖动 float2 finalOffset = dir * finalNoise; // 加上纯粹的位置抖动 (不依赖方向) finalOffset += jitterOffset; // 应用遮罩和总强度 finalOffset *= mask * intensity; // 7. 分离通道采样 // 注意:URP 的 _BlitTexture 采样时最好 Clamp,防止边缘溢出 float2 uvR = uv - finalOffset * splitWeights.r; float2 uvG = uv - finalOffset * splitWeights.g; float2 uvB = uv - finalOffset * splitWeights.b; half r = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uvR).r; half g = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uvG).g; half b = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uvB).b; // 8. 重新组合 return half4(r, g, b, 1.0); } ENDHLSL Pass { Name "Advanced Chromatic Aberration" HLSLPROGRAM #pragma vertex Vert #pragma fragment Frag ENDHLSL } } }