public override UnityEngine.Color GetColour(double x, double y) { // Read H: float h = (float)HueModule.GetValue(x, y); // Read S: float s = (float)SaturationModule.GetValue(x, y); // Read Y: float ly = (float)LightModule.GetValue(x, y); // Convert to RGB: HsyRgb.ToRgb(ref h, ref s, ref ly); // Now RGB. return(new Color(h, s, ly, 1f)); }
public override UnityEngine.Color GetColour(double x, double y) { // Read colour: UnityEngine.Color col1 = SourceModule1.GetColour(x, y); // Read colour: UnityEngine.Color col2 = SourceModule2.GetColour(x, y); // Blend factor is.. float dstA = col1.a; float srcA = (float)WeightModule.GetColour(x, y).r *col2.a; switch (Mode) { case BlendingMode.Normal: // Do nothing here - we just alpha blend. break; case BlendingMode.Darken: // Pick the smallest of the two and set col2: if (col1.r < col2.r) { col2.r = col1.r; } if (col1.g < col2.g) { col2.g = col1.g; } if (col1.b < col2.b) { col2.b = col1.b; } break; case BlendingMode.Multiply: col2.r *= col1.r; col2.g *= col1.g; col2.b *= col1.b; break; case BlendingMode.ColourBurn: col2.r = 1f - ((1f - col1.r) / col2.r); col2.g = 1f - ((1f - col1.g) / col2.g); col2.b = 1f - ((1f - col1.b) / col2.b); break; case BlendingMode.LinearBurn: col2.r += col1.r - 1f; col2.g += col1.g - 1f; col2.b += col1.b - 1f; break; case BlendingMode.Lighten: // Pick the biggest of the two and set col2: if (col1.r > col2.r) { col2.r = col1.r; } if (col1.g > col2.g) { col2.g = col1.g; } if (col1.b > col2.b) { col2.b = col1.b; } break; case BlendingMode.Screen: col2.r = 1f - (1f - col1.r) * (1f - col2.r); col2.g = 1f - (1f - col1.g) * (1f - col2.g); col2.b = 1f - (1f - col1.b) * (1f - col2.b); break; case BlendingMode.ColourDodge: // Bottom layer / (inverted Top layer) if (col2.r != 1f) { col2.r = col1.r / (1f - col2.r); } if (col2.g != 1f) { col2.g = col1.g / (1f - col2.g); } if (col2.b != 1f) { col2.b = col1.b / (1f - col2.b); } break; case BlendingMode.LinearDodge: // Sum the two layers: col2.r += col1.r; col2.g += col1.g; col2.b += col1.b; break; case BlendingMode.Overlay: if (col1.r < 0.5f) { col2.r = 2f * col1.r * col2.r; } else { col2.r = 1f - 2f * (1f - col1.r) * (1f - col2.r); } if (col1.g < 0.5f) { col2.g = 2f * col1.g * col2.g; } else { col2.g = 1f - 2f * (1f - col1.g) * (1f - col2.g); } if (col1.b < 0.5f) { col2.b = 2f * col1.b * col2.b; } else { col2.b = 1f - 2f * (1f - col1.b) * (1f - col2.b); } break; case BlendingMode.SoftLight: // W3C soft light blend here. float g; float a; float b; a = col1.r; b = col2.r; if (b <= 0.5f) { col2.r = a - (1f - 2f * b) * a * (1f - a); } else { if (a <= 0.25f) { g = ((16f * a - 12f) * a + 4f) * a; } else { g = (float)System.Math.Sqrt(a); } col2.r = a + (2f * b - 1f) * (g - a); } a = col1.g; b = col2.g; if (b <= 0.5f) { col2.g = a - (1f - 2f * b) * a * (1f - a); } else { if (a <= 0.25f) { g = ((16f * a - 12f) * a + 4f) * a; } else { g = (float)System.Math.Sqrt(a); } col2.g = a + (2f * b - 1f) * (g - a); } a = col1.b; b = col2.b; if (b <= 0.5f) { col2.b = a - (1f - 2f * b) * a * (1f - a); } else { if (a <= 0.25f) { g = ((16f * a - 12f) * a + 4f) * a; } else { g = (float)System.Math.Sqrt(a); } col2.b = a + (2f * b - 1f) * (g - a); } break; case BlendingMode.HardLight: if (col2.r < 0.5f) { col2.r = 2f * col2.r * col1.r; } else { col2.r = 1f - 2f * (1f - col2.r) * (1f - col1.r); } if (col2.g < 0.5f) { col2.g = 2f * col2.g * col1.g; } else { col2.g = 1f - 2f * (1f - col2.g) * (1f - col1.g); } if (col2.b < 0.5f) { col2.b = 2f * col2.b * col1.b; } else { col2.b = 1f - 2f * (1f - col2.b) * (1f - col1.b); } break; case BlendingMode.VividLight: if (col2.r < 0.5f) { // Colour Burn col2.r = 1f - ((1f - col1.r) / col2.r); } else { // Colour Dodge col2.r = col1.r / (1f - col2.r); } if (col2.g < 0.5f) { // Colour Burn col2.g = 1f - ((1f - col1.g) / col2.g); } else { // Colour Dodge col2.g = col1.g / (1f - col2.g); } if (col2.b < 0.5f) { // Colour Burn col2.b = 1f - ((1f - col1.b) / col2.b); } else { // Colour Dodge col2.b = col1.b / (1f - col2.b); } break; case BlendingMode.LinearLight: if (col2.r < 0.5f) { // Linear Burn col2.r += col1.r - 1f; } else { // Linear Dodge col2.r += col1.r; } if (col2.g < 0.5f) { // Linear Burn col2.g += col1.g - 1f; } else { // Linear Dodge col2.g += col1.g; } if (col2.b < 0.5f) { // Linear Burn col2.b += col1.b - 1f; } else { // Linear Dodge col2.b += col1.b; } break; case BlendingMode.Hue: // Top layers hue and the sat/lum from bottom layer. float s = col1.r; float l = col1.g; HsyRgb.ToSatLum(ref s, ref l, col1.b); // Top hue: float h = HsyRgb.Hue(col2.r, col2.g, col2.b); // Recombine to RGB. HsyRgb.ToRgb(ref h, ref s, ref l); // They're now RGB. col2.r = h; col2.g = s; col2.b = l; break; case BlendingMode.Saturation: // Top layers saturation and the hue/lum from bottom layer. h = col1.r; l = col1.g; HsyRgb.ToHueLum(ref h, ref l, col1.b); // Top saturation: s = HsyRgb.Saturation(col2.r, col2.g, col2.b); // Recombine to RGB. HsyRgb.ToRgb(ref h, ref s, ref l); // They're now RGB. col2.r = h; col2.g = s; col2.b = l; break; case BlendingMode.Colour: // Top layers hue/sat and the luminosity from bottom layer. h = col2.r; s = col2.g; HsyRgb.ToHueSat(ref h, ref s, col2.b); // Bottom luminosity: l = HsyRgb.Luminance(col1.r, col1.g, col1.b); // Recombine to RGB. HsyRgb.ToRgb(ref h, ref s, ref l); // They're now RGB. col2.r = h; col2.g = s; col2.b = l; break; case BlendingMode.Luminosity: // Top layers luminosity and the hue/sat from bottom layer. h = col1.r; s = col1.g; HsyRgb.ToHueSat(ref h, ref s, col1.b); // Top luminosity: l = HsyRgb.Luminance(col2.r, col2.g, col2.b); // Recombine to RGB. HsyRgb.ToRgb(ref h, ref s, ref l); // They're now RGB. col2.r = h; col2.g = s; col2.b = l; break; case BlendingMode.Divide: // Bottom layer / Top layer if (col2.r != 0f) { col2.r = col1.r / col2.r; } if (col2.g != 0f) { col2.g = col1.g / col2.g; } if (col2.b != 0f) { col2.b = col1.b / col2.b; } break; case BlendingMode.Subtract: // Subtract: col2.r = (col1.r - col2.r); col2.g = (col1.g - col2.g); col2.b = (col1.b - col2.b); break; case BlendingMode.Difference: case BlendingMode.Exclusion: // Subtract: g = (col1.r - col2.r); if (g < 0f) { col2.r = -g; } else { col2.r = g; } g = (col1.g - col2.g); if (g < 0f) { col2.g = -g; } else { col2.g = g; } g = (col1.b - col2.b); if (g < 0f) { col2.b = -g; } else { col2.b = g; } break; case BlendingMode.HardMix: // Linear light first: if (col2.r < 0.5f) { // Linear Burn col2.r += col1.r - 1f; } else { // Linear Dodge col2.r += col1.r; } if (col2.g < 0.5f) { // Linear Burn col2.g += col1.g - 1f; } else { // Linear Dodge col2.g += col1.g; } if (col2.b < 0.5f) { // Linear Burn col2.b += col1.b - 1f; } else { // Linear Dodge col2.b += col1.b; } // Threshold: if (col2.r < 0.5f) { col2.r = 0f; } else { col2.r = 1f; } if (col2.g < 0.5f) { col2.g = 0f; } else { col2.g = 1f; } if (col2.b < 0.5f) { col2.b = 0f; } else { col2.b = 1f; } break; case BlendingMode.PinLight: if (col2.r < 0.5f) { // Darken if (col1.r < col2.r) { col2.r = col1.r; } } else { // Lighten if (col1.r > col2.r) { col2.r = col1.r; } } if (col2.g < 0.5f) { // Darken if (col1.g < col2.g) { col2.g = col1.g; } } else { // Lighten if (col1.g > col2.g) { col2.g = col1.g; } } if (col2.b < 0.5f) { // Darken if (col1.b < col2.b) { col2.b = col1.b; } } else { // Lighten if (col1.b > col2.b) { col2.b = col1.b; } } break; case BlendingMode.LighterColor: // Like lighten but applies to the composite channel. float total1 = col1.r + col1.g + col1.b; float total2 = col2.r + col2.g + col2.b; if (total1 > total2) { // Blend will do nothing: col1.a = srcA + dstA * (1f - srcA); return(col1); } break; case BlendingMode.DarkerColor: // Like darken but applies to the composite channel. total1 = col1.r + col1.g + col1.b; total2 = col2.r + col2.g + col2.b; if (total1 < total2) { // Blend will do nothing: col1.a = srcA + dstA * (1f - srcA); return(col1); } break; } // Time to alpha blend! if (srcA == 1f) { // Just foreground: col2.a = 1f; return(col2); } float dstAinvSrc = dstA * (1f - srcA); float outA = srcA + dstAinvSrc; if (outA == 0f) { col1.r = 0f; col1.g = 0f; col1.b = 0f; } else { col1.r = ((col2.r * srcA) + (col1.r * dstAinvSrc)) / outA; col1.g = ((col2.g * srcA) + (col1.g * dstAinvSrc)) / outA; col1.b = ((col2.b * srcA) + (col1.b * dstAinvSrc)) / outA; } col1.a = outA; return(col1); }