Mixbox
Mixbox is a library for natural color mixing based on real pigments.
Install / Use
/learn @Solido/MixboxREADME
Mixbox for Dart/Flutter
Port of original MIXBOX
<p align="center"> <img src="https://scrtwpns.com/mixbox/teaser.jpg"/> </p>Dart implementation of Mixbox 2.0 - physically realistic color mixing simulating real pigment behavior.
🎨 Why Mixbox?
Classic RGB mixing produces dull colors:
- Yellow + Blue = Gray ❌ (in RGB)
- Yellow + Blue = Green ✅ (with Mixbox)
Mixbox simulates physical pigment behavior for natural results.
📦 Installation
1. Add the files
lib/
mixbox/
mixbox.dart
mixbox_loader.dart
assets/
mixbox_lut.dat
2. Dependencies in pubspec.yaml
dependencies:
flutter:
sdk: flutter
archive: ^3.4.0
flutter:
assets:
- assets/mixbox_lut.dat
3. Download the LUT
The mixbox_lut.dat file must be downloaded from:
- Official source: https://github.com/scrtwpns/mixbox
- Place it in
assets/mixbox_lut.dat
⚠️ Important: Without the LUT, Mixbox won't work properly.
🚀 Usage
Initialization (once at startup)
import 'mixbox_loader.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Load the LUT
await MixboxLoader.initializeFromAsset('assets/mixbox_lut.dat');
runApp(MyApp());
}
Simple mixing (2 colors)
import 'package:flutter/material.dart';
import 'mixbox.dart';
import 'mixbox_loader.dart';
// Extension for easy use with Flutter Color
final yellow = Color(0xFFFEEC00);
final blue = Color(0xFF190059);
final green = yellow.mixWith(blue, 0.5); // 50% of each
Multi-color mixing (3+)
final red = Color(0xFFFF2702);
final yellow = Color(0xFFFCD300);
final blue = Color(0xFF0D1B44);
// Convert to latent space
final z1 = Mixbox.rgbToLatent(red.toMixboxInt());
final z2 = Mixbox.rgbToLatent(yellow.toMixboxInt());
final z3 = Mixbox.rgbToLatent(blue.toMixboxInt());
// Custom mixing
final zMix = List.generate(
Mixbox.latentSize,
(i) => 0.4 * z1[i] + 0.3 * z2[i] + 0.3 * z3[i],
);
final mixed = Color(Mixbox.latentToRgb(zMix));
Physically correct gradient
final gradient = List.generate(
10,
(i) => yellow.mixWith(blue, i / 9.0),
);
🎨 Predefined Pigment Colors
Use these colors for realistic results:
const cadmiumYellow = Color(0xFFFEEC00); // Cadmium yellow
const hansaYellow = Color(0xFFFCD300); // Hansa yellow
const cadmiumOrange = Color(0xFFFF6900); // Cadmium orange
const cadmiumRed = Color(0xFFFF2702); // Cadmium red
const quinacridoneMagenta = Color(0xFF80022E); // Quinacridone magenta
const cobaltViolet = Color(0xFF4E0042); // Cobalt violet
const ultramarineBlue = Color(0xFF190059); // Ultramarine blue
const cobaltBlue = Color(0xFF002185); // Cobalt blue
const phthaloBlue = Color(0xFF0D1B44); // Phthalo blue
const phthaloGreen = Color(0xFF003C32); // Phthalo green
const permanentGreen = Color(0xFF076D16); // Permanent green
const sapGreen = Color(0xFF6B9404); // Sap green
const burntSienna = Color(0xFF7B4800); // Burnt sienna
📊 Complete API
Main methods
// Mix int (0xAARRGGBB)
int Mixbox.lerp(int color1, int color2, double t)
// Mix list [r, g, b] or [r, g, b, a] (0-255)
List<int> Mixbox.lerpList(List<int> color1, List<int> color2, double t)
// Mix float [r, g, b] or [r, g, b, a] (0.0-1.0)
List<double> Mixbox.lerpFloat(List<double> color1, List<double> color2, double t)
// Mix linear RGB (for 3D rendering)
List<double> Mixbox.lerpLinearFloat(List<double> color1, List<double> color2, double t)
Conversions
// RGB → Latent
List<double> Mixbox.rgbToLatent(int color)
List<double> Mixbox.floatRgbToLatent(double r, double g, double b)
// Latent → RGB
int Mixbox.latentToRgb(List<double> latent)
List<double> Mixbox.latentToFloatRgb(List<double> latent)
🧪 Complete Example
import 'package:flutter/material.dart';
import 'mixbox.dart';
import 'mixbox_loader.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await MixboxLoader.initializeFromAsset('assets/mixbox_lut.dat');
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
double _mix = 0.5;
final _yellow = const Color(0xFFFEEC00);
final _blue = const Color(0xFF190059);
@override
Widget build(BuildContext context) {
final mixed = _yellow.mixWith(_blue, _mix);
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Mixbox Demo')),
body: Column(
children: [
Container(height: 200, color: mixed),
Slider(
value: _mix,
onChanged: (v) => setState(() => _mix = v),
),
],
),
),
);
}
}
⚙️ Advanced Configuration
Without the LUT (Testing only)
// Generates an approximation (NOT recommended in production)
final testLut = MixboxLoader.generateTestLut();
Mixbox.initialize(testLut);
Linear Space (3D Rendering)
For shaders/3D rendering, use linear space:
final color1Linear = [1.0, 0.5, 0.0]; // Linear RGB
final color2Linear = [0.0, 0.2, 1.0];
final mixed = Mixbox.lerpLinearFloat(color1Linear, color2Linear, 0.5);
📝 License
Creative Commons Attribution-NonCommercial 4.0
- ✅ Free non-commercial use
- ❌ Commercial use requires license
- Contact: mixbox@scrtwpns.com
🔗 Resources
- Official website: https://scrtwpns.com/mixbox
- Paper: https://scrtwpns.com/mixbox.pdf
- GitHub: https://github.com/scrtwpns/mixbox
- Interactive demo: https://scrtwpns.com/mixbox/painter/
❓ FAQ
Q: Why is the LUT necessary?
A: It contains pre-calculated data from the physical pigment model (64×64×64 = 262,144 values).
Q: Can I use it without the LUT?
A: No for correct results. The generateTestLut() function is just for quick testing.
Q: Performance?
A: Very fast (~1μs per mix). Trilinear interpolation is optimized.
Q: Difference with HSV/HSL?
A: HSV/HSL are mathematical transformations. Mixbox simulates real pigment physics.
Q: Does it work for animation?
A: Yes! Perfect for gradients, transitions, and smooth animations.
🎯 Use Cases
- 🎨 Drawing/painting applications
- 🌈 Natural gradients
- 🎬 Content creation tools
- 🎮 Game color systems
- 🖼️ Realistic photo filters
- 📊 Data visualizations
Related Skills
node-connect
334.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
82.1kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
334.1kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
82.1kCommit, push, and open a PR
