LABColor

From Unify Community Wiki
(Difference between revisions)
Jump to: navigation, search
(Removing all content from page)
m (Reverted edits by Joseph05408 (Talk); changed back to last version by Charleshinshaw)
Line 1: Line 1:
 +
[[Category: C Sharp]]
 +
[[Category: Utility]]
 +
[[Category: Struct]]
 +
[[Category: Color]]
 +
[[Category: LAB]]
 +
Author: [[User:charleshinshaw|Charles Hinshaw]]
 +
==Description==
 +
This script provides a Lab color space in addition to Unity's built in Red/Green/Blue colors.  Lab is based on CIE XYZ and is a color-opponent space with L for lightness and a and b for the color-opponent dimensions. Lab color is designed to approximate human vision and so it aspires to perceptual uniformity. The L component closely matches human perception of lightness.
  
 +
==Usage==
 +
Put this script in a file in /Plugins/LABColor.cs so that it may be callable by JavaScript. 
 +
 +
==C# - LABColor.cs==
 +
<csharp>
 +
using UnityEngine;
 +
[System.Serializable]
 +
 +
public struct LABColor{
 +
 +
// This script provides a Lab color space in addition to Unity's built in Red/Green/Blue colors.
 +
// Lab is based on CIE XYZ and is a color-opponent space with L for lightness and a and b for the color-opponent dimensions.
 +
// Lab color is designed to approximate human vision and so it aspires to perceptual uniformity.
 +
// The L component closely matches human perception of lightness.
 +
// Put LABColor.cs in a 'Plugins' folder to ensure that it is accessible to other scripts.
 +
 +
private float L;
 +
private float A;
 +
private float B;
 +
 +
// lightness accessors
 +
public float l{
 +
get { return this.L; }
 +
set { this.L = value; }
 +
}
 +
 +
// a color-opponent accessor
 +
public float a{
 +
get { return this.A; }
 +
set { this.A = value; }
 +
}
 +
 +
// b color-opponent accessor
 +
public float b{
 +
get { return this.B; }
 +
set { this.B = value; }
 +
}
 +
 +
// constructor - takes three floats for lightness and color-opponent dimensions
 +
public LABColor(float l, float a, float b){
 +
this.l = l;
 +
this.a = a;
 +
this.b = b;
 +
}
 +
 +
// constructor - takes a Color
 +
public LABColor(Color col){
 +
LABColor temp = FromColor(col);
 +
l = temp.l;
 +
a = temp.a;
 +
b = temp.b;
 +
}
 +
 +
// static function for linear interpolation between two LABColors
 +
public static LABColor Lerp(LABColor a, LABColor b, float t){
 +
return new LABColor(Mathf.Lerp(a.l, b.l, t), Mathf.Lerp(a.a, b.a, t), Mathf.Lerp(a.b, b.b, t));
 +
}
 +
 +
// static function for interpolation between two Unity Colors through normalized colorspace
 +
public static Color Lerp(Color a, Color b, float t){
 +
return (LABColor.Lerp(LABColor.FromColor(a), LABColor.FromColor(b), t)).ToColor();
 +
}
 +
 +
// static function for returning the color difference in a normalized colorspace (Delta-E)
 +
public static float Distance(LABColor a, LABColor b){
 +
return Mathf.Sqrt(Mathf.Pow((a.l - b.l), 2f) + Mathf.Pow((a.a - b.a), 2f) + Mathf.Pow((a.b - b.b),2f));
 +
}
 +
 +
// static function for converting from Color to LABColor
 +
public static LABColor FromColor(Color c){
 +
float D65x = 0.9505f;
 +
float D65y = 1.0f;
 +
float D65z = 1.0890f;
 +
float rLinear = c.r;
 +
float gLinear = c.g;
 +
float bLinear = c.b;
 +
float r = (rLinear > 0.04045f)? Mathf.Pow((rLinear + 0.055f)/(1f + 0.055f), 2.2f) : (rLinear/12.92f) ;
 +
float g = (gLinear > 0.04045f)? Mathf.Pow((gLinear + 0.055f)/(1f + 0.055f), 2.2f) : (gLinear/12.92f) ;
 +
float b = (bLinear > 0.04045f)? Mathf.Pow((bLinear + 0.055f)/(1f + 0.055f), 2.2f) : (bLinear/12.92f) ;
 +
float x = (r*0.4124f + g*0.3576f + b*0.1805f);
 +
float y = (r*0.2126f + g*0.7152f + b*0.0722f);
 +
float z = (r*0.0193f + g*0.1192f + b*0.9505f);
 +
x = (x>0.9505f)? 0.9505f : ((x<0f)? 0f : x);
 +
y = (y>1.0f)? 1.0f : ((y<0f)? 0f : y);
 +
z = (z>1.089f)? 1.089f : ((z<0f)? 0f : z);
 +
LABColor lab = new LABColor(0f,0f,0f);
 +
float fx = x/D65x;
 +
float fy = y/D65y;
 +
float fz = z/D65z;
 +
fx = ((fx > 0.008856f)? Mathf.Pow(fx, (1.0f/3.0f)) : (7.787f*fx + 16.0f/116.0f));
 +
fy = ((fy > 0.008856f)? Mathf.Pow(fy, (1.0f/3.0f)) : (7.787f*fy + 16.0f/116.0f));
 +
fz = ((fz > 0.008856f)? Mathf.Pow(fz, (1.0f/3.0f)) : (7.787f*fz + 16.0f/116.0f));
 +
lab.l = 116.0f * fy - 16f;
 +
lab.a = 500.0f * (fx - fy);
 +
lab.b = 200.0f * (fy - fz);
 +
return lab;
 +
}
 +
 +
// static function for converting from LABColor to Color
 +
public static Color ToColor(LABColor lab){
 +
float D65x = 0.9505f;
 +
float D65y = 1.0f;
 +
float D65z = 1.0890f;
 +
float delta = 6.0f/29.0f;
 +
float fy = (lab.l+16f)/116.0f;
 +
float fx = fy + (lab.a/500.0f);
 +
float fz = fy - (lab.b/200.0f);
 +
float x = (fx > delta)? D65x * (fx*fx*fx) : (fx - 16.0f/116.0f)*3f*(delta*delta)*D65x;
 +
float y = (fy > delta)? D65y * (fy*fy*fy) : (fy - 16.0f/116.0f)*3f*(delta*delta)*D65y;
 +
float z = (fz > delta)? D65z * (fz*fz*fz) : (fz - 16.0f/116.0f)*3f*(delta*delta)*D65z;
 +
float r = x*3.2410f - y*1.5374f - z*0.4986f;
 +
float g = -x*0.9692f + y*1.8760f - z*0.0416f;
 +
float b = x*0.0556f - y*0.2040f + z*1.0570f;
 +
r = (r<=0.0031308f)? 12.92f*r : (1f+0.055f)* Mathf.Pow(r, (1.0f/2.4f)) - 0.055f;
 +
g = (g<=0.0031308f)? 12.92f*g : (1f+0.055f)* Mathf.Pow(g, (1.0f/2.4f)) - 0.055f;
 +
b = (b<=0.0031308f)? 12.92f*b : (1f+0.055f)* Mathf.Pow(b, (1.0f/2.4f)) - 0.055f;
 +
r = (r<0)? 0 : r;
 +
g = (g<0)? 0 : g;
 +
b = (b<0)? 0 : b;
 +
return new Color(r, g, b);
 +
}
 +
 +
// function for converting an instance of LABColor to Color
 +
public Color ToColor(){
 +
return LABColor.ToColor(this);
 +
}
 +
 +
// override for string
 +
public override string ToString(){
 +
return "L:"+l+" A:"+a+" B:"+b;
 +
}
 +
 +
// are two LABColors the same?
 +
public override bool Equals(System.Object obj){
 +
if(obj==null || GetType()!=obj.GetType()) return false;
 +
return (this == (LABColor)obj);
 +
}
 +
 +
// override hashcode for a LABColor
 +
public override int GetHashCode(){
 +
return l.GetHashCode() ^ a.GetHashCode() ^ b.GetHashCode();
 +
}
 +
 +
// Equality operator
 +
public static bool operator ==(LABColor item1, LABColor item2){
 +
return (item1.l == item2.l && item1.a == item2.a && item1.b == item2.b);
 +
}
 +
 +
// Inequality operator
 +
public static bool operator !=(LABColor item1, LABColor item2){
 +
return (item1.l != item2.l || item1.a != item2.a || item1.b != item2.b);
 +
}
 +
}
 +
