122 lines
4.5 KiB
Plaintext
122 lines
4.5 KiB
Plaintext
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
|
||
}
|
||
}
|
||
} |