Color extraction from Vertex/UV
Color extraction from Vertex/UV
This tool extract color from a mesh using its uv and get its world position to emit particles
C#, Unity
using System.Collections;using System.Collections.Generic;using UnityEngine;using System.Linq;[System.Serializable]public struct ColorAdjustParticle{ [Tooltip("Object that contains particle system component")] public GameObject Obj; [Tooltip("Color value level")] public bool SingleColor;}[System.Serializable]public struct ColorAdjustMesh{ [Tooltip("Object that contains particle system component")] public GameObject Obj;}[ExecuteInEditMode]public class ParticleTextureColor : MonoBehaviour { [Tooltip("Reference Card Texture")] public Texture2D TextureImg; [Tooltip("Mipmap Level of the Card Texture")] public bool UseMipmap = false; [Tooltip("Mipmap Level of the Card Texture")] public int MipmapLevel = 0; [Space(10)] [Tooltip("Particle systems that will be affected by this color module")] public ColorAdjustParticle[] ParticleObjs; [Space(10)] [Tooltip("Particle systems that will be affected by this color module")] public ColorAdjustMesh[] MeshObjs; private List<Color32> MostUsedColors = new List<Color32>(); private ParticleSystem.MainModule[] ParticleColorModules; private Material[] MeshMaterials; public Color32 C1; public Color32 C2; public float Saturation = 1.2f; public float Value = 2f; // Use this for initialization void Start() { //SetColors(); } public void SetDominantColors(Color32 c1, Color32 c2) { C1 = c1; C2 = c2; SetColors(); } void GetParticleModules() { //ParticleColorModules = new ParticleSystem.MainModule[ParticleObjs.Length]; List<ParticleSystem.MainModule> result = new List<ParticleSystem.MainModule>(); for (int i = 0; i < ParticleObjs.Length; i++) { GameObject obj = ParticleObjs[i].Obj; if (obj) { result.Add(obj.GetComponent<ParticleSystem>().main); } } ParticleColorModules = result.ToArray(); } public void SetColors() { MeshMaterials = new Material[MeshObjs.Length]; for (int i = 0; i < MeshObjs.Length; i++) { GameObject obj = MeshObjs[i].Obj; if (obj) { Renderer rend = obj.GetComponent<Renderer>(); MeshMaterials[i] = rend.sharedMaterial; } } for (int i = 0; i < MeshMaterials.Length; i++) { Color adjustedC1 = SaturateAdjust(C1, Saturation, Value); if (MeshMaterials[i] != null) { MeshMaterials[i].SetColor("_MasterColor", adjustedC1); } } GetParticleModules(); for (int i = 0; i < ParticleColorModules.Length; i++) { Color adjustedC1 = SaturateAdjust(C1, Saturation, Value); if (ParticleObjs[i].SingleColor) { ParticleColorModules[i].startColor = new ParticleSystem.MinMaxGradient(adjustedC1, adjustedC1); // random between 2 colors continue; } Color adjustedC2 = SaturateAdjust(C2, Saturation, Value); ParticleColorModules[i].startColor = new ParticleSystem.MinMaxGradient(adjustedC1, adjustedC2); // random between 2 colors } } int DeRes(float val, int count) { int i = 0; while (i < count) { val *= 0.5f; i++; } return Mathf.RoundToInt(val); } private Color32[] GetPixels() { if (UseMipmap) { return TextureImg.GetPixels32(MipmapLevel); // at mipmap level % } else { //TextureImg.GetPixel(1, 2); return new Color32[10]; // TODO : return randomized picked from texture 60~100 and get 2 dominant colors - not yet ready } } public void GetDominantColors() { int width = TextureImg.width; int height = TextureImg.height; Color32[] Colors; Colors = GetPixels(); if (MipmapLevel > 0) { width = DeRes(width, MipmapLevel + 1); height = DeRes(height, MipmapLevel + 1); } // does using Dictionary<Color,int> here // really pay-off compared to using // Dictionary<Color, int> ? // would using a SortedDictionary be much slower, or ? Dictionary<Color32, int> dctColorIncidence = new Dictionary<Color32, int>(); Color32 pixelColor; for (int row = 0; row < width; row++) { for (int col = 0; col < height; col++) { int index = row * 10 + col; pixelColor = Colors[index]; // divide by 8 to cluster better if (pixelColor.a < 0.01f) continue; pixelColor.r /= 8; pixelColor.g /= 8; pixelColor.b /= 8; if (dctColorIncidence.Keys.Contains(pixelColor)) { dctColorIncidence[pixelColor]++; } else { dctColorIncidence.Add(pixelColor, 1); } } } // note that there are those who argue that a // .NET Generic Dictionary is never guaranteed // to be sorted by methods like this var dctSortedByValueHighToLow = dctColorIncidence.OrderByDescending(x => x.Value).ToDictionary(x => x.Key, x => x.Value); // this should be replaced with some elegant Linq ? MostUsedColors.Clear(); foreach (KeyValuePair<Color32, int> kvp in dctSortedByValueHighToLow.Take(2)) { Color32 c = kvp.Key; MostUsedColors.Add(c); } } Color32 SaturateAdjust(Color32 color, float saturation, float value) { float H; float S; float V; Color.RGBToHSV(color, out H, out S, out V); S *= saturation; V *= value; return Color.HSVToRGB(H, S, V); }}