Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

scrtwpns/mixbox

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

20 Commits

Repository files navigation

Mixbox: Pigment-Based Color Mixing

Mixbox is a new blending method for natural color mixing. It produces saturated gradients with hue shifts and natural secondary colors during blending. Yellow and blue make green. The interface is simple - RGB in, RGB out. Internally, Mixbox treats colors as real-life pigments using the Kubelka & Munk theory to predict realistic color behavior. That way, colors act like actual paints and bring more vibrance and intuition into digital painting.

Mixbox is shipping in Rebelle 5 Pro as the Rebelle Pigments feature and in the Flip Fluids addon for Blender.

Usage

  • C / C++: #include "mixbox.h" and build mixbox.cpp together with your project
  • C#: use Mixbox package from NuGet https://www.nuget.org/packages/Mixbox/2.0.0
  • Java: add implementation 'com.scrtwpns:mixbox:2.0.0' to your Gradle
  • JavaScript: <script src="https://scrtwpns.com/mixbox.js">
  • Node: npm install mixbox
  • Python: pip install pymixbox
  • Rust: add mixbox = "2.0.0" to your Cargo.toml
  • Unity: add package from git url git://github.com/scrtwpns/mixbox.git#upm
  • Godot: copy godot\addons to the root of your project
  • Shaders: load mixbox_lut.png as texture and include mixbox.glsl/.hlsl/.metal code into your shader

Pigment Colors

Pigment RGB Float RGB Linear RGB
Cadmium Yellow 254, 236, 0 0.996, 0.925, 0.0 0.991, 0.839, 0.0
Hansa Yellow 252, 211, 0 0.988, 0.827, 0.0 0.973, 0.651, 0.0
Cadmium Orange 255, 105, 0 1.0, 0.412, 0.0 1.0, 0.141, 0.0
Cadmium Red 255, 39, 2 1.0, 0.153, 0.008 1.0, 0.02, 0.001
Quinacridone Magenta 128, 2, 46 0.502, 0.008, 0.18 0.216, 0.001, 0.027
Cobalt Violet 78, 0, 66 0.306, 0.0, 0.259 0.076, 0.0, 0.054
Ultramarine Blue 25, 0, 89 0.098, 0.0, 0.349 0.01, 0.0, 0.1
Cobalt Blue 0, 33, 133 0.0, 0.129, 0.522 0.0, 0.015, 0.235
Phthalo Blue 13, 27, 68 0.051, 0.106, 0.267 0.004, 0.011, 0.058
Phthalo Green 0, 60, 50 0.0, 0.235, 0.196 0.0, 0.045, 0.032
Permanent Green 7, 109, 22 0.027, 0.427, 0.086 0.002, 0.153, 0.008
Sap Green 107, 148, 4 0.42, 0.58, 0.016 0.147, 0.296, 0.001
Burnt Sienna 123, 72, 0 0.482, 0.282, 0.0 0.198, 0.065, 0.0

C / C++

#include <stdio.h>
#include "mixbox.h"
int main() {
 unsigned char r1 = 0, g1 = 33, b1 = 133; // blue
 unsigned char r2 = 252, g2 = 211, b2 = 0; // yellow
 float t = 0.5;
 unsigned char r, g, b;
 mixbox_lerp(r1, g1, b1, // first color
 r2, g2, b2, // second color
 t, // mixing ratio
 &r, &g, &b); // result
 printf("%d %d %d\n", r, g, b);
}

GLSL Shader

#ifdef GL_ES
precision highp float;
#endif
uniform sampler2D mixbox_lut; // bind the "mixbox_lut.png" texture here
#include "mixbox.glsl" // paste the contents of mixbox.glsl here
void main(void) {
 vec3 rgb1 = vec3(0, 0.129, 0.522); // blue
 vec3 rgb2 = vec3(0.988, 0.827, 0); // yellow
 float t = 0.5; // mixing ratio
 vec3 rgb = mixbox_lerp(rgb1, rgb2, t);
 gl_FragColor = vec4(rgb, 1.0);
}

Rust

fn main() {
 let rgb1 = [0, 33, 133]; // blue
 let rgb2 = [252, 211, 0]; // yellow
 let t = 0.5; // mixing ratio
 let [r, g, b] = mixbox::lerp(&rgb1, &rgb2, t);
 println!("{} {} {}", r, g, b);
}

Python

import mixbox
rgb1 = (0, 33, 133) # blue
rgb2 = (252, 211, 0) # yellow
t = 0.5 # mixing ratio
rgb_mix = mixbox.lerp(rgb1, rgb2, t)
print(rgb_mix)

JavaScript

<html>
 <body>
 <script src="https://scrtwpns.com/mixbox.js"></script>
 <script>
 var rgb1 = "rgb(0, 33, 133)"; // blue
 var rgb2 = "rgb(252, 211, 0)"; // yellow
 var t = 0.5; // mixing ratio
 var mixed = mixbox.lerp(rgb1, rgb2, t);
 document.body.style.background = mixed;
 </script>
 </body>
</html>

Node

import mixbox from 'mixbox';
let rgb1 = "rgb(0, 33, 133)"; // blue
let rgb2 = "rgb(252, 211, 0)"; // yellow
let t = 0.5; // mixing ratio
let mixed = mixbox.lerp(rgb1, rgb2, t);
console.log(mixed);

Java

