diff --git a/esphome/components/light/addressable_light.cpp b/esphome/components/light/addressable_light.cpp index 671f10874d..f52f27c63d 100644 --- a/esphome/components/light/addressable_light.cpp +++ b/esphome/components/light/addressable_light.cpp @@ -63,20 +63,14 @@ void AddressableLightTransformer::start() { // strip), interpolate math-only against a single start color. Avoiding the per-step read-back // through the 8-bit stored byte prevents gamma round-trip quantization from stalling the fade // at low values (e.g. gamma 2.8 pre-gamma values <27 round to stored 0, freezing progress). - this->uniform_start_ = false; + this->uniform_start_color_.reset(); if (this->light_.size() > 0) { Color first = this->light_[0].get(); - bool uniform = true; for (int32_t i = 1; i < this->light_.size(); i++) { - if (this->light_[i].get() != first) { - uniform = false; - break; - } - } - if (uniform) { - this->uniform_start_ = true; - this->start_color_ = first; + if (this->light_[i].get() != first) + return; } + this->uniform_start_color_ = first; } } @@ -117,16 +111,17 @@ optional AddressableLightTransformer::apply() { // non-linear when applying small deltas. if (smoothed_progress > this->last_transition_progress_ && this->last_transition_progress_ < 1.f) { - if (this->uniform_start_) { + if (this->uniform_start_color_.has_value()) { // All LEDs started at the same color: compute the interpolated value once and write it to // every LED. No read-back, so each LED's stored byte advances through every gamma threshold // as smoothed_progress crosses it, instead of stalling at 0 for low pre-gamma values. // lerp(start, target, progress) via existing helper: target - (target-start)*(1-progress). + const Color &start = *this->uniform_start_color_; int32_t remaining = int32_t(256.f * (1.f - smoothed_progress)); - uint8_t r = subtract_scaled_difference(this->target_color_.red, this->start_color_.red, remaining); - uint8_t g = subtract_scaled_difference(this->target_color_.green, this->start_color_.green, remaining); - uint8_t b = subtract_scaled_difference(this->target_color_.blue, this->start_color_.blue, remaining); - uint8_t w = subtract_scaled_difference(this->target_color_.white, this->start_color_.white, remaining); + uint8_t r = subtract_scaled_difference(this->target_color_.red, start.red, remaining); + uint8_t g = subtract_scaled_difference(this->target_color_.green, start.green, remaining); + uint8_t b = subtract_scaled_difference(this->target_color_.blue, start.blue, remaining); + uint8_t w = subtract_scaled_difference(this->target_color_.white, start.white, remaining); for (auto led : this->light_) { led.set_rgbw(r, g, b, w); } diff --git a/esphome/components/light/addressable_light.h b/esphome/components/light/addressable_light.h index 684dcd4eb1..c4eabbad2e 100644 --- a/esphome/components/light/addressable_light.h +++ b/esphome/components/light/addressable_light.h @@ -115,8 +115,7 @@ class AddressableLightTransformer : public LightTransformer { AddressableLight &light_; float last_transition_progress_{0.0f}; Color target_color_{}; - Color start_color_{}; - bool uniform_start_{false}; + optional uniform_start_color_{}; }; } // namespace esphome::light