Add stroke alpha blend reference tests
This commit is contained in:
@@ -44,6 +44,67 @@ namespace {
|
||||
return stroke;
|
||||
}
|
||||
|
||||
[[nodiscard]] float blend_stroke_screen(float base, float stroke) noexcept
|
||||
{
|
||||
return base + stroke - (base * stroke);
|
||||
}
|
||||
|
||||
[[nodiscard]] float blend_stroke_hard_light(float base, float stroke) noexcept
|
||||
{
|
||||
return stroke < 0.5F
|
||||
? base * (stroke * 2.0F)
|
||||
: blend_stroke_screen(base, 2.0F * stroke - 1.0F);
|
||||
}
|
||||
|
||||
[[nodiscard]] float blend_stroke_hard_mix(float base, float stroke) noexcept
|
||||
{
|
||||
if (base == 0.0F) {
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
return base + stroke < 0.5F ? 0.0F : saturate(base + stroke);
|
||||
}
|
||||
|
||||
[[nodiscard]] float blend_stroke_color_dodge(float base, float stroke) noexcept
|
||||
{
|
||||
if (base == 0.0F) {
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
if (stroke == 1.0F) {
|
||||
return 1.0F;
|
||||
}
|
||||
|
||||
return base / (1.0F - stroke);
|
||||
}
|
||||
|
||||
[[nodiscard]] float blend_stroke_color_burn(float base, float stroke) noexcept
|
||||
{
|
||||
if (base == 1.0F) {
|
||||
return 1.0F;
|
||||
}
|
||||
|
||||
if (stroke == 0.0F) {
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
return 1.0F - std::min(1.0F, (1.0F - base) / stroke);
|
||||
}
|
||||
|
||||
[[nodiscard]] float blend_stroke_linear_height(float base, float stroke, float depth) noexcept
|
||||
{
|
||||
const auto partial = (1.0F - stroke) * std::pow(depth, 0.25F) + (base * depth * 10.0F);
|
||||
return base * partial;
|
||||
}
|
||||
|
||||
[[nodiscard]] float blend_stroke_height(float base, float stroke, float depth) noexcept
|
||||
{
|
||||
const auto a = std::pow(1.0F - stroke, std::max(1.0F, (1.0F - depth) * 10.0F))
|
||||
* std::pow(depth, 0.25F);
|
||||
const auto b = base * depth * 5.0F;
|
||||
return base * (a + b);
|
||||
}
|
||||
|
||||
[[nodiscard]] float blend_rgb(float base, float stroke, float base_alpha, float stroke_alpha, float alpha_total, BlendMode mode) noexcept
|
||||
{
|
||||
if (alpha_total <= 0.0F) {
|
||||
@@ -88,6 +149,44 @@ Rgba blend_pixels(Rgba base, Rgba stroke, BlendMode mode) noexcept
|
||||
};
|
||||
}
|
||||
|
||||
float blend_stroke_alpha(
|
||||
float base,
|
||||
float stroke,
|
||||
float depth,
|
||||
StrokeBlendMode mode) noexcept
|
||||
{
|
||||
base = saturate(base);
|
||||
stroke = saturate(stroke);
|
||||
depth = saturate(depth);
|
||||
|
||||
switch (mode) {
|
||||
case StrokeBlendMode::normal:
|
||||
return saturate(mix(base, stroke, depth));
|
||||
case StrokeBlendMode::multiply:
|
||||
return saturate(mix(base, base * stroke, depth));
|
||||
case StrokeBlendMode::subtract:
|
||||
return saturate(mix(base, std::max(0.0F, base - stroke), depth));
|
||||
case StrokeBlendMode::darken:
|
||||
return saturate(mix(base, std::min(base, stroke), depth));
|
||||
case StrokeBlendMode::overlay:
|
||||
return saturate(mix(base, blend_stroke_hard_light(stroke, base), depth));
|
||||
case StrokeBlendMode::color_dodge:
|
||||
return saturate(mix(base, blend_stroke_color_dodge(base, stroke), depth));
|
||||
case StrokeBlendMode::color_burn:
|
||||
return saturate(mix(base, blend_stroke_color_burn(base, stroke), depth));
|
||||
case StrokeBlendMode::linear_burn:
|
||||
return saturate(mix(base, saturate(base + stroke - 1.0F), depth));
|
||||
case StrokeBlendMode::hard_mix:
|
||||
return saturate(mix(base, blend_stroke_hard_mix(base, stroke), depth));
|
||||
case StrokeBlendMode::linear_height:
|
||||
return saturate(blend_stroke_linear_height(base, stroke, depth));
|
||||
case StrokeBlendMode::height:
|
||||
return saturate(blend_stroke_height(base, stroke, depth));
|
||||
}
|
||||
|
||||
return 1.0F;
|
||||
}
|
||||
|
||||
const char* blend_mode_name(BlendMode mode) noexcept
|
||||
{
|
||||
switch (mode) {
|
||||
@@ -106,4 +205,34 @@ const char* blend_mode_name(BlendMode mode) noexcept
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
const char* stroke_blend_mode_name(StrokeBlendMode mode) noexcept
|
||||
{
|
||||
switch (mode) {
|
||||
case StrokeBlendMode::normal:
|
||||
return "normal";
|
||||
case StrokeBlendMode::multiply:
|
||||
return "multiply";
|
||||
case StrokeBlendMode::subtract:
|
||||
return "subtract";
|
||||
case StrokeBlendMode::darken:
|
||||
return "darken";
|
||||
case StrokeBlendMode::overlay:
|
||||
return "overlay";
|
||||
case StrokeBlendMode::color_dodge:
|
||||
return "color_dodge";
|
||||
case StrokeBlendMode::color_burn:
|
||||
return "color_burn";
|
||||
case StrokeBlendMode::linear_burn:
|
||||
return "linear_burn";
|
||||
case StrokeBlendMode::hard_mix:
|
||||
return "hard_mix";
|
||||
case StrokeBlendMode::linear_height:
|
||||
return "linear_height";
|
||||
case StrokeBlendMode::height:
|
||||
return "height";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,6 +12,20 @@ enum class BlendMode : std::uint8_t {
|
||||
overlay,
|
||||
};
|
||||
|
||||
enum class StrokeBlendMode : std::uint8_t {
|
||||
normal,
|
||||
multiply,
|
||||
subtract,
|
||||
darken,
|
||||
overlay,
|
||||
color_dodge,
|
||||
color_burn,
|
||||
linear_burn,
|
||||
hard_mix,
|
||||
linear_height,
|
||||
height,
|
||||
};
|
||||
|
||||
struct Rgba {
|
||||
float r = 0.0F;
|
||||
float g = 0.0F;
|
||||
@@ -20,6 +34,12 @@ struct Rgba {
|
||||
};
|
||||
|
||||
[[nodiscard]] Rgba blend_pixels(Rgba base, Rgba stroke, BlendMode mode) noexcept;
|
||||
[[nodiscard]] float blend_stroke_alpha(
|
||||
float base,
|
||||
float stroke,
|
||||
float depth,
|
||||
StrokeBlendMode mode) noexcept;
|
||||
[[nodiscard]] const char* blend_mode_name(BlendMode mode) noexcept;
|
||||
[[nodiscard]] const char* stroke_blend_mode_name(StrokeBlendMode mode) noexcept;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user