-
Notifications
You must be signed in to change notification settings - Fork 45
Expand file tree
/
Copy pathUberColorCorrect.osl
More file actions
191 lines (163 loc) · 6.71 KB
/
UberColorCorrect.osl
File metadata and controls
191 lines (163 loc) · 6.71 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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// Color Correction
// ColorCorrect.osl, by Zap Andersson
// Modified: 2021-12-20 by Saul Espinosa for Redshift 3D
// Removed Max UI specific options and added Page grouping Metadata
// Copyright 2020 Autodesk Inc, All rights reserved. This file is licensed under Apache 2.0 license
// https://github.com/ADN-DevTech/3dsMax-OSL-Shaders/blob/master/LICENSE.txt
float remap(color In, int mapping)
{
if (mapping < 3)
return In[mapping];
if (mapping < 6)
return 1.0 - In[mapping-3];
if (mapping == 6) return luminance(In);
if (mapping == 7) return 1.0 - luminance(In);
if (mapping == 8) return 0.0;
return 1.0;
}
shader UberColorCorrect
[[ string label = "Color Correction",
// string category = "Color Correction",
string version = "1.5" ]]
(
color Input = 0.18 [[string page = "Input"]],
int Bypass = 0 [[ string widget = "checkBox", string page = "Input" ]],
float Overall = 1.0 [[ float min = 0.0, float max = 1.0, string page = "Input" ]],
int HueRange = 0 [[ string widget = "checkBox", string page = "Hue Ranges" ]],
color AffectHue = color(1.0, 0.4, 0.3) [[string page = "Hue Ranges"]],
float HueRangeWidth = 10 [[ float min = 0.0, float max = 360, float step = 1.0, string page = "Hue Ranges" ]],
float HueRangeSoftness = 10 [[ float min = 0.0, float max = 360, float step = 1.0, string page = "Hue Ranges" ]],
int ChannelMapping = 0 [[ string widget = "checkBox", string page = "Channels" ]],
int RedMapping = 0
[[
int connectable = 0,
string page = "Channels",
string widget = "mapper",
string options =
"Red:0|Green:1|Blue:2|"
"Red (Inverse):3|Green (Inverse):4|Blue (Inverse):5|"
"Luminance:6|Luminance (Inverse):7|Zero:8|One:9" ]],
int GreenMapping = 1
[[ int connectable = 0,
string page = "Channels",
string widget = "mapper",
string options =
"Red:0|Green:1|Blue:2|"
"Red (Inverse):3|Green (Inverse):4|Blue (Inverse):5|"
"Luminance:6|Luminance (Inverse):7|Zero:8|One:9" ]],
int BlueMapping = 2
[[ int connectable = 0,
string page = "Channels",
string widget = "mapper",
string options =
"Red:0|Green:1|Blue:2|"
"Red (Inverse):3|Green (Inverse):4|Blue (Inverse):5|"
"Luminance:6|Luminance (Inverse):7|Zero:8|One:9" ]],
int BrightnessAdjustment = 1 [[ string widget = "checkBox", string page = "Value Adjustments" ]],
int Invert = 0 [[ string widget = "checkBox", int connectable=0, string page = "Value Adjustments" ]],
float Brightness = 1.0 [[string page = "Value Adjustments"]],
float Contrast = 1.0 [[string page = "Value Adjustments"]],
float Lift = 0.0 [[string page = "Value Adjustments"]],
float Pivot = 0.5 [[string page = "Value Adjustments"]],
int InverseGamma = 0 [[ string widget = "checkBox", int connectable=0, string page = "Value Adjustments" ]],
float Gamma = 1.0 [[string page = "Value Adjustments"]],
int ColorAdjustment = 0 [[ string widget = "checkBox", int connectable=0, string page = "Color Adjustments" ]],
float HueShift = 0.0 [[ float min = -1.0, float max = 1.0, string page = "Color Adjustments" ]],
float Saturation = 1.0 [[ float min = 0.0, float max = 10.0, string page = "Color Adjustments" ]],
color TintColor = 1.0 [[ string page = "Color Adjustments"]],
float TintStrength = 0.0 [[ float min = 0.0, float max = 1.0, string page = "Color Adjustments" ]],
int OutputTint = 0 [[ string widget = "checkBox", int connectable=0, string page = "Output Adjustments" ]],
color Shadows = 0.0 [[ string page = "Output Adjustments"]],
color Midtones = 0.2 [[ string page = "Output Adjustments"]],
color Highlights = 1.0 [[ string page = "Output Adjustments"]],
float MidtoneLum = 0.2 [[ float min = 0.0, float max = 1.0, string page = "Output Adjustments" ]],
int Clamp = 1 [[ string widget = "checkBox", int connectable=0, string page = "Output Clamp" ]],
float ClampLow = 0.0 [[string page = "Output Clamp"]],
float ClampHi = 1.0 [[string page = "Output Clamp"]],
// Outputs
output color Out = 0.0,
output float R = 0.0,
output float G = 0.0,
output float B = 0.0
)
{
float effect = Overall;
Out = Input;
if (!Bypass)
{
// Apply only to hue range
if (HueRange)
{
// Tramsform to HSV space
color hsv = transformc("rgb", "hsv", Input);
// Tramsform to HSV space
color hsv2 = transformc("rgb", "hsv", AffectHue);
float huedifference = fabs(hsv[0] - hsv2[0]);
// If distance in hue is larger than half
// the color wheel, measure the other way around
if (huedifference > 0.5)
huedifference = 1.0 - huedifference;
float HRW = HueRangeWidth / 360.0 / 2.0;
float HRS = HueRangeSoftness / 360.0;
// Are we outside the hue range? Then we need to modulate
// the effect value to apply the effect less (or not at all)
if (huedifference > HRW)
{
// Outside range - apply softness (if any)
if (HRS > 0.0)
effect *= smoothstep(0.0, 1.0, 1.0 - (huedifference - HRW) / HRS);
else
effect = 0.0; // No softness - just hard cut effect to zero
}
}
// Apply the channel mapping
if (ChannelMapping)
{
Out[0] = remap(Input, RedMapping);
Out[1] = remap(Input, GreenMapping);
Out[2] = remap(Input, BlueMapping);
}
// Brightness adjustment section
if (BrightnessAdjustment)
{
// Invert, if requested
if (Invert) Out = 1.0 - Out;
// Multiply by Brightness
Out = Out * Brightness;
// Scale around Pivot by Contrast
Out = ((Out - Pivot) * Contrast) + Pivot;
// Add Lift
Out = Out + Lift;
// Apply Gamma
if (Gamma != 1.0)
Out = pow(max(0.0, Out), InverseGamma?1.0/Gamma:Gamma);
}
// Color adjustment section
if (ColorAdjustment)
{
// Tramsform to HSV space
color hsv = transformc("rgb", "hsv", Out);
hsv[0] += HueShift;
hsv[1] *= Saturation;
// Convert back to RGB
Out = transformc("hsv", "rgb", hsv);
// Mix with tint color scaled by value
Out = mix(Out, TintColor * hsv[2], TintStrength);
}
// Output Tint Section
if (OutputTint)
{
color below = clamp((Out / MidtoneLum), 0.0, 1.0);
color above = clamp((Out - MidtoneLum) / (1.0 - MidtoneLum), 0.0, 1.0);
Out = mix(Shadows, mix(Midtones, Highlights, above), below);
}
if (Clamp)
Out = clamp(Out, ClampLow, ClampHi);
// Do the overall mix in of the effect
Out = mix(Input, Out, effect);
}
// Output individual channels for convenience
R = Out[0];
G = Out[1];
B = Out[2];
}