diff --git a/KeyLighting/CPUImageProcessor.cs b/KeyLighting/CPUImageProcessor.cs index 2a1cc11..da2765b 100644 --- a/KeyLighting/CPUImageProcessor.cs +++ b/KeyLighting/CPUImageProcessor.cs @@ -24,7 +24,7 @@ public class CPUImageProcessor : IDisposable private OpenRGB.NET.Color[] resultBuffer; private bool hasPreviousFrame = false; - private double fadeSpeed; + private double fadeSpeed; public CPUImageProcessor(LightingConfig config) { @@ -107,12 +107,12 @@ public OpenRGB.NET.Color[] ProcessImage(Bitmap image, int targetWidth, int targe } else { - ProcessColumnsWithEffects(targetWidth, brightness, vibrance, contrast, darkThreshold, darkFactor); - if (hasPreviousFrame) + // Apply fading only if fade speed is less than 1.0 + if (hasPreviousFrame && fadeSpeed < 1.0) { - ApplyFading(targetWidth, lastFrameWasSolid ? 0.95 : fadeSpeed); + ApplyFading(targetWidth, fadeSpeed); } } @@ -134,39 +134,7 @@ public OpenRGB.NET.Color[] ProcessImage(Bitmap image, int targetWidth, int targe } } - [MethodImpl(MethodImplOptions.AggressiveOptimization)] - private void ProcessSolidColor(byte r, byte g, byte b, int width, double brightness, double vibrance, double contrast, int darkThreshold, double darkFactor) - { - - OpenRGB.NET.Color processedColor = FastApplyEffects(r, g, b, brightness, vibrance, contrast, darkThreshold, darkFactor); - bool needsFade = hasPreviousFrame && !(lastFrameWasSolid && - lastSolidR == processedColor.R && - lastSolidG == processedColor.G && - lastSolidB == processedColor.B); - - if (needsFade) - { - - double fadeFactor = 0.95; - - Parallel.For(0, width, i => { - resultBuffer[i] = FastBlendColors(previousFrame[i], processedColor, fadeFactor); - }); - } - else - { - - for (int i = 0; i < width; i++) - { - resultBuffer[i] = processedColor; - } - } - - lastSolidR = processedColor.R; - lastSolidG = processedColor.G; - lastSolidB = processedColor.B; - } [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool AreSettingsCached(double brightness, double contrast) @@ -189,13 +157,13 @@ private bool IsSolidColorFrame() if (rawColors.Length < 2) return true; OpenRGB.NET.Color first = rawColors[0]; - const int tolerance = 5; + const int tolerance = 5; int[] samplePoints = { 0, rawColors.Length / 3, rawColors.Length / 2, (rawColors.Length * 2) / 3, rawColors.Length - 1 }; foreach (int i in samplePoints) { - if (i == 0) continue; + if (i == 0) continue; if (Math.Abs(first.R - rawColors[i].R) > tolerance || Math.Abs(first.G - rawColors[i].G) > tolerance || @@ -211,6 +179,9 @@ private bool IsSolidColorFrame() [MethodImpl(MethodImplOptions.AggressiveOptimization)] private void ApplyFading(int width, double fadeFactor) { + // This method should only be called when fadeSpeed < 1.0 + // Simply use the provided fade factor without any brightness-based adjustments + Parallel.For(0, width, i => { resultBuffer[i] = FastBlendColors(previousFrame[i], resultBuffer[i], fadeFactor); }); @@ -219,10 +190,10 @@ private void ApplyFading(int width, double fadeFactor) [MethodImpl(MethodImplOptions.AggressiveInlining)] private OpenRGB.NET.Color FastBlendColors(OpenRGB.NET.Color color1, OpenRGB.NET.Color color2, double factor) { - factor = Math.Clamp(factor, 0.0, 1.0); double inverseFactor = 1.0 - factor; + // Process each channel with adaptive blending byte r = (byte)(color1.R * inverseFactor + color2.R * factor); byte g = (byte)(color1.G * inverseFactor + color2.G * factor); byte b = (byte)(color1.B * inverseFactor + color2.B * factor); @@ -230,6 +201,47 @@ private OpenRGB.NET.Color FastBlendColors(OpenRGB.NET.Color color1, OpenRGB.NET. return new OpenRGB.NET.Color(r, g, b); } + // Also modify ProcessSolidColor method to handle brightness transitions better + [MethodImpl(MethodImplOptions.AggressiveOptimization)] + private void ProcessSolidColor(byte r, byte g, byte b, int width, double brightness, double vibrance, double contrast, int darkThreshold, double darkFactor) + { + OpenRGB.NET.Color processedColor = FastApplyEffects(r, g, b, brightness, vibrance, contrast, darkThreshold, darkFactor); + + // Check if we need to apply fading + bool needsFade = hasPreviousFrame && + fadeSpeed < 1.0 && // Only fade if fade speed is less than 1.0 + !(lastFrameWasSolid && + lastSolidR == processedColor.R && + lastSolidG == processedColor.G && + lastSolidB == processedColor.B); + + if (needsFade) + { + // Calculate brightness values for current and previous frame + int prevBrightness = lastSolidR + lastSolidG + lastSolidB; + int newBrightness = processedColor.R + processedColor.G + processedColor.B; + + // Determine if we're brightening or darkening + double fadeFactor = fadeSpeed; // Use the configured fade speed + + // Apply transition + Parallel.For(0, width, i => { + resultBuffer[i] = FastBlendColors(previousFrame[i], processedColor, fadeFactor); + }); + } + else + { + for (int i = 0; i < width; i++) + { + resultBuffer[i] = processedColor; + } + } + + lastSolidR = processedColor.R; + lastSolidG = processedColor.G; + lastSolidB = processedColor.B; + } + [MethodImpl(MethodImplOptions.AggressiveOptimization)] private void ExtractColumns(int stride, int width, int height, int bytesPerPixel) { diff --git a/KeyLighting/Program.cs b/KeyLighting/Program.cs index 2fced74..0a71457 100644 --- a/KeyLighting/Program.cs +++ b/KeyLighting/Program.cs @@ -26,7 +26,8 @@ class Program static DateTime lastUpdate = DateTime.MinValue; static DateTime lastDebugImageSave = DateTime.MinValue; - static float[] fadeProgress; + // Remove fade progress tracking + // static float[] fadeProgress; static ORGBColor[] targetColors; const int MIN_CAPTURE_INTERVAL_MS = 16; @@ -74,7 +75,7 @@ static void Main(string[] args) prevColors = new ORGBColor[ledCount]; ledColorsBuffer = new ORGBColor[ledCount]; - fadeProgress = new float[ledCount]; + // Removed fadeProgress targetColors = new ORGBColor[ledCount]; var processor = new CPUImageProcessor(config); @@ -216,6 +217,8 @@ static void ProcessFrame(ScreenCapturer capturer, CPUImageProcessor processor, O [MethodImpl(MethodImplOptions.AggressiveInlining)] static void UpdateLedColors(ORGBColor[] columnColors, LightingConfig config, int ledCount) { + // Check if we want instant transitions (fadeSpeed at or very near 1.0) + bool instantTransition = config.FadeFactor >= 0.99; var wasdEnabled = config.WASDEnabled; var wasdKeys = wasdEnabled ? config.WASDKeys : Array.Empty(); @@ -230,77 +233,46 @@ static void UpdateLedColors(ORGBColor[] columnColors, LightingConfig config, int } int columnLength = columnColors.Length; - float deltaTime = 1.0f / 60.0f; for (int i = 0; i < ledCount; i++) { if (wasdEnabled && Array.IndexOf(wasdKeys, i) >= 0) { - - continue; - } - else - { - - int columnIndex = Math.Min(i, columnLength - 1); - targetColors[i] = columnColors[columnIndex]; - } - } - - for (int i = 0; i < ledCount; i++) - { - if (wasdEnabled && Array.IndexOf(wasdKeys, i) >= 0) - { - + // Handle WASD keys with special color ledColorsBuffer[i] = new ORGBColor(wasdR, wasdG, wasdB); - prevColors[i] = ledColorsBuffer[i]; - fadeProgress[i] = 1.0f; } else { + // Apply column colors to the keyboard + int columnIndex = Math.Min(i, columnLength - 1); - ORGBColor prev = prevColors[i]; - ORGBColor target = targetColors[i]; - - bool colorChanged = - Math.Abs(prev.R - target.R) > 3 || - Math.Abs(prev.G - target.G) > 3 || - Math.Abs(prev.B - target.B) > 3; - - if (colorChanged && fadeProgress[i] >= 1.0f) + if (instantTransition) { - - fadeProgress[i] = 0.0f; + // With instantTransition, directly apply the column color + ledColorsBuffer[i] = columnColors[columnIndex]; } + else + { + // For backward compatibility, keep some very minimal smoothing + ORGBColor prev = prevColors[i]; + ORGBColor target = columnColors[columnIndex]; - fadeProgress[i] = (float)Math.Min(fadeProgress[i] + config.FadeFactor * deltaTime, 1.0f); - - float t = EaseInOutCubic(fadeProgress[i]); - - byte r = (byte)Math.Round(prev.R * (1 - t) + target.R * t); - byte g = (byte)Math.Round(prev.G * (1 - t) + target.G * t); - byte b = (byte)Math.Round(prev.B * (1 - t) + target.B * t); + // Simple lerp with very high weight toward target color + float t = 0.8f; // High value for quick transition but not instant - ledColorsBuffer[i] = new ORGBColor(r, g, b); + byte r = (byte)Math.Round(prev.R * (1 - t) + target.R * t); + byte g = (byte)Math.Round(prev.G * (1 - t) + target.G * t); + byte b = (byte)Math.Round(prev.B * (1 - t) + target.B * t); - if (fadeProgress[i] >= 1.0f) - { - prevColors[i] = target; - } - else - { - prevColors[i] = ledColorsBuffer[i]; + ledColorsBuffer[i] = new ORGBColor(r, g, b); } + + // Store current color for next frame + prevColors[i] = ledColorsBuffer[i]; } } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - static float EaseInOutCubic(float t) - { - return t < 0.5 ? 4 * t * t * t : 1 - (float)Math.Pow(-2 * t + 2, 3) / 2; - } - static void SaveDebugImages(Bitmap frame, ORGBColor[] columnColors, LightingConfig config) { try diff --git a/KeyLighting/config.json b/KeyLighting/config.json index c96c77d..acd6763 100644 --- a/KeyLighting/config.json +++ b/KeyLighting/config.json @@ -6,7 +6,7 @@ "brightnessMultiplier": 1.8, "vibranceFactor": 1, "contrastPower": 1.8, - "fadeFactor": 0.9, + "fadeFactor": 0.3, "darkenThreshold": 65, "darkenFactor": 0.4, "wasdEnabled": false,