@@ -24,7 +24,7 @@ public class CPUImageProcessor : IDisposable
2424 private OpenRGB.NET.Color[] resultBuffer;
2525 private bool hasPreviousFrame = false;
2626
27- private double fadeSpeed;
27+ private double fadeSpeed;
2828
2929 public CPUImageProcessor(LightingConfig config)
3030 {
@@ -107,12 +107,12 @@ public OpenRGB.NET.Color[] ProcessImage(Bitmap image, int targetWidth, int targe
107107 }
108108 else
109109 {
110-
111110 ProcessColumnsWithEffects(targetWidth, brightness, vibrance, contrast, darkThreshold, darkFactor);
112111
113- if (hasPreviousFrame)
112+ // Apply fading only if fade speed is less than 1.0
113+ if (hasPreviousFrame && fadeSpeed < 1.0)
114114 {
115- ApplyFading(targetWidth, lastFrameWasSolid ? 0.95 : fadeSpeed);
115+ ApplyFading(targetWidth, fadeSpeed);
116116 }
117117 }
118118
@@ -134,39 +134,7 @@ public OpenRGB.NET.Color[] ProcessImage(Bitmap image, int targetWidth, int targe
134134 }
135135 }
136136
137- [MethodImpl(MethodImplOptions.AggressiveOptimization)]
138- private void ProcessSolidColor(byte r, byte g, byte b, int width, double brightness, double vibrance, double contrast, int darkThreshold, double darkFactor)
139- {
140-
141- OpenRGB.NET.Color processedColor = FastApplyEffects(r, g, b, brightness, vibrance, contrast, darkThreshold, darkFactor);
142137
143- bool needsFade = hasPreviousFrame && !(lastFrameWasSolid &&
144- lastSolidR == processedColor.R &&
145- lastSolidG == processedColor.G &&
146- lastSolidB == processedColor.B);
147-
148- if (needsFade)
149- {
150-
151- double fadeFactor = 0.95;
152-
153- Parallel.For(0, width, i => {
154- resultBuffer[i] = FastBlendColors(previousFrame[i], processedColor, fadeFactor);
155- });
156- }
157- else
158- {
159-
160- for (int i = 0; i < width; i++)
161- {
162- resultBuffer[i] = processedColor;
163- }
164- }
165-
166- lastSolidR = processedColor.R;
167- lastSolidG = processedColor.G;
168- lastSolidB = processedColor.B;
169- }
170138
171139 [MethodImpl(MethodImplOptions.AggressiveInlining)]
172140 private bool AreSettingsCached(double brightness, double contrast)
@@ -189,13 +157,13 @@ private bool IsSolidColorFrame()
189157 if (rawColors.Length < 2) return true;
190158
191159 OpenRGB.NET.Color first = rawColors[0];
192- const int tolerance = 5;
160+ const int tolerance = 5;
193161
194162 int[] samplePoints = { 0, rawColors.Length / 3, rawColors.Length / 2, (rawColors.Length * 2) / 3, rawColors.Length - 1 };
195163
196164 foreach (int i in samplePoints)
197165 {
198- if (i == 0) continue;
166+ if (i == 0) continue;
199167
200168 if (Math.Abs(first.R - rawColors[i].R) > tolerance ||
201169 Math.Abs(first.G - rawColors[i].G) > tolerance ||
@@ -211,6 +179,9 @@ private bool IsSolidColorFrame()
211179 [MethodImpl(MethodImplOptions.AggressiveOptimization)]
212180 private void ApplyFading(int width, double fadeFactor)
213181 {
182+ // This method should only be called when fadeSpeed < 1.0
183+ // Simply use the provided fade factor without any brightness-based adjustments
184+
214185 Parallel.For(0, width, i => {
215186 resultBuffer[i] = FastBlendColors(previousFrame[i], resultBuffer[i], fadeFactor);
216187 });
@@ -219,17 +190,58 @@ private void ApplyFading(int width, double fadeFactor)
219190 [MethodImpl(MethodImplOptions.AggressiveInlining)]
220191 private OpenRGB.NET.Color FastBlendColors(OpenRGB.NET.Color color1, OpenRGB.NET.Color color2, double factor)
221192 {
222-
223193 factor = Math.Clamp(factor, 0.0, 1.0);
224194 double inverseFactor = 1.0 - factor;
225195
196+ // Process each channel with adaptive blending
226197 byte r = (byte)(color1.R * inverseFactor + color2.R * factor);
227198 byte g = (byte)(color1.G * inverseFactor + color2.G * factor);
228199 byte b = (byte)(color1.B * inverseFactor + color2.B * factor);
229200
230201 return new OpenRGB.NET.Color(r, g, b);
231202 }
232203
204+ // Also modify ProcessSolidColor method to handle brightness transitions better
205+ [MethodImpl(MethodImplOptions.AggressiveOptimization)]
206+ private void ProcessSolidColor(byte r, byte g, byte b, int width, double brightness, double vibrance, double contrast, int darkThreshold, double darkFactor)
207+ {
208+ OpenRGB.NET.Color processedColor = FastApplyEffects(r, g, b, brightness, vibrance, contrast, darkThreshold, darkFactor);
209+
210+ // Check if we need to apply fading
211+ bool needsFade = hasPreviousFrame &&
212+ fadeSpeed < 1.0 && // Only fade if fade speed is less than 1.0
213+ !(lastFrameWasSolid &&
214+ lastSolidR == processedColor.R &&
215+ lastSolidG == processedColor.G &&
216+ lastSolidB == processedColor.B);
217+
218+ if (needsFade)
219+ {
220+ // Calculate brightness values for current and previous frame
221+ int prevBrightness = lastSolidR + lastSolidG + lastSolidB;
222+ int newBrightness = processedColor.R + processedColor.G + processedColor.B;
223+
224+ // Determine if we're brightening or darkening
225+ double fadeFactor = fadeSpeed; // Use the configured fade speed
226+
227+ // Apply transition
228+ Parallel.For(0, width, i => {
229+ resultBuffer[i] = FastBlendColors(previousFrame[i], processedColor, fadeFactor);
230+ });
231+ }
232+ else
233+ {
234+ for (int i = 0; i < width; i++)
235+ {
236+ resultBuffer[i] = processedColor;
237+ }
238+ }
239+
240+ lastSolidR = processedColor.R;
241+ lastSolidG = processedColor.G;
242+ lastSolidB = processedColor.B;
243+ }
244+
233245 [MethodImpl(MethodImplOptions.AggressiveOptimization)]
234246 private void ExtractColumns(int stride, int width, int height, int bytesPerPixel)
235247 {
0 commit comments