MCPcopy Create free account
hub / github.com/FastLED/FastLED / solve_wx_overdrive

Function solve_wx_overdrive

src/fl/gfx/rgbw_colorimetric.cpp.hpp:789–859  ·  view source on GitHub ↗

Boosted / overdrive solver. This remains useful as an optional visual policy, but it is deliberately distinct from wx_lp_legacy. The non-overdriven residual boundary gives the chromaticity-preserving W limit; overdrive_ratio then moves W toward 1.0 and accepts the corresponding drift toward the W diode.

Source from the content-addressed store, hash-verified

787// chromaticity-preserving W limit; overdrive_ratio then moves W toward 1.0 and
788// accepts the corresponding drift toward the W diode.
789void solve_wx_overdrive(const ProfileCache& cache, float s_r, float s_g,
790 float s_b, float overdrive_ratio,
791 float out_rgbw[4]) FL_NOEXCEPT {
792 zero4(out_rgbw);
793
794 const float value = max3f(s_r, s_g, s_b);
795 if (value <= 1e-9f) {
796 return;
797 }
798
799 // Boosted/overdrive is a distinct visual policy, but it still must keep
800 // native single/dual topology authority. Single axes stay exact; dual
801 // edges stay locked to RG/RB/GB through the measured two-emitter solve.
802 if (is_native_input_gamut(*cache.profile)) {
803 const int n_active = count_active_channels(s_r, s_g, s_b);
804 if (n_active == 1) {
805 native_single_identity(s_r, s_g, s_b, out_rgbw);
806 return;
807 }
808 if (n_active == 2) {
809 solve_native_dual_edge_fixed_topology(cache, s_r, s_g,
810 s_b, out_rgbw);
811 return;
812 }
813 }
814
815 // Solve the full-chroma endpoint first and scale value later. This keeps
816 // boosted mode from flattening fixed-hue HSV value ramps into repeated
817 // saturated endpoint tuples.
818 const float c_r = s_r / value;
819 const float c_g = s_g / value;
820 const float c_b = s_b / value;
821
822 float X_t[3];
823 source_rgb_to_XYZ(cache, c_r, c_g, c_b, X_t);
824
825 float xy_t[2];
826 project_to_hull(cache, X_t, xy_t);
827
828 float a[3];
829 matvec3(cache.P_RGB_inv, X_t, a);
830 const float* d = cache.d_W;
831
832 float w_strict = 1.0f;
833 for (int i = 0; i < 3; ++i) {
834 if (d[i] > 1e-9f && a[i] >= 0.0f) {
835 const float lim = a[i] / d[i];
836 if (lim < w_strict) {
837 w_strict = lim;
838 }
839 }
840 }
841 w_strict = fl::clamp(w_strict, 0.0f, 1.0f);
842
843 const float rho = fl::clamp(overdrive_ratio, 0.0f, 1.0f);
844 float w = w_strict + rho * (1.0f - w_strict);
845 w = fl::clamp(w, 0.0f, 1.0f);
846

Callers 1

Calls 12

zero4Function · 0.85
max3fFunction · 0.85
is_native_input_gamutFunction · 0.85
count_active_channelsFunction · 0.85
native_single_identityFunction · 0.85
source_rgb_to_XYZFunction · 0.85
matvec3Function · 0.85
clampFunction · 0.85
maxFunction · 0.85
normalize4_if_neededFunction · 0.85
project_to_hullFunction · 0.70

Tested by

no test coverage detected