Threejs 高度热力图

10 篇文章 2 订阅
10 篇文章 0 订阅

Threejs 高度热力图

热力图是比较常见的一个应用场景,很多关于人流密度,受力应力云图,还有污染物的扩散图。如果是依照heatmapjs库的方式生成一个canvas做为纹理,贴在PlaneBufferGeometry上,但是这样是平面的,如果想要根据热力图数据的大小来生成一个带有高度的,好像没找到现成的,就自己写一个吧。效果如下:
在这里插入图片描述
实现比较核心的思路是:

1、根据灰度图中rgb某一个通道的值来在vertex shader中调整具体高度,其实也可以根据彩色图中的rgb值通过置灰的算法换算成对应高度,也行。

2、由于vertex shader是一个逐顶点计算,所以在生成PlaneBufferGeometry的时候要考虑多生成几份顶点。

具体实现核心代码如下:

自定义材质ShaderMaterial

// 自定义材质
  var material = new THREE.ShaderMaterial({
    // 用于给着色器中的uniform变量传值
    uniforms: THREE.UniformsUtils.merge([
      THREE.UniformsLib.common,
      THREE.UniformsLib.specularmap,
      THREE.UniformsLib.envmap,
      THREE.UniformsLib.aomap,
      THREE.UniformsLib.lightmap,
      THREE.UniformsLib.emissivemap,
      THREE.UniformsLib.bumpmap,
      THREE.UniformsLib.normalmap,
      THREE.UniformsLib.displacementmap,
      THREE.UniformsLib.gradientmap,
      THREE.UniformsLib.fog,
      THREE.UniformsLib.lights,
    {
      emissive: { value: new THREE.Color( 0x000000 ) },
      specular: { value: new THREE.Color( 0x111111 ) },
      shininess: { value: 30 },
      heatMap: { value: undefined }, // 热力图
      greyMap: { value: undefined }, // 灰度图
      Zscale: { value: 50.0 }, // Z方向上的缩放量
    }
    ]),
    vertexShader: THREE.ShaderChunk.meshphong_vert,
    fragmentShader: THREE.ShaderChunk.meshphong_frag
  });
  material.lights = true;

  let texture = new THREE.Texture(heatmap._config.container.children[0]);
  texture.needsUpdate = true;
  let texture2 = new THREE.Texture(greymap._config.container.children[0]);
  texture2.needsUpdate = true;
  material.uniforms.heatMap.value = texture;
  material.side = THREE.DoubleSide; // 双面渲染
  material.uniforms.greyMap.value = texture2;
  // 目前看分成300X300份
  var geometry = new THREE.PlaneBufferGeometry( 300, 300, 300, 300);
  var mesh = new THREE.Mesh( geometry, material );

生成热力图

需要引用heatmapjs库,具体代码如下:

// 热力图
   var heatmap = h337.create({
      container: document.getElementById('heatmap')
    });
    len = 100;
    width = 300;
    height = 300;
    points = [];
    max = 0;
    while (len--) {
      var val = Math.floor(Math.random()*100);
      max = Math.max(max, val);
      var point = {
        x: Math.floor(Math.random()*width),
        y: Math.floor(Math.random()*height),
        value: val
      };
      points.push(point);
    }
    heatmap.setData({
      max: max,
      data: points
    });
    // 灰度图
    var greymap = h337.create({
      container: document.getElementById('greymap'),
      gradient: {
        '0': 'black',
        '1.0': 'white'
      }
    });
    
    greymap.setData({
      max: max,
      data: points
    });

其中比较重要的是

修改THREE.ShaderChunk.meshphong_frag的源码

(…src\renderers\shaders\ShaderLib\meshphong_frag.glsl.js),修改的核心代码:

// 定义变量
uniform sampler2D heatMap;
varying vec2 vUVs;

.......

vec4 frgColor = texture2D(heatMap, vUVs);
gl_FragColor = frgColor;

修改THREE.ShaderChunk.meshphong_vert的源码

(…src\renderers\shaders\ShaderLib\meshphong_vert.glsl.js),修改的核心代码:


varying vec2 vUVs;
uniform float Zscale;

............

vUVs = uv;

修改THREE.ShaderChunk.begin_vertex的源码

(…src\renderers\shaders\ShaderChunk\begin_vertex.glsl.js),修改的核心代码:

vec4 frgColor = texture2D(greyMap, uv);
float height = Zscale * frgColor.a;
vec3 transformed = vec3( position.x, position.y, height);

在这里插入图片描述
在这里插入图片描述
这样就大功告成了。


BIM树洞

做一个静谧的树洞君

用建筑的语言描述IT事物;

用IT的思维解决建筑问题;

共建BIM桥梁,聚合团队。

本学习分享资料不得用于商业用途,仅做学习交流!!如有侵权立即删除!!


  • 微信公众号: BIM树洞
    在这里插入图片描述

  • 知乎专栏:BIM树洞

  • 气氛组博客:http://www.31bim.com

  • BIM应用及咨询,CAD,Revit, OpenGL,图形开发交流,加Q群1083064224

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值