Unity中如何按百分比计算颜色差异实现相似度校验
Unity 颜色混合相似度校验方案
需求背景
开发中需要实现候选颜色混合匹配标准色的校验逻辑:
- 标准色定义为100%目标纯度
- 不需要完全RGB值相等,支持多色阶判定:相似度≥80%为合格,低于80%为不合格
- 需输出混合色与标准色的具体相似度百分比,覆盖近似色混合场景
已知示例参数
候选颜色数组
Color[] aColors = { new Color(1f, 1f, 0f), new Color(0.3f, 0.9f, 0f), new Color(1f, 0.6f, 0f), new Color(1f, 0f, 0f), new Color(0.5f,0f,0f), new Color(0.5f, 0f, 0.9f), new Color(0f, 0.3f, 0f)};
参考标准色
酸橙绿(Lime),色值:
Color(0.43f,0.74f,0f)
待覆盖混合场景
- 常规正确混合:黄色与绿色等比混合
// 注意原写法存在运算优先级问题,等比混合需补全括号 resultColor = (aColors[0] + aColors[1]) / 2; - 近似色混合:暗红色与绿色混合得到接近Lime的颜色,暗红色色值:
new Color(0.5f,0f,0f)
实现逻辑
直接用RGB欧氏距离计算的相似度不符合人眼感知,容易出现视觉上差异明显但计算相似度高、视觉上接近但相似度低的问题。采用人眼感知加权的差值计算即可满足普通玩法的判定需求,计算量小、结果贴合视觉判断:
- 先将混合色、参考色的R/G/B通道值钳制到0-1的合法区间,排除颜色混合时数值越界的干扰
- 按照人眼对三原色的敏感度分配权重:绿色敏感度最高权重0.59,红色次之权重0.3,蓝色最低权重0.11
- 计算加权后的通道差值,映射为0-100%的相似度值,和阈值对比输出合格结果
可直接复用的代码
using UnityEngine; public static class ColorMatchValidator { /// <summary> /// 计算两个颜色的相似度 /// </summary> /// <param name="mixedColor">混合得到的待校验颜色</param> /// <param name="targetColor">标准参考色</param> /// <returns>相似度百分比,范围0-100,100为完全匹配</returns> public static float GetColorSimilarity(Color mixedColor, Color targetColor) { // 钳制通道值到合法范围 float rMixed = Mathf.Clamp01(mixedColor.r); float gMixed = Mathf.Clamp01(mixedColor.g); float bMixed = Mathf.Clamp01(mixedColor.b); float rTarget = Mathf.Clamp01(targetColor.r); float gTarget = Mathf.Clamp01(targetColor.g); float bTarget = Mathf.Clamp01(targetColor.b); // 人眼感知加权系数 const float rWeight = 0.3f; const float gWeight = 0.59f; const float bWeight = 0.11f; // 计算加权总差值 float totalDiff = rWeight * Mathf.Abs(rMixed - rTarget) + gWeight * Mathf.Abs(gMixed - gTarget) + bWeight * Mathf.Abs(bMixed - bTarget); // 转换为百分比相似度 return Mathf.Clamp((1f - totalDiff) * 100f, 0f, 100f); } /// <summary> /// 校验混合色是否达到合格要求 /// </summary> /// <param name="mixedColor">待校验混合色</param> /// <param name="targetColor">标准参考色</param> /// <param name="passThreshold">合格相似度阈值,默认80%</param> /// <returns>true为合格,false为不合格</returns> public static bool IsColorMatchPass(Color mixedColor, Color targetColor, float passThreshold = 80f) { return GetColorSimilarity(mixedColor, targetColor) >= passThreshold; } }
使用说明
- 代码为静态工具类,直接调用
ColorMatchValidator.GetColorSimilarity即可拿到具体相似度,调用IsColorMatchPass即可直接拿到合格判定结果 - 80%的默认阈值可以根据项目美术的实际视觉效果微调,上下浮动2%-5%都属于正常调整范围
- 如果是对色彩精度要求极高的场景,可以替换为CIEDE2000色差算法(需先将RGB转换为Lab颜色空间),计算精度更高但性能消耗略大,普通休闲游戏玩法用上述加权方案完全足够
- 颜色混合时注意运算优先级,多色等比混合时一定要给加法运算加括号后再除以颜色数量,避免比例计算错误
内容的提问来源于stack exchange,提问作者Vitaliy Radchuk
相关产品推荐
相关产品推荐

