# Mixbox for Dart/Flutter

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` ```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) ```dart 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) ```dart 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+) ```dart 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 ```dart final gradient = List.generate( 10, (i) => yellow.mixWith(blue, i / 9.0), ); ``` ## ๐ŸŽจ Predefined Pigment Colors Use these colors for realistic results: ```dart 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 ```dart // 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 Mixbox.lerpList(List color1, List color2, double t) // Mix float [r, g, b] or [r, g, b, a] (0.0-1.0) List Mixbox.lerpFloat(List color1, List color2, double t) // Mix linear RGB (for 3D rendering) List Mixbox.lerpLinearFloat(List color1, List color2, double t) ``` ### Conversions ```dart // RGB โ†’ Latent List Mixbox.rgbToLatent(int color) List Mixbox.floatRgbToLatent(double r, double g, double b) // Latent โ†’ RGB int Mixbox.latentToRgb(List latent) List Mixbox.latentToFloatRgb(List latent) ``` ## ๐Ÿงช Complete Example ```dart 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 createState() => _MyAppState(); } class _MyAppState extends State { 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) ```dart // 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: ```dart 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