From eaef098d96c8998b52c4c3ba7d7f90023b5cd7c3 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 21 Mar 2026 08:14:06 -1000 Subject: [PATCH] [light] Fix gamma LUT quantizing small brightness to zero The gamma LUT refactor (#14123) introduced a regression where small brightness values (e.g. 1%) get quantized to exactly 0.0 because the uint16 LUT entries round down to 0 for indices 1-3 with the default gamma of 2.8. This breaks zero_means_zero: true in FloatOutput because the min_power scaling is skipped when state == 0.0, causing LEDs to turn off completely instead of respecting the configured min_power. Fix by clamping non-zero LUT entries to a minimum of 1, preserving the invariant that non-zero input always produces non-zero output. Fixes #15055 --- esphome/components/light/__init__.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/esphome/components/light/__init__.py b/esphome/components/light/__init__.py index 4403281116a..bf382e8f5ae 100644 --- a/esphome/components/light/__init__.py +++ b/esphome/components/light/__init__.py @@ -88,7 +88,15 @@ def _get_or_create_gamma_table(gamma_correct): if gamma_correct > 0: forward = [ - HexInt(min(65535, int(round((i / 255.0) ** gamma_correct * 65535)))) + # Clamp non-zero indices to minimum of 1 to preserve the invariant + # that non-zero input always produces non-zero output. Without this, + # small brightness values (e.g. 1%) get quantized to exactly 0.0, + # which breaks zero_means_zero logic in FloatOutput. + HexInt( + max(1, min(65535, int(round((i / 255.0) ** gamma_correct * 65535)))) + if i > 0 + else HexInt(0) + ) for i in range(256) ] else: