Threejs 高度热力图
Posted BIM树洞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Threejs 高度热力图相关的知识,希望对你有一定的参考价值。
Author--------------- Yen
热力图是比较常见的一个应用场景,很多关于人流密度,受力应力云图,还有污染物的扩散图。如果是依照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 enderersshadersShaderLibmeshphong_frag.glsl.js),修改的核心代码:
// 定义变量
uniform sampler2D heatMap;
varying vec2 vUVs;
.......
vec4 frgColor = texture2D(heatMap, vUVs);
gl_FragColor = frgColor;
修改THREE.ShaderChunk.meshphong_vert的源码(..src enderersshadersShaderLibmeshphong_vert.glsl.js),修改的核心代码:
varying vec2 vUVs;
uniform float Zscale;
............
vUVs = uv;
修改THREE.ShaderChunk.begin_vertex的源码(..src enderersshadersShaderChunkegin_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桥梁,聚合团队。
本学习分享资料不得用于商业用途,仅做学习交流!!如有侵权立即删除!!
以上是关于Threejs 高度热力图的主要内容,如果未能解决你的问题,请参考以下文章