Firstborn/Library/PackageCache/com.unity.postprocessing@3.2.2/PostProcessing/Shaders/Builtins/Lut2DBaker.shader

223 lines
7.1 KiB
Plaintext
Raw Normal View History

2023-03-28 13:24:16 -04:00
Shader "Hidden/PostProcessing/Lut2DBaker"
{
HLSLINCLUDE
#pragma target 3.0
#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/StdLib.hlsl"
#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/Colors.hlsl"
#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/ACES.hlsl"
TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
float4 _Lut2D_Params;
float4 _UserLut2D_Params;
float3 _ColorBalance;
float3 _ColorFilter;
float3 _HueSatCon;
float _Brightness; // LDR only
float3 _ChannelMixerRed;
float3 _ChannelMixerGreen;
float3 _ChannelMixerBlue;
float3 _Lift;
float3 _InvGamma;
float3 _Gain;
TEXTURE2D_SAMPLER2D(_Curves, sampler_Curves);
float4 _CustomToneCurve;
float4 _ToeSegmentA;
float4 _ToeSegmentB;
float4 _MidSegmentA;
float4 _MidSegmentB;
float4 _ShoSegmentA;
float4 _ShoSegmentB;
float3 ApplyCommonGradingSteps(float3 colorLinear)
{
colorLinear = WhiteBalance(colorLinear, _ColorBalance);
colorLinear *= _ColorFilter;
colorLinear = ChannelMixer(colorLinear, _ChannelMixerRed, _ChannelMixerGreen, _ChannelMixerBlue);
colorLinear = LiftGammaGainHDR(colorLinear, _Lift, _InvGamma, _Gain);
// Do NOT feed negative values to RgbToHsv or they'll wrap around
colorLinear = max((float3)0.0, colorLinear);
float3 hsv = RgbToHsv(colorLinear);
// Hue Vs Sat
float satMult;
satMult = saturate(SAMPLE_TEXTURE2D_LOD(_Curves, sampler_Curves, float2(hsv.x, 0.25), 0).y) * 2.0;
// Sat Vs Sat
satMult *= saturate(SAMPLE_TEXTURE2D_LOD(_Curves, sampler_Curves, float2(hsv.y, 0.25), 0).z) * 2.0;
// Lum Vs Sat
satMult *= saturate(SAMPLE_TEXTURE2D_LOD(_Curves, sampler_Curves, float2(Luminance(colorLinear), 0.25), 0).w) * 2.0;
// Hue Vs Hue
float hue = hsv.x + _HueSatCon.x;
float offset = saturate(SAMPLE_TEXTURE2D_LOD(_Curves, sampler_Curves, float2(hue, 0.25), 0).x) - 0.5;
hue += offset;
hsv.x = RotateHue(hue, 0.0, 1.0);
colorLinear = HsvToRgb(hsv);
colorLinear = Saturation(colorLinear, _HueSatCon.y * satMult);
return colorLinear;
}
//
// LDR Grading process
//
float3 ColorGradeLDR(float3 colorLinear)
{
// Brightness is a simple linear multiplier. Works better in LDR than using e.v.
colorLinear *= _Brightness;
// Contrast is done in linear, switching to log for that in LDR is pointless and doesn't
// feel as good to tweak
const float kMidGrey = pow(0.5, 2.2);
colorLinear = Contrast(colorLinear, kMidGrey, _HueSatCon.z);
colorLinear = ApplyCommonGradingSteps(colorLinear);
// YRGB only works in LDR for now as we don't do any curve range remapping
colorLinear = YrgbCurve(saturate(colorLinear), TEXTURE2D_PARAM(_Curves, sampler_Curves));
return saturate(colorLinear);
}
float4 FragLDRFromScratch(VaryingsDefault i) : SV_Target
{
float3 colorLinear = GetLutStripValue(i.texcoordStereo, _Lut2D_Params);
float3 graded = ColorGradeLDR(colorLinear);
return float4(graded, 1.0);
}
float4 FragLDR(VaryingsDefault i) : SV_Target
{
// Note: user luts may not have the same size as the internal one
float3 neutralColorLinear = GetLutStripValue(i.texcoordStereo, _Lut2D_Params);
float3 lookup = ApplyLut2D(TEXTURE2D_PARAM(_MainTex, sampler_MainTex), neutralColorLinear, _UserLut2D_Params.xyz);
float3 colorLinear = lerp(neutralColorLinear, lookup, _UserLut2D_Params.w);
float3 graded = ColorGradeLDR(colorLinear);
return float4(graded, 1.0);
}
//
// HDR Grading process
//
float3 LogGradeHDR(float3 colorLog)
{
// HDR contrast feels a lot more natural when done in log rather than doing it in linear
colorLog = Contrast(colorLog, ACEScc_MIDGRAY, _HueSatCon.z);
return colorLog;
}
float3 LinearGradeHDR(float3 colorLinear)
{
colorLinear = ApplyCommonGradingSteps(colorLinear);
return colorLinear;
}
float3 ColorGradeHDR(float3 colorLutSpace)
{
#if TONEMAPPING_ACES
{
float3 colorLinear = LUT_SPACE_DECODE(colorLutSpace);
float3 aces = unity_to_ACES(colorLinear);
// ACEScc (log) space
float3 acescc = ACES_to_ACEScc(aces);
acescc = LogGradeHDR(acescc);
aces = ACEScc_to_ACES(acescc);
// ACEScg (linear) space
float3 acescg = ACES_to_ACEScg(aces);
acescg = LinearGradeHDR(acescg);
// Tonemap ODT(RRT(aces))
aces = ACEScg_to_ACES(acescg);
colorLinear = AcesTonemap(aces);
return colorLinear;
}
#else
{
// colorLutSpace is already in log space
colorLutSpace = LogGradeHDR(colorLutSpace);
// Switch back to linear
float3 colorLinear = LUT_SPACE_DECODE(colorLutSpace);
colorLinear = LinearGradeHDR(colorLinear);
colorLinear = max(0.0, colorLinear);
// Tonemap
#if TONEMAPPING_NEUTRAL
{
colorLinear = NeutralTonemap(colorLinear);
}
#elif TONEMAPPING_CUSTOM
{
colorLinear = CustomTonemap(
colorLinear, _CustomToneCurve.xyz,
_ToeSegmentA, _ToeSegmentB.xy,
_MidSegmentA, _MidSegmentB.xy,
_ShoSegmentA, _ShoSegmentB.xy
);
}
#endif
return colorLinear;
}
#endif
}
float4 FragHDR(VaryingsDefault i) : SV_Target
{
float3 colorLutSpace = GetLutStripValue(i.texcoord, _Lut2D_Params);
float3 graded = ColorGradeHDR(colorLutSpace);
return float4(max(graded, 0.0), 1.0);
}
ENDHLSL
SubShader
{
Cull Off ZWrite Off ZTest Always
Pass
{
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment FragLDRFromScratch
ENDHLSL
}
Pass
{
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment FragLDR
ENDHLSL
}
Pass
{
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment FragHDR
#pragma multi_compile __ TONEMAPPING_ACES TONEMAPPING_NEUTRAL TONEMAPPING_CUSTOM
ENDHLSL
}
}
}