
// 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.txtfloat 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];}