#ifndef PROC_NODES_BLENDER_RAMP_BLEND_H
#define PROC_NODES_BLENDER_RAMP_BLEND_H
// BLENDER'S COLOUR BLEND MODES — NOW AN ADAPTER, NOT AN IMPLEMENTATION.
//
// The arithmetic is in src/shared/blender_ramp_blend.inc, compiled as GLSL and
// as C++ from one text, as the hash, perlin, voronoi and erosion filter are.
// Every name callers used is still here -- including the reference
// out-parameter signatures, which the .inc could not keep (GLSL has no
// references) and which this header restores over vec3 returns.
//
// This is what the Mix node does for COLOUR data, and it is nineteen distinct
// functions, several of which are not a lerp of anything. proc-nodes
// implemented one of them and had no blend_type at all, so every colour Mix
// crossing the bridge came out as MIX regardless of what Blender said.
//
// The alpha channel is deliberately left alone by every mode except BLEND --
// that asymmetry is Blender's, not an oversight.
#include "blender_noise_cpp_shim.h"
#include <godot_cpp/variant/color.hpp>
namespace godot {
namespace bramp {
enum {
RAMP_BLEND = 0, RAMP_ADD = 1, RAMP_MULT = 2, RAMP_SUB = 3, RAMP_SCREEN = 4,
RAMP_DIV = 5, RAMP_DIFF = 6, RAMP_DARK = 7, RAMP_LIGHT = 8, RAMP_OVERLAY = 9,
RAMP_DODGE = 10, RAMP_BURN = 11, RAMP_HUE = 12, RAMP_SAT = 13, RAMP_VAL = 14,
RAMP_COLOR = 15, RAMP_SOFT = 16, RAMP_LINEAR = 17, RAMP_EXCLUSION = 18,
};
// The conversions kept their out-parameter shape for callers; the .inc returns
// a vec3 because GLSL has no references.
static inline void rgb_to_hsv(float r, float g, float b, float &h, float &s, float &v) {
bnoisegl::vec3 o = bnoisegl::br_rgb_to_hsv(r, g, b);
h = o.x; s = o.y; v = o.z;
}
static inline void hsv_to_rgb(float h, float s, float v, float &r, float &g, float &b) {
bnoisegl::vec3 o = bnoisegl::br_hsv_to_rgb(h, s, v);
r = o.x; g = o.y; b = o.z;
}
static inline void rgb_to_hsl(float r, float g, float b, float &h, float &s, float &l) {
bnoisegl::vec3 o = bnoisegl::br_rgb_to_hsl(r, g, b);
h = o.x; s = o.y; l = o.z;
}
static inline void hsl_to_rgb(float h, float s, float l, float &r, float &g, float &b) {
bnoisegl::vec3 o = bnoisegl::br_hsl_to_rgb(h, s, l);
r = o.x; g = o.y; b = o.z;
}
// r_col is BOTH the A input and the result, exactly as Blender's signature has
// it; col is B.
static inline void ramp_blend(int type, float r_col[4], const float fac, const float col[4]) {
bnoisegl::vec4 o = bnoisegl::br_ramp_blend(type,
bnoisegl::vec4(r_col[0], r_col[1], r_col[2], r_col[3]), fac,
bnoisegl::vec4(col[0], col[1], col[2], col[3]));
r_col[0] = o.x; r_col[1] = o.y; r_col[2] = o.z; r_col[3] = o.w;
}
static inline Color ramp_blend(int type, const Color &a, float fac, const Color &b) {
bnoisegl::vec4 o = bnoisegl::br_ramp_blend(type, bnoisegl::vec4(a.r, a.g, a.b, a.a), fac,
bnoisegl::vec4(b.r, b.g, b.b, b.a));
return Color(o.x, o.y, o.z, o.w);
}
} // namespace bramp
} // namespace godot
#endif // PROC_NODES_BLENDER_RAMP_BLEND_H