import java.awt.Color;
import com.scrtwpns.Mixbox;
class HelloMixbox {
 public static void main(String[] args) {
 Color color1 = new Color(0, 33, 133); // blue
 Color color2 = new Color(252, 211, 0); // yellow
 float t = 0.5f; // mixing ratio
 Color colorMix = new Color(Mixbox.lerp(color1.getRGB(), color2.getRGB(), t));
 System.out.print(colorMix);
 }
}

Android

package com.example.hellomixbox;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.graphics.Color;
import com.scrtwpns.Mixbox;
public class MainActivity extends Activity {
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 int color1 = Color.rgb(0, 33, 133); // blue
 int color2 = Color.rgb(252, 211, 0); // yellow
 float t = 0.5f; // mixing ratio
 int colorMix = Mixbox.lerp(color1, color2, t);
 View view = new View(this);
 view.setBackgroundColor(colorMix);
 setContentView(view);
 }
}

C#

using System.Drawing;
using Scrtwpns.Mixbox;
public class HelloMixbox
{
 public static void Main(string[] args)
 {
 Color color1 = Color.FromArgb(0, 33, 133); // blue
 Color color2 = Color.FromArgb(252, 211, 0); // yellow
 float t = 0.5f; // mixing ratio
 Color colorMix = Color.FromArgb(Mixbox.Lerp(color1.ToArgb(), color2.ToArgb(), t));
 System.Console.WriteLine(colorMix);
 }
}

Unity

using UnityEngine;
using Scrtwpns.Mixbox;
public class NewBehaviourScript : MonoBehaviour
{
 void Start()
 {
 Color color1 = new Color(0.0f, 0.129f, 0.522f); // blue
 Color color2 = new Color(0.988f, 0.827f, 0.0f); // yellow
 float t = 0.5f; // mixing ratio
 Color colorMix = Mixbox.Lerp(color1, color2, t);
 Debug.Log(colorMix);
 }
}

Unity Shader

Shader "MixboxHelloShader"
{
 Properties
 {
 _MixboxLUT ("Mixbox LUT", 2D) = "white" {} // assign "Packages/Mixbox/Textures/MixboxLUT.png"
 _Color1 ("Color 1", Color) = (0, 0.129, 0.522, 1) // blue
 _Color2 ("Color 2", Color) = (0.988, 0.827, 0, 1) // yellow
 }
 SubShader
 {
 Pass
 {
 CGPROGRAM
 #pragma vertex vert
 #pragma fragment frag
 #include "UnityCG.cginc"
 sampler2D _MixboxLUT;
 #include "Packages/com.scrtwpns.mixbox/ShaderLibrary/Mixbox.cginc"
 fixed4 _Color1;
 fixed4 _Color2;
 struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; };
 struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; };
 v2f vert (appdata v)
 {
 v2f o;
 o.vertex = UnityObjectToClipPos(v.vertex);
 o.uv = v.uv;
 return o;
 }
 fixed4 frag (v2f i) : SV_Target
 {
 fixed4 mixedColor = MixboxLerp(_Color1, _Color2, i.uv.x);
 return mixedColor;
 }
 ENDCG
 }
 }
}

Unity Shader Graph

Godot

var Mixbox = preload("res://addons/mixbox/mixbox.gd")
var color1 = Color(0.0, 0.129, 0.522) # blue
var color2 = Color(0.988, 0.827, 0.0) # yellow
var t = 0.5 # mixing ratio
var color_mix = Mixbox.lerp(color1, color2, t)
print(color_mix)

Godot Shader

shader_type canvas_item;
uniform sampler2D mixbox_lut; // attach "addons/mixbox/mixbox_lut.png" here
uniform vec4 color1 : hint_color = vec4(0.0, 0.129, 0.522, 1.0); // blue
uniform vec4 color2 : hint_color = vec4(0.988, 0.827, 0.0, 1.0); // yellow
#include "addons/mixbox/mixbox.gdshaderinc"
void fragment() {
 COLOR = mixbox_lerp(color1, color2, UV.x);
}

Godot VisualShader

WebGL

<script src="https://scrtwpns.com/mixbox.js"></script>
var shader = `
 precision highp float;

 uniform sampler2D mixbox_lut; // bind mixbox.lutTexture(gl) here

 #include "mixbox.glsl"

 void main(void) {
 vec3 rgb1 = vec3(0, 0.129, 0.522); // blue
 vec3 rgb2 = vec3(0.988, 0.827, 0); // yellow
 float t = 0.5; // mixing ratio

 vec3 rgb = mixbox_lerp(rgb1, rgb2, t);

 gl_FragColor = vec4(rgb, 1.0);
 }
`;
shader = shader.replace('#include "mixbox.glsl"', mixbox.glsl());
gl.useProgram(shaderProgram);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, mixbox.lutTexture(gl));
gl.uniform1i(gl.getUniformLocation(shaderProgram, "mixbox_lut"), 0);

Examples

Gradients Mountains Palette Snakes
source code source code source code
Splash Art Paint Mixer Pigment Fluids
source code source code source code

Painter

This painting app runs two color mixing implementations in parallel: one based on Mixbox and the other that performs ordinary RGB mixing. The app allows switching between them on the fly, showing the differences between pigment-based mixing and the normal RGB mixing. To launch the painter in your browser, please click here.

License

Copyright (c) 2022, Secret Weapons. All rights reserved.
Mixbox is provided under the CC BY-NC 4.0 license for non-commercial use only.
If you want to obtain commercial license, please contact: mixbox@scrtwpns.com

About

Mixbox is a library for natural color mixing based on real pigments.

Topics

Resources

License

Stars

Watchers

Forks

AltStyle によって変換されたページ (->オリジナル) /