LutGen.shader
3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
Shader "Hidden/Post FX/Lut Generator"
{
CGINCLUDE
#pragma target 3.0
#pragma multi_compile __ TONEMAPPING_NEUTRAL TONEMAPPING_FILMIC
#include "UnityCG.cginc"
#include "ACES.cginc"
#include "Common.cginc"
#include "ColorGrading.cginc"
#include "Tonemapping.cginc"
half3 _Balance;
half3 _Lift;
half3 _InvGamma;
half3 _Gain;
half3 _Offset;
half3 _Power;
half3 _Slope;
half _HueShift;
half _Saturation;
half _Contrast;
half3 _ChannelMixerRed;
half3 _ChannelMixerGreen;
half3 _ChannelMixerBlue;
half4 _NeutralTonemapperParams1;
half4 _NeutralTonemapperParams2;
sampler2D _Curves;
half4 _LutParams;
half3 ColorGrade(half3 color)
{
half3 aces = unity_to_ACES(color);
// ACEScc (log) space
half3 acescc = ACES_to_ACEScc(aces);
acescc = OffsetPowerSlope(acescc, _Offset, _Power, _Slope);
half2 hs = RgbToHsv(acescc).xy;
half satMultiplier = SecondaryHueSat(hs.x, _Curves);
satMultiplier *= SecondarySatSat(hs.y, _Curves);
satMultiplier *= SecondaryLumSat(AcesLuminance(acescc), _Curves);
acescc = Saturation(acescc, _Saturation * satMultiplier);
acescc = ContrastLog(acescc, _Contrast);
aces = ACEScc_to_ACES(acescc);
// ACEScg (linear) space
half3 acescg = ACES_to_ACEScg(aces);
acescg = WhiteBalance(acescg, _Balance);
acescg = LiftGammaGain(acescg, _Lift, _InvGamma, _Gain);
half3 hsv = RgbToHsv(max(acescg, 0.0));
hsv.x = SecondaryHueHue(hsv.x + _HueShift, _Curves);
acescg = HsvToRgb(hsv);
acescg = ChannelMixer(acescg, _ChannelMixerRed, _ChannelMixerGreen, _ChannelMixerBlue);
#if TONEMAPPING_FILMIC
aces = ACEScg_to_ACES(acescg);
color = FilmicTonemap(aces);
#elif TONEMAPPING_NEUTRAL
color = ACEScg_to_unity(acescg);
color = NeutralTonemap(color, _NeutralTonemapperParams1, _NeutralTonemapperParams2);
#else
color = ACEScg_to_unity(acescg);
#endif
// YRGB curves (done in linear/LDR for now)
color = YrgbCurve(color, _Curves);
return color;
}
half4 FragCreateLut(VaryingsDefault i) : SV_Target
{
// 2D strip lut
half2 uv = i.uv - _LutParams.yz;
half3 color;
color.r = frac(uv.x * _LutParams.x);
color.b = uv.x - color.r / _LutParams.x;
color.g = uv.y;
// Lut is in LogC
half3 colorLogC = color * _LutParams.w;
// Switch back to unity linear and color grade
half3 colorLinear = LogCToLinear(colorLogC);
half3 graded = ColorGrade(colorLinear);
return half4(graded, 1.0);
}
ENDCG
SubShader
{
Cull Off ZWrite Off ZTest Always
// (0)
Pass
{
CGPROGRAM
#pragma vertex VertDefault
#pragma fragment FragCreateLut
ENDCG
}
}
}