</csharp>

Revision as of 19:06, 19 October 2009

Author: Charles Hinshaw

Description

This script provides a Lab color space in addition to Unity's built in Red/Green/Blue colors. Lab is based on CIE XYZ and is a color-opponent space with L for lightness and a and b for the color-opponent dimensions. Lab color is designed to approximate human vision and so it aspires to perceptual uniformity. The L component closely matches human perception of lightness.

Usage

Put this script in a file in /Plugins/LABColor.cs so that it may be callable by JavaScript.

C# - LABColor.cs

<csharp> using UnityEngine; [System.Serializable]

public struct LABColor{

// This script provides a Lab color space in addition to Unity's built in Red/Green/Blue colors. // Lab is based on CIE XYZ and is a color-opponent space with L for lightness and a and b for the color-opponent dimensions. // Lab color is designed to approximate human vision and so it aspires to perceptual uniformity. // The L component closely matches human perception of lightness. // Put LABColor.cs in a 'Plugins' folder to ensure that it is accessible to other scripts.

private float L; private float A; private float B;

// lightness accessors public float l{ get { return this.L; } set { this.L = value; } }

// a color-opponent accessor public float a{ get { return this.A; } set { this.A = value; } }

// b color-opponent accessor public float b{ get { return this.B; } set { this.B = value; } }

// constructor - takes three floats for lightness and color-opponent dimensions public LABColor(float l, float a, float b){ this.l = l; this.a = a; this.b = b; }

// constructor - takes a Color public LABColor(Color col){ LABColor temp = FromColor(col); l = temp.l; a = temp.a; b = temp.b; }

// static function for linear interpolation between two LABColors public static LABColor Lerp(LABColor a, LABColor b, float t){ return new LABColor(Mathf.Lerp(a.l, b.l, t), Mathf.Lerp(a.a, b.a, t), Mathf.Lerp(a.b, b.b, t)); }

// static function for interpolation between two Unity Colors through normalized colorspace public static Color Lerp(Color a, Color b, float t){ return (LABColor.Lerp(LABColor.FromColor(a), LABColor.FromColor(b), t)).ToColor(); }

// static function for returning the color difference in a normalized colorspace (Delta-E) public static float Distance(LABColor a, LABColor b){ return Mathf.Sqrt(Mathf.Pow((a.l - b.l), 2f) + Mathf.Pow((a.a - b.a), 2f) + Mathf.Pow((a.b - b.b),2f)); }

// static function for converting from Color to LABColor public static LABColor FromColor(Color c){ float D65x = 0.9505f; float D65y = 1.0f; float D65z = 1.0890f; float rLinear = c.r; float gLinear = c.g; float bLinear = c.b; float r = (rLinear > 0.04045f)? Mathf.Pow((rLinear + 0.055f)/(1f + 0.055f), 2.2f) : (rLinear/12.92f) ; float g = (gLinear > 0.04045f)? Mathf.Pow((gLinear + 0.055f)/(1f + 0.055f), 2.2f) : (gLinear/12.92f) ; float b = (bLinear > 0.04045f)? Mathf.Pow((bLinear + 0.055f)/(1f + 0.055f), 2.2f) : (bLinear/12.92f) ; float x = (r*0.4124f + g*0.3576f + b*0.1805f); float y = (r*0.2126f + g*0.7152f + b*0.0722f); float z = (r*0.0193f + g*0.1192f + b*0.9505f); x = (x>0.9505f)? 0.9505f : ((x<0f)? 0f : x); y = (y>1.0f)? 1.0f : ((y<0f)? 0f : y); z = (z>1.089f)? 1.089f : ((z<0f)? 0f : z); LABColor lab = new LABColor(0f,0f,0f); float fx = x/D65x; float fy = y/D65y; float fz = z/D65z; fx = ((fx > 0.008856f)? Mathf.Pow(fx, (1.0f/3.0f)) : (7.787f*fx + 16.0f/116.0f)); fy = ((fy > 0.008856f)? Mathf.Pow(fy, (1.0f/3.0f)) : (7.787f*fy + 16.0f/116.0f)); fz = ((fz > 0.008856f)? Mathf.Pow(fz, (1.0f/3.0f)) : (7.787f*fz + 16.0f/116.0f)); lab.l = 116.0f * fy - 16f; lab.a = 500.0f * (fx - fy); lab.b = 200.0f * (fy - fz); return lab; }

// static function for converting from LABColor to Color public static Color ToColor(LABColor lab){ float D65x = 0.9505f; float D65y = 1.0f; float D65z = 1.0890f; float delta = 6.0f/29.0f; float fy = (lab.l+16f)/116.0f; float fx = fy + (lab.a/500.0f); float fz = fy - (lab.b/200.0f); float x = (fx > delta)? D65x * (fx*fx*fx) : (fx - 16.0f/116.0f)*3f*(delta*delta)*D65x; float y = (fy > delta)? D65y * (fy*fy*fy) : (fy - 16.0f/116.0f)*3f*(delta*delta)*D65y; float z = (fz > delta)? D65z * (fz*fz*fz) : (fz - 16.0f/116.0f)*3f*(delta*delta)*D65z; float r = x*3.2410f - y*1.5374f - z*0.4986f; float g = -x*0.9692f + y*1.8760f - z*0.0416f; float b = x*0.0556f - y*0.2040f + z*1.0570f; r = (r<=0.0031308f)? 12.92f*r : (1f+0.055f)* Mathf.Pow(r, (1.0f/2.4f)) - 0.055f; g = (g<=0.0031308f)? 12.92f*g : (1f+0.055f)* Mathf.Pow(g, (1.0f/2.4f)) - 0.055f; b = (b<=0.0031308f)? 12.92f*b : (1f+0.055f)* Mathf.Pow(b, (1.0f/2.4f)) - 0.055f; r = (r<0)? 0 : r; g = (g<0)? 0 : g; b = (b<0)? 0 : b; return new Color(r, g, b); }

// function for converting an instance of LABColor to Color public Color ToColor(){ return LABColor.ToColor(this); }

// override for string public override string ToString(){ return "L:"+l+" A:"+a+" B:"+b; }

// are two LABColors the same? public override bool Equals(System.Object obj){ if(obj==null || GetType()!=obj.GetType()) return false; return (this == (LABColor)obj); }

// override hashcode for a LABColor public override int GetHashCode(){ return l.GetHashCode() ^ a.GetHashCode() ^ b.GetHashCode(); }

// Equality operator public static bool operator ==(LABColor item1, LABColor item2){ return (item1.l == item2.l && item1.a == item2.a && item1.b == item2.b); }

// Inequality operator public static bool operator !=(LABColor item1, LABColor item2){ return (item1.l != item2.l || item1.a != item2.a || item1.b != item2.b); } } </csharp>

Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox