【问题标题】:Is there any way/shader for generating 3d heatmap in Unity WebGL?有什么方法/着色器可以在 Unity WebGL 中生成 3d 热图?
【发布时间】:2019-10-22 12:04:09
【问题描述】:

我正在 Unity-Webgl 中开展一个项目,该项目将不同位置的温度传感器值编码为建筑物的 3d 热图。我曾尝试使用粒子系统和着色器根据这些值对粒子进行着色,但效果不是很理想。我现在正在寻找一种解决方案或着色器,它可以使用温度值(例如带颜色的体积照明)为半透明对象着色。它应该看起来像这样:example

我搜索了互联网,但发现许多体积着色器不支持 OpenGL 或仅支持单色。

我想知道是否有任何其他解决方案。提前感谢您的帮助!

【问题讨论】:

标签: unity3d glsl shader unity-webgl


【解决方案1】:

您不需要着色器来完成示例中的效果。您可以将热图数据的水平切片加载到纹理中,并将它们放在平面上。这是我创建的一个示例,它使用 perlin 噪声作为热量数据。你可以从这里https://github.com/keijiro/PerlinNoise获得perlin噪声函数

public class HeatmapBehavior : MonoBehaviour
{
    public int x_size = 128; //width of the textures
    public int y_size = 128; //height of the textures
    public int num_shells = 10; //number of slices of the data
    public GameObject plane_prefab; //the slice geometry and shader
                                    //this prefab is just a plane with the same area 
                                    //as the building, with a material that has its
                                    //shader set to Unlit/Transparent

    public float height = 10; //how tall in world units the dataset is
    public Color LowColor; //the cold color
    public Color HiColor; //the hot color

    void Start()
    {
        for (int i = 0; i < num_shells; i++)
        {

            var shell = GameObject.Instantiate(this.plane_prefab);  //create a slice
            shell.transform.parent = this.transform;
            shell.transform.position += new Vector3(0, (float)i / (float)this.num_shells * this.height, 0);

            var texture = new Texture2D(x_size, y_size);
            //for each texel in the shell's texture
            for(int x = 0; x < x_size; x++)
            {
                for(int y = 0; y < y_size; y++)
                {
                    var heatLocation = new Vector3((float)x / (float)x_size, (float)y / (float)y_size, (float)i / (float)num_shells); //find the coordinate in the heatmap for this texel
                    var heat = (Perlin.Fbm(heatLocation, 4) + 1)/2f; //grab the heat map data
                    texture.SetPixel(x, y, Color.Lerp(this.LowColor, this.HiColor, heat)); //interpolate the color based on heat map
                }
            }

            texture.Apply();


            shell.GetComponent<MeshRenderer>().material.SetTexture("_MainTex", texture);

        }
    }
}

如果您想在建筑物内的场景中交互式地飞来飞去,解决方案会更加复杂。您需要将外壳与相机对齐,根据相机视锥计算它们需要多大,并根据外壳的旋转方向对热图数据进行采样。

【讨论】:

  • 非常感谢您的回复!它有很大帮助。我已经在演示中尝试过,效果看起来非常理想。但是我在 WebGL 中遇到了一些 GL_INVALID_FRAMEBUFFER_OPERATION 错误。我想知道你是否有任何想法。
  • 奇怪的是在实际项目中可以,我一定是做错了什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-22
  • 1970-01-01
  • 2011-08-18
  • 2014-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多