基于compute shader生成热力图

Requirements

  • 由离散的测温点得到炉体表面的热力图
  • 测温点分布不均匀,数量较多(如下图)

Blender中程序化生成的测温点

Solution

我们采用反距离权重差值(IDW)生成连续的热力图。受炉体结构的对称性影响,直接应用三维空间的欧氏距离计算的结果有较大偏差。因此我们将测温点的三维坐标映射成二维坐标,其中是的角度(z轴为0度),是高度。这样整个模型表面即被展开在角度和高度张成的二维平面。这样角度和高度即可以代替UV坐标进行采样。

ComputeShader

  • :测温点向量(x/y/z对于角度/高度/温度)
  • :贴图分辨率,最大高度,用于坐标映射
  • :IDW参数
  • :温度区间,用于归一化
  1. 将thread id转换为高度角度

  2. 在遍历每个温度点计算权重时,为避免0°和360°交界处不平滑,角度差应调整到0-180°之间,则角度差应为(表示第测温点)

    的最终权重为

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
float2 coord = float2(id.x * 360 / xRes, id.y * yHeight / yRes);

float nominator = 0;
float denominator = 0;

for (int i = 0; i < len; i++)
{
float dx = abs(coord.x - points[i].x);
dx = dx > 180 ? 360 - dx : dx;
float dy = coord.y - points[i].y;
float dis = sqrt(dx * dx + dy * dy) + s);
float inv_w = pow(dis, p);
nominator += points[i].z / inv_w;
denominator += 1 / inv_w;
}

float value = nominator / denominator;
value = (value - tmin) / (tmax - tmin);

STEPS

  • Initialize:Including parameters for both compute shader and material, RenderTexture & ComputeBuffer.
  • Dispatch Compute Shader
  • Assign RenderTexture to Material.
  • Release buffer.
  • Convert to Texture2D for inverse-sampling(Mouse click interaction)

tips

由于角度和高度单位不一致,因此差距很大(值域在几度到几十度之间,最小值能到零点几米)。为了使得差值权重更合理,我们对高度乘上一个倍数以调整其值域。相应的,RenderTexture的分辨率和也需要同比例缩放(初始化阶段)。

Result

生成的RenderTexture(高度放大5倍)

在Fragment Shader中采用相同的方式,将世界空间的坐标转换为角度和高度进行采样,得到的r值作为uv再采样Gradient贴图,最后效果为

渲染效果图

Accuracy

差值后的结果与原始数据的对比