Grease Pencil: Draw Tool: Improve random color value and saturation setting results

This makes the random vertex color brightness work on a relative basis.

Because humans see relative differences in brightness more then absolute
brightness, simple adding randomness to `Value` will cause dark colors to be
effected more heavily then light colors.

This also fixes a problem desaturated colors with becoming red after
saturation randomization.

Pull Request: https://projects.blender.org/blender/blender/pulls/107315
This commit is contained in:
Casey Bianco-Davis
2025-03-21 12:15:09 +01:00
committed by Falk David
parent ec149a919a
commit cdccc51b2e

View File

@@ -180,25 +180,41 @@ ColorGeometry4f randomize_color(const BrushGpencilSettings &settings,
}
float3 hsv;
rgb_to_hsv_v(color, hsv);
linearrgb_to_srgb_v3_v3(hsv, color);
rgb_to_hsv_v(hsv, hsv);
hsv += float3(random_hue * settings.random_hue,
random_saturation * settings.random_saturation,
random_value * settings.random_value);
hsv[0] += random_hue * settings.random_hue;
/* Wrap hue. */
if (hsv[0] > 1.0f) {
hsv[0] -= 1.0f;
}
else if (hsv[0] < 0.0f) {
hsv[0] += 1.0f;
}
const float absolute_brightness = hsv[2] + random_value * settings.random_value;
/*
* To match relative brightness we want the ratio of the original to modified Value to not
* depend on the brightness of the input Value, Exp is used because we need a function that
* is positive for all 'x' and has the property that 'f(-x) = 1/f(x)' this is so that
* we make the Value on average growth and shrink by the same amount. To detriment the rate
* of the Exponential we set slope to match addition for small random values at an arbitrary
* Base Value.
*/
constexpr float base_value = 0.5f;
const float relative_brightness = hsv[2] *
math::exp(random_value * settings.random_value / base_value);
/* Use the fourth power. */
const float blend_factor = math::pow(settings.random_value, 4.0f);
/* Use relative brightness at low randomness, and switch to absolute at high. */
hsv[2] = math::interpolate(relative_brightness, absolute_brightness, blend_factor);
/* Multiply by the current saturation to prevent grays from becoming red. */
hsv[1] += random_saturation * settings.random_saturation * 2.0f * hsv[1];
/* Wrap hue, clamp saturation and value. */
hsv[0] = math::fract(hsv[0]);
hsv[1] = math::clamp(hsv[1], 0.0f, 1.0f);
hsv[2] = math::clamp(hsv[2], 0.0f, 1.0f);
ColorGeometry4f random_color;
hsv_to_rgb_v(hsv, random_color);
srgb_to_linearrgb_v3_v3(random_color, random_color);
random_color.a = color.a;
return random_color;
}