1 Shader "Hidden/PostProcessing/Lut2DBaker"
6 #include "../StdLib.hlsl"
7 #include "../Colors.hlsl"
8 #include "../ACES.hlsl"
10 TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
12 float4 _UserLut2D_Params;
17 float _Brightness; // LDR only
19 float3 _ChannelMixerRed;
20 float3 _ChannelMixerGreen;
21 float3 _ChannelMixerBlue;
27 TEXTURE2D_SAMPLER2D(_Curves, sampler_Curves);
29 float4 _CustomToneCurve;
37 float3 ApplyCommonGradingSteps(float3 colorLinear)
39 colorLinear = WhiteBalance(colorLinear, _ColorBalance);
40 colorLinear *= _ColorFilter;
41 colorLinear = ChannelMixer(colorLinear, _ChannelMixerRed, _ChannelMixerGreen, _ChannelMixerBlue);
42 colorLinear = LiftGammaGainHDR(colorLinear, _Lift, _InvGamma, _Gain);
44 // Do NOT feed negative values to RgbToHsv or they'll wrap around
45 colorLinear = max((float3)0.0, colorLinear);
47 float3 hsv = RgbToHsv(colorLinear);
51 satMult = saturate(SAMPLE_TEXTURE2D_LOD(_Curves, sampler_Curves, float2(hsv.x, 0.25), 0).y) * 2.0;
54 satMult *= saturate(SAMPLE_TEXTURE2D_LOD(_Curves, sampler_Curves, float2(hsv.y, 0.25), 0).z) * 2.0;
57 satMult *= saturate(SAMPLE_TEXTURE2D_LOD(_Curves, sampler_Curves, float2(Luminance(colorLinear), 0.25), 0).w) * 2.0;
60 float hue = hsv.x + _HueSatCon.x;
61 float offset = saturate(SAMPLE_TEXTURE2D_LOD(_Curves, sampler_Curves, float2(hue, 0.25), 0).x) - 0.5;
63 hsv.x = RotateHue(hue, 0.0, 1.0);
65 colorLinear = HsvToRgb(hsv);
66 colorLinear = Saturation(colorLinear, _HueSatCon.y * satMult);
72 // LDR Grading process
74 float3 ColorGradeLDR(float3 colorLinear)
76 // Brightness is a simple linear multiplier. Works better in LDR than using e.v.
77 colorLinear *= _Brightness;
79 // Contrast is done in linear, switching to log for that in LDR is pointless and doesn't
80 // feel as good to tweak
81 const float kMidGrey = pow(0.5, 2.2);
82 colorLinear = Contrast(colorLinear, kMidGrey, _HueSatCon.z);
84 colorLinear = ApplyCommonGradingSteps(colorLinear);
86 // YRGB only works in LDR for now as we don't do any curve range remapping
87 colorLinear = YrgbCurve(saturate(colorLinear), TEXTURE2D_PARAM(_Curves, sampler_Curves));
89 return saturate(colorLinear);
92 float4 FragLDRFromScratch(VaryingsDefault i) : SV_Target
94 float3 colorLinear = GetLutStripValue(i.texcoordStereo, _Lut2D_Params);
95 float3 graded = ColorGradeLDR(colorLinear);
96 return float4(graded, 1.0);
99 float4 FragLDR(VaryingsDefault i) : SV_Target
101 // Note: user luts may not have the same size as the internal one
102 float3 neutralColorLinear = GetLutStripValue(i.texcoordStereo, _Lut2D_Params);
103 float3 lookup = ApplyLut2D(TEXTURE2D_PARAM(_MainTex, sampler_MainTex), neutralColorLinear, _UserLut2D_Params.xyz);
104 float3 colorLinear = lerp(neutralColorLinear, lookup, _UserLut2D_Params.w);
105 float3 graded = ColorGradeLDR(colorLinear);
106 return float4(graded, 1.0);
110 // HDR Grading process
112 float3 LogGradeHDR(float3 colorLog)
114 // HDR contrast feels a lot more natural when done in log rather than doing it in linear
115 colorLog = Contrast(colorLog, ACEScc_MIDGRAY, _HueSatCon.z);
119 float3 LinearGradeHDR(float3 colorLinear)
121 colorLinear = ApplyCommonGradingSteps(colorLinear);
125 float3 ColorGradeHDR(float3 colorLutSpace)
129 float3 colorLinear = LUT_SPACE_DECODE(colorLutSpace);
130 float3 aces = unity_to_ACES(colorLinear);
132 // ACEScc (log) space
133 float3 acescc = ACES_to_ACEScc(aces);
134 acescc = LogGradeHDR(acescc);
135 aces = ACEScc_to_ACES(acescc);
137 // ACEScg (linear) space
138 float3 acescg = ACES_to_ACEScg(aces);
139 acescg = LinearGradeHDR(acescg);
141 // Tonemap ODT(RRT(aces))
142 aces = ACEScg_to_ACES(acescg);
143 colorLinear = AcesTonemap(aces);
149 // colorLutSpace is already in log space
150 colorLutSpace = LogGradeHDR(colorLutSpace);
152 // Switch back to linear
153 float3 colorLinear = LUT_SPACE_DECODE(colorLutSpace);
154 colorLinear = LinearGradeHDR(colorLinear);
155 colorLinear = max(0.0, colorLinear);
158 #if TONEMAPPING_NEUTRAL
160 colorLinear = NeutralTonemap(colorLinear);
162 #elif TONEMAPPING_CUSTOM
164 colorLinear = CustomTonemap(
165 colorLinear, _CustomToneCurve.xyz,
166 _ToeSegmentA, _ToeSegmentB.xy,
167 _MidSegmentA, _MidSegmentB.xy,
168 _ShoSegmentA, _ShoSegmentB.xy
178 float4 FragHDR(VaryingsDefault i) : SV_Target
180 float3 colorLutSpace = GetLutStripValue(i.texcoord, _Lut2D_Params);
181 float3 graded = ColorGradeHDR(colorLutSpace);
182 return float4(max(graded, 0.0), 1.0);
189 Cull Off ZWrite Off ZTest Always
195 #pragma vertex VertDefault
196 #pragma fragment FragLDRFromScratch
205 #pragma vertex VertDefault
206 #pragma fragment FragLDR
215 #pragma vertex VertDefault
216 #pragma fragment FragHDR
217 #pragma multi_compile __ TONEMAPPING_ACES TONEMAPPING_NEUTRAL TONEMAPPING_CUSTOM