Unity 热力图建立方法

Unity 热力图建立方法

实现效果


工程文件下载

基本思路

之前有写过用网格顶点赋值颜色生成热力图的方法。有一个很大的缺点,需要大量的网格点支持,提高了GPU的渲染压力。所以换了一个思路,直接创建并修改图片像素的颜色,这样只需要四个顶点的网格就可以承载热力图的生成。

计算前fbs→97.5

计算后fbs→96.5

基本不受影响。

解决问题及办法

  1. 世界坐标和像素坐标的转换;

  2. 像素的初始化及像素的加权值;

  3. 色块的颜色和影响范围关系的配置;

  4. 分辨率和性能的调节。

世界坐标和像素坐标的转换

这里有两个注意点,一是网格的轴心点,二是uv的坐标轴。网格的原点是模型美术规定的,但是在世界坐标转像素坐标时,需要将原点对应,所以要改变一下网格的原点。改变原点有两种方式,1.让美术修改,将网格的原点改成uv坐标系的原点;2.给网格加一个父物体,父物体的位置在网格的uv坐标原点。如下图所示

完成原点对齐后,自需要求出比例就可以。

            Vector3 modelSize = gameObject.GetComponent<Collider>().bounds.size;
            float MapRatio = heatMapBase.Resolution / modelSize.x;
            //heatMapBase.Resolution是定义的图片像素分辨率。
            //MapRatio是图片坐标和世界坐标转换的比例
像素的初始化及像素的加权值

运行之前要先把所以像素的权值全部归零。带权的参考点会对周围的像素点进行影响,影响的范围和自身的权值有关,这里还可以引入一个变量DisRatio,用于改变权值的影响范围。给像素赋权值的时,只能值覆盖小值。

 //每个像素初始化
            List<Vector2> my_Pixels = new List<Vector2>();
            List<float> my_Values = new List<float>();
            for (int y = 0; y < texture.height; y++)
            {
                for (int x = 0; x < texture.width; x++)
                {

                    Vector2 pixel = new Vector2(x, y);
                    my_Pixels.Add(pixel);
                    my_Values.Add(0);
                }
            }
            int allLength = my_Pixels.Count;//所以像素点数量
            int pointLength = heatMapInfos.Count;//热力图兴趣点点数量
            int colorLength = heatMapBase.HeatMapInfos.Count;//色块等级
            //每个像素加权值
            for (int p = 0; p < pointLength; p++)
            {
                for (int a = 0; a < allLength; a++)
                {
                    float my_Distance = Vector2.Distance(heatMapInfos[p].Pixel* MapRatio, my_Pixels[a]);

                    float my_MaxDis = heatMapBase.DisRatio * heatMapInfos[p].Amount;

                    if (my_Distance < my_MaxDis)
                    {

                        float value = (1 - (Mathf.Pow(my_Distance, 2) / Mathf.Pow(my_MaxDis, 2))) * heatMapInfos[p].Amount;
                        if (value > my_Values[a])
                        {
                            my_Values[a] = value;
                        }
                    }
                }
            }
色块的颜色和影响范围关系的配置

色块的颜色选取,权值,图片的分辨率和影响范围是动态可以配置的。这里加一个模板用来控制。为了方便像素颜色的赋值,规定权值由大到小填入。

    public class HeatMapBase : ScriptableObject
    {
        public float DisRatio;//距离比例
        public float Resolution;//分辨率
        public List<HeatMapInfo> HeatMapInfos;
   
        [Serializable]
        public class HeatMapInfo
        {
            public float MaxAmount;//最大权值
            public Color Color;//颜色
        }
    }
分辨率和性能的调节

在编写之初,考虑动态改变分辨率,网格越大分辨率越大。但这个无疑是增加了性能的消耗。所以考虑将分辨率写入配置表。转而出现了图片大范围的锯齿如下图。后面引入了color的插值运算,完美解决问题。

不加插值

加插值

  //每个像素赋值颜色
            for (int i = 0; i < allLength; i++)
            {
                for (int j = 0; j < colorLength; j++)
                {
                    float my_CurMaxAmount = heatMapBase.HeatMapInfos[j].MaxAmount;
                  
                    if (my_Values[i] >= my_CurMaxAmount)
                    {
                        //当前块的颜色
                        Color my_CurColor = heatMapBase.HeatMapInfos[j].Color;

                        if (j != 0)
                        {

                            float my_UpDiffValue = heatMapBase.HeatMapInfos[j - 1].MaxAmount - my_CurMaxAmount;
                            Color my_UpColor = heatMapBase.HeatMapInfos[j - 1].Color;

                            float t = (my_Values[i] - my_CurMaxAmount) / my_UpDiffValue;
                            texture.SetPixel((int)my_Pixels[i].x, (int)my_Pixels[i].y, Color.Lerp(my_CurColor, my_UpColor, t));
                            break;
                        }
                        else
                        {
                            texture.SetPixel((int)my_Pixels[i].x, (int)my_Pixels[i].y, my_CurColor);
                            break;
                        }
                    }
                }
            }
  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
Unity热力图生成算法是一种通过收集和分析大量数据来生成可视化热力图的算法。热力图用不同颜色的热点表示特定区域的数据密集程度,由此可以有效地展示出数据的分布情况和热点区域。 在Unity中,热力图生成算法通常包括以下步骤: 1. 数据收集:首先需要收集与热力图相关的数据。这些数据可以来自用户行为、传感器数据或其他来源。数据可以是离散的,如坐标点或事件发生次数,也可以是连续的,如数值或颜色。 2. 数据归一化:归一化是将原始数据转化为统一的数值范围,以便数据能够在热力图中呈现。这样可以确保每个数据点的权重相对均衡。 3. 热力图网格划分:将数据点分布的区域划分为网格,每个网格表示一个区域。网格的大小可以根据需求进行调整,较小的网格可以提供更精确的热力图细节,而较大的网格可以加快计算速度。 4. 热力值计算:对于每个网格,根据其包含的数据点进行热力值的计算。常见的计算方法是根据数据点的距离、权重或频率来决定热力值。 5. 热力图渲染:将计算得到的热力图数据转化为可视化的图像。通常使用渐变色来表示热力值的不同程度,如使用红色表示高热力值,蓝色表示低热力值。 6. 显示与交互:最后,将生成的热力图Unity中的场景进行融合,使用户可以通过交互方式与热力图进行互动。这可以包括添加标签、放大、缩小或导航等功能,以使热力图更加易于理解和使用。 通过以上步骤,Unity热力图生成算法可以将大量数据转化为直观的热力图,帮助用户更好地理解数据分布和趋势,从而做出有效的决策或优化操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小生云木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值