Skip to content

Instantly share code, notes, and snippets.

@arif-pandu
Created August 24, 2023 05:50
Show Gist options
  • Save arif-pandu/1e1888a6119eeeafbb5f39d3622b5cfe to your computer and use it in GitHub Desktop.
Save arif-pandu/1e1888a6119eeeafbb5f39d3622b5cfe to your computer and use it in GitHub Desktop.
Combine 2 HSL Colors in C#
using UnityEngine;
using System.Collections.Generic;
public class ColorCombination : MonoBehaviour
{
public Material newMaterial;
private void OnCollisionEnter(Collision collision)
{
Renderer renderer = collision.gameObject.GetComponent<Renderer>();
ClayObject clayObject = collision.gameObject.GetComponent<ClayObject>();
if (renderer != null && newMaterial != null && !collision.gameObject.CompareTag("Ground") && clayObject != null)
{
if (clayObject.objectColor != Color.clear)
{
List<Color> listColors = new List<Color>();
listColors.Add(clayObject.objectColor);
listColors.Add(newMaterial.color);
Color averageColor = CalculateAverageColor(listColors);
clayObject.objectColor = averageColor;
renderer.material.color = averageColor;
}
else
{
clayObject.objectColor = newMaterial.color;
renderer.material.color = newMaterial.color;
}
}
Destroy(gameObject);
}
string ColorToHex(Color color)
{
int r = Mathf.RoundToInt(color.r * 255);
int g = Mathf.RoundToInt(color.g * 255);
int b = Mathf.RoundToInt(color.b * 255);
int a = Mathf.RoundToInt(color.a * 255);
return string.Format("#{0:X2}{1:X2}{2:X2}{3:X2}", r, g, b, a);
}
public static Color CalculateAverageColor(List<Color> colors)
{
if (colors == null || colors.Count == 0)
{
return Color.black;
}
// Initialize total H, S, and L values
List<float> totalH = new List<float>();
float totalS = 0f;
float totalL = 0f;
foreach (Color color in colors)
{
// Convert RGB to HSL
RGBToHSL(color, out float h, out float s, out float l);
// Accumulate H, S, and L values
totalH.Add(h);
totalS += s;
totalL += l;
}
float averageH = CountHValue(totalH);
float averageS = totalS / 2;
float averageL = totalL / 2;
string hDebug = string.Join(", ", totalH);
Debug.Log("(" + hDebug + ") => " + averageH);
// Convert average HSL back to RGB
Color averageColor = HSLToRGB(averageH, averageS, averageL);
return averageColor;
}
// Helper function to convert RGB to HSL
public static void RGBToHSL(Color rgb, out float h, out float s, out float l)
{
float r = rgb.r;
float g = rgb.g;
float b = rgb.b;
float max = Mathf.Max(r, Mathf.Max(g, b));
float min = Mathf.Min(r, Mathf.Min(g, b));
// Calculate lightness
l = (max + min) / 2;
if (max == min)
{
// Grayscale
h = 0;
s = 0;
}
else
{
// Calculate saturation
if (l < 0.5f)
{
s = (max - min) / (max + min);
}
else
{
s = (max - min) / (2.0f - max - min);
}
// Calculate hue
if (max == r)
{
h = (g - b) / (max - min);
}
else if (max == g)
{
h = 2.0f + (b - r) / (max - min);
}
else
{
h = 4.0f + (r - g) / (max - min);
}
h *= 60;
if (h < 0)
{
h += 360;
}
}
}
// Helper function to convert HSL to RGB
public static Color HSLToRGB(float h, float s, float l)
{
float r, g, b;
if (s == 0)
{
// Grayscale
r = g = b = l;
}
else
{
float q = l < 0.5f ? l * (1.0f + s) : l + s - l * s;
float p = 2.0f * l - q;
r = HueToRGB(p, q, h + 120);
g = HueToRGB(p, q, h);
b = HueToRGB(p, q, h - 120);
}
return new Color(r, g, b);
}
private static float HueToRGB(float p, float q, float t)
{
if (t < 0) t += 360;
if (t >= 360) t -= 360;
if (t < 60) return p + (q - p) * t / 60;
if (t < 180) return q;
if (t < 240) return p + (q - p) * (240 - t) / 60;
return p;
}
private static float CountHValue(List<float> doubleH)
{
float smallestH = Mathf.Min(doubleH.ToArray());
float highestH = Mathf.Max(doubleH.ToArray());
float distanceA = Mathf.Abs(highestH - smallestH);
float distanceB = 360 - distanceA;
if (doubleH.Count == 2)
{
if (distanceA <= distanceB)
{
smallestH += (distanceA / 2);
return smallestH;
}
else
{
highestH += (distanceB / 2);
return highestH;
}
}
return 0f;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment