这篇文章主要介绍一下如何使用three.js 制作拓扑图
three.js拓扑图
// 合并两张图片 img1、img2,其中图片占比 a:b(需要两张图片同高)
export function mergeImage(imgSrc1, imgSrc2, a, b) {
return new Promise((res) => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const img1 = new Image();
img1.src = imgSrc1;
img1.onload = function () {
const img2 = new Image();
img2.src = imgSrc2;
img2.onload = function () {
canvas.width = img1.width * a + img2.width * b;
canvas.height = img1.height;
ctx.rect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#fff';
ctx.fill();
let width = 0;
// 绘制img1
for (let i = 0; i < a; i++) {
ctx.drawImage(img1, width, 0, img1.width, img1.height);
width += img1.width;
}
// 绘制img2
for (let i = 0; i < b; i++) {
ctx.drawImage(img2, width, 0, img2.width, img2.height);
width += img2.width;
}
// 合并
const base64 = canvas.toDataURL('image/png');
res(base64);
};
};
});
}
import * as THREE from 'three';
// 高亮材质
export const activeModelMaterial = new THREE.MeshPhongMaterial({
color: '#66b1ff',
transparent: true,
opacity: 0.8
});
const vertexShader = [
'varying vec2 vUv;',
'void main()',
'{',
' vUv = uv;',
' vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );',
' gl_Position = projectionMatrix * mvPosition;',
'}'
].join('');
const fragmentShader = [
'uniform float r;',
'uniform float g;',
'uniform float b;',
'uniform float a;',
'uniform float distanceZ;',
'uniform float distanceX;',
'uniform float pulse;',
'uniform float speed;',
'varying vec2 vUv;',
'void main( void ) {',
' vec2 position = abs(-1.0 + 2.0 * vUv);',
' float edging = abs((pow(position.y, 5.0) + pow(position.x, 5.0)) / 2.0);',
' float perc = (0.2 * pow(speed + 1.0, 2.0) + edging * 0.8) * distanceZ * distanceX;',
' float red = r * perc + pulse;',
' float green = g * perc + pulse;',
' float blue = b * perc + pulse;',
' gl_FragColor = vec4(red, green, blue, a);',
'}'
].join('');
export const baseUniforms = {
r: { type: 'f', value: 0.1 },
g: { type: 'f', value: 0.1 },
b: { type: 'f', value: 0.8 },
a: { type: 'f', value: 1.0 },
distanceX: { type: 'f', value: 1 },
distanceZ: { type: 'f', value: 1 },
pulse: { type: 'f', value: 0.1 },
speed: { type: 'f', value: 0.5 }
};
export const waringUniforms = {
r: { type: 'f', value: 0.9 },
g: { type: 'f', value: 0.1 },
b: { type: 'f', value: 0.1 },
a: { type: 'f', value: 1.0 },
distanceX: { type: 'f', value: 1 },
distanceZ: { type: 'f', value: 1 },
pulse: { type: 'f', value: 0.1 },
speed: { type: 'f', value: 0.5 }
};
export const boxBaseMaterial = new THREE.ShaderMaterial({
uniforms: baseUniforms,
vertexShader: vertexShader,
fragmentShader: fragmentShader,
transparent: true,
opacity: 1
});
export const boxWaringMaterial = new THREE.ShaderMaterial({
uniforms: waringUniforms,
vertexShader: vertexShader,
fragmentShader: fragmentShader,
transparent: true,
opacity: 1
});
export function createLineMaterial(number, color) {
const shader = {
vs: `
varying vec2 v_uv;
varying float v_z;
void main() {
v_z = position.z;
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4( position, 1.0 );
}
`,
fs: `
uniform float number;
uniform vec3 color;
varying float v_z;
void main() {
if(v_z < number) {
gl_FragColor = vec4(color, 1.0);
}else{
gl_FragColor = vec4(1.0, 1.0, 1.0, 0.0);
}
}
`,
uniform: {
number: {
value: number
},
color: {
value: new THREE.Color(color)
}
}
};
return new THREE.ShaderMaterial({
vertexShader: shader.vs,
fragmentShader: shader.fs,
uniforms: shader.uniform,
transparent: true
});
}