| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- Shader "Hidden/PostProcessing/Lut2DBaker"
- {
- HLSLINCLUDE
- #pragma target 3.0
- #include "../StdLib.hlsl"
- #include "../Colors.hlsl"
- #include "../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
- }
- }
- }
|