-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Color Threshold, Color Scheme, Cleanup. (#3)
* Add plasma preset. * Add color threshold node. * Update docs. Organic Noise : Remove scaling. * Add color scheme. Fea tweaks.
- Loading branch information
Showing
9 changed files
with
358 additions
and
290 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
// ColorScheme - Various schemes to convert a float grayscale map to color. | ||
// ColorScheme by Philippe Groarke | ||
// Copyright 2022 Philippe Groarke, All rights reserved. This file is licensed under Apache 2.0 license | ||
// https://github.com/ADN-DevTech/3dsMax-OSL-Shaders/blob/master/LICENSE.txt | ||
|
||
#include "D:\code\3dsmax-plugins\OSL\FeaOSL\fea.osl" | ||
|
||
#define degs30 0.0833333333333333 | ||
#define degs60 0.1666666666666667 | ||
|
||
// Given a hue and how many levels to output, | ||
// returns the closest multiple. | ||
float flattenize(int levels, float in_val) { | ||
if (!levels) { | ||
return in_val; | ||
} | ||
|
||
float multiple = 1.0 / float(levels); | ||
return ceil(in_val / multiple) * multiple; | ||
} | ||
|
||
shader ColorScheme | ||
[[ | ||
string help = | ||
"<h3>Color Scheme</h3>" | ||
"Various schemes to convert a float grayscale map to color.\n" | ||
"Expects values between [0, 1], clamps input." | ||
, | ||
string label = "Color Scheme" | ||
]] | ||
( | ||
float In = 0 | ||
[[ | ||
string label = "In", | ||
string help = "Input grayscale map, expects float.", | ||
]], | ||
|
||
int in_invert = 0 | ||
[[ | ||
string label = "Invert", | ||
string help = "Flips the input values, 1 becomes 0, 0 becomes 1.", | ||
int connectable = 0, | ||
string widget = "checkBox", | ||
]], | ||
|
||
// FEA_SPACER(0), | ||
|
||
int in_color_mode = 0 | ||
[[ | ||
string widget = "mapper", | ||
string label = "Color Mode", | ||
string options = | ||
"Simple Hue:0" | ||
"|Heat Map:1" | ||
"|Bright Burn:2" | ||
"|Complements:3" | ||
"|Analogous:4" | ||
"|Split-Complementary:5" | ||
"|Triad:6" | ||
"|Tetradic:7" | ||
"|Square:8" | ||
, | ||
string help = "The output 'Color' algorithm to use.", | ||
int connectable = 0, | ||
string packName = "Color Mode / Hue", | ||
]], | ||
|
||
float in_hue = 0 | ||
[[ | ||
string label = "Hue", | ||
string help = "Cycles through available hues.", | ||
// float min = 0, | ||
// float max = 1, | ||
string packName = "Color Mode / Hue", | ||
int widgetWidth = FEA_RPACK_W, | ||
]], | ||
|
||
FEA_SPACER(1), | ||
|
||
int in_step_amount = 6 | ||
[[ | ||
string label = "Step Amount", | ||
string help = "The number of steps to use for 'Flatten' and for 'Countour' settings.", | ||
int min = 2, | ||
int connectable = 0, | ||
]], | ||
|
||
|
||
int in_flatten = 0 | ||
[[ | ||
string label = "Flatten", | ||
string help = "Flatten colors to selected bands.", | ||
int connectable = 0, | ||
string widget = "checkBox", | ||
]], | ||
|
||
int in_contours = 0 | ||
[[ | ||
string label = "Contour", | ||
string help = "Draw contours / edges according to number of levels.", | ||
int connectable = 0, | ||
string widget = "checkBox", | ||
string packName = "Countour / Soft" | ||
]], | ||
|
||
int in_smooth_contours = 0 | ||
[[ | ||
string label = "Soften Contour", | ||
string help = "Soften edges of contour lines.", | ||
int connectable = 0, | ||
string widget = "checkBox", | ||
string packName = "Countour / Soft" | ||
]], | ||
|
||
float in_contour_width = 1.0 | ||
[[ | ||
string label = "Contour Width", | ||
string help = "The contour width.", | ||
int connectable = 0, | ||
float min = 0.0001, | ||
]], | ||
|
||
output color Out = 0 | ||
) | ||
{ | ||
float val = clamp(In, 0.0, 1.0); | ||
val = in_invert ? 1.0 - val : val; | ||
|
||
float hue = in_hue; | ||
float hsv_v = 1.0; | ||
|
||
if (in_contours && val != 0.0 && val != 1.0) { | ||
float c_multiple = 1.0 / float(in_step_amount); | ||
float c_mod = fmod(val, c_multiple); | ||
float c_width = in_contour_width * 0.01; | ||
|
||
if (in_smooth_contours) { | ||
float high_w = c_width * 2.0; | ||
hsv_v = smoothstep(c_width, high_w, c_mod); | ||
hsv_v -= smoothstep(c_multiple - high_w, c_multiple - c_width, c_mod); | ||
} else { | ||
if (c_mod < c_width || c_mod > c_multiple - c_width) { | ||
hsv_v = 0.0; | ||
} | ||
} | ||
} | ||
|
||
// Step | ||
if (in_flatten != 0) { | ||
val = flattenize(in_step_amount, val); | ||
} | ||
|
||
color out_col; | ||
if (in_color_mode == 0) { | ||
// hsv | ||
// float col = fmod(val + hue, 1); | ||
float col = val + hue; | ||
out_col = color("hsv", col, 1, hsv_v); | ||
} else if (in_color_mode == 1) { | ||
// heat map | ||
float offset = 0.5 + degs60 + hue; | ||
float col = offset + val * 0.5; | ||
out_col = color("hsv", col, 1, hsv_v); | ||
} else if (in_color_mode == 2) { | ||
// bright burn | ||
float g = 0.618033988749895; | ||
float col = val * 0.569 + g + hue; | ||
float s = 1.0 - val; | ||
|
||
if (in_flatten) { | ||
s = flattenize(in_step_amount, s); | ||
} | ||
|
||
out_col = color("hsv", col, s, hsv_v); | ||
} else if (in_color_mode == 3) { | ||
// complements | ||
color start_col = color("hsv", hue, 1, hsv_v); | ||
color end_col = color("hsv", 0.5 + hue, 1, hsv_v); | ||
out_col = mix(start_col, end_col, val); | ||
} else if (in_color_mode == 4) { | ||
// analogous | ||
float col = fmod(val * degs60 + hue, 1) ; | ||
out_col = color("hsv", col, 1, hsv_v); | ||
} else if (in_color_mode == 5) { | ||
// split complementary | ||
color c1 = color("hsv", hue, 1, hsv_v); | ||
color c2 = color("hsv", 0.5 + degs30 + hue, 1, hsv_v); | ||
color c3 = color("hsv", 0.5 - degs30 + hue, 1, hsv_v); | ||
out_col = fea_mix(c1, c2, c3, val); | ||
} else if (in_color_mode == 6) { | ||
// triad | ||
color c1 = color("hsv", hue, 1, hsv_v); | ||
color c2 = color("hsv", 0.25 + degs30 + hue, 1, hsv_v); | ||
color c3 = color("hsv", 0.75 - degs30 + hue, 1, hsv_v); | ||
out_col = fea_mix(c1, c3, c2, val); | ||
} else if (in_color_mode == 7) { | ||
// tetradic | ||
color c1 = color("hsv", (1 / 12.0) + hue, 1, hsv_v); | ||
color c2 = color("hsv", 0.5 - degs30 + hue, 1, hsv_v); | ||
color c3 = color("hsv", 0.5 + degs30 + hue, 1, hsv_v); | ||
color c4 = color("hsv", 1.0 - degs30 + hue, 1, hsv_v); | ||
out_col = fea_mix(c1, c4, c2, c3, val); | ||
} else if (in_color_mode == 8) { | ||
// square | ||
color c1 = color("hsv", hue, 1, hsv_v); | ||
color c2 = color("hsv", 0.25 + hue, 1, hsv_v); | ||
color c3 = color("hsv", 0.5 + hue, 1, hsv_v); | ||
color c4 = color("hsv", 0.75 + hue, 1, hsv_v); | ||
out_col = fea_mix(c1, c3, c4, c2, val); | ||
} | ||
|
||
Out = out_col; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// ColorThreshold Shader | ||
// ColorThreshold by Philippe Groarke | ||
// Copyright 2022 Philippe Groarke, All rights reserved. This file is licensed under Apache 2.0 license | ||
// https://github.com/ADN-DevTech/3dsMax-OSL-Shaders/blob/master/LICENSE.txt | ||
|
||
#include "D:\code\3dsmax-plugins\OSL\FeaOSL\fea.osl" | ||
|
||
#define color_passthrough_opts \ | ||
"None:0" \ | ||
"|Above Intensity:1" \ | ||
"|Below Intensity:2" \ | ||
"|Pick Intensity:3" \ | ||
"|Pick Color:4" | ||
|
||
color color_passthrough(int mode, color source, color threshold, float pick_range, color mask) { | ||
color ret = source; | ||
if (mode == 0) { | ||
return ret; | ||
} | ||
|
||
float avg_source = fea_average(source); | ||
float avg_thresh = fea_average(threshold); | ||
|
||
if (mode == 1) { | ||
ret = avg_source >= avg_thresh ? source : mask; | ||
} else if (mode == 2) { | ||
ret = avg_source <= avg_thresh ? source : mask; | ||
} else if (mode == 3) { | ||
ret = abs(avg_source - avg_thresh) < pick_range ? source : mask; | ||
} else if (mode == 4) { | ||
color diff = abs(source - threshold); | ||
ret = diff[0] < pick_range && diff[1] < pick_range && diff[2] < pick_range ? source : mask; | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
shader ColorThreshold | ||
[[ | ||
string help = | ||
"<h3>Color Threshold</h3>" | ||
"Filter or pick colors from input. Mask the rest." | ||
, | ||
string label = "Color Threshold" | ||
]] | ||
( | ||
int in_mode = 0 | ||
[[ | ||
string widget = "mapper", | ||
string label = "Mode", | ||
string options = | ||
color_passthrough_opts | ||
, | ||
string help = "Filter mode.", | ||
int connectable = 0, | ||
]], | ||
|
||
float in_pick_range = 0.02 | ||
[[ | ||
string label = "Pick Range", | ||
string help = "The +/- range with which to pick intensities or colors. The higher the value, the wider the range picked.", | ||
float min = 0.0, | ||
float max = 0.5, | ||
int connectable = 0, | ||
]], | ||
|
||
color in_source = 1.0 | ||
[[ | ||
string label = "Source", | ||
string help = "The input color to filter.", | ||
]], | ||
|
||
color in_threshold = 0.0 | ||
[[ | ||
string label = "Target", | ||
string help = "Either the threshold value or the target intensity/color for pick mode.\nWarning : When using the color picker in the viewport, the actual result will be shaded and usually incorrect. You can use the color picker on a material's preview in the SME graph to get a non-shaded source color.", | ||
]], | ||
|
||
color in_mask = 1.0 | ||
[[ | ||
string label = "Mask", | ||
string help = "When the condition is true, the replacement color.", | ||
]], | ||
|
||
output color Out = 0 | ||
) | ||
{ | ||
Out = color_passthrough(in_mode, in_source, in_threshold, in_pick_range, in_mask); | ||
} |
Oops, something went wrong.