Files
SoulliesOfficial aee62cd637 大修
2026-03-14 02:30:26 -04:00

109 lines
3.6 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Shader "SLS/Postprocessing/AnimeACES"
{
SubShader
{
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
}
ZWrite Off
Cull Off
ZTest Always
Pass
{
Name "Anime ACES Tonemapping"
Blend Off // 强制覆盖
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
// --- 参数定义 ---
float4 _TonemapParams;
// x: Exposure
// y: Contrast
// z: Saturation
// w: Hue Preservation (新增:色彩保留强度 0-1)
float4 _ACESCoeffs;
// x: A, y: B, z: C, w: D
float _ACES_E; // E
float4 _ColorFilter;
// Narkowicz ACES 曲线
float3 ACESCurve(float3 x)
{
float a = _ACESCoeffs.x;
float b = _ACESCoeffs.y;
float c = _ACESCoeffs.z;
float d = _ACESCoeffs.w;
float e = _ACES_E;
return saturate((x * (a * x + b)) / (x * (c * x + d) + e));
}
// 标量版本
float ACESCurve(float x)
{
float a = _ACESCoeffs.x;
float b = _ACESCoeffs.y;
float c = _ACESCoeffs.z;
float d = _ACESCoeffs.w;
float e = _ACES_E;
return saturate((x * (a * x + b)) / (x * (c * x + d) + e));
}
half4 Frag(Varyings input) : SV_Target
{
float2 uv = input.texcoord;
half4 sceneColor = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv);
half3 color = sceneColor.rgb;
// 1. Exposure (曝光)
color *= _TonemapParams.x;
// 2. Contrast (对比度) - 【核心修正】
// Pivot 从 0.5 改为 0.18 (Linear Middle Gray)
// 这样增加对比度会压暗阴影,而不是提亮阴影
float midGray = 0.18;
color = (color - midGray) * _TonemapParams.y + midGray;
color = max(0, color);
// 3. ACES Tonemapping with Hue Preservation (色彩保留) - 【核心修正】
float huePreserve = _TonemapParams.w;
// A. 标准 ACES (会吃色RGB 通道独立压缩)
float3 acesFit = ACESCurve(color);
// B. 亮度 ACES (不吃色,只压缩亮度)
float lum = Luminance(color);
float lumTonemapped = ACESCurve(lum);
// 重建颜色:保持原色相,只改变亮度
float3 colorPreserved = color * (lumTonemapped / max(lum, 1e-4));
// 混合两者:二次元通常希望皮肤保色(B),但场景光影有电影感(A)
// 建议 Hue Preservation 设为 0.5 左右
color = lerp(acesFit, colorPreserved, huePreserve);
// 4. Saturation (饱和度)
// 重新计算亮度进行饱和度调整
float finalLum = Luminance(color);
color = lerp(finalLum.xxx, color, _TonemapParams.z);
// 5. Color Filter
color *= _ColorFilter.rgb;
return half4(color, sceneColor.a);
}
ENDHLSL
}
}
}