Меня также заинтересовало, чтобы это работало.
Я использовал этот трих пример и увидел, что эти две строки были необходимы:
var glowMesh = new THREEx.GeometricGlowMesh(mesh)
mesh.add(glowMesh.object3d)
Объедините это с этим примером 3d-графика силы для пользовательской геометрии узла.
Вся базовая c рабочая вещь приведена ниже:
// Random tree data
var generateData = function() {
const N = 50;
const gData = {
nodes: [...Array(N).keys()].map(i => ({ id: i })),
links: [...Array(N).keys()]
.filter(id => id)
.map(id => ({
source: id,
target: Math.round(Math.random() * (id-1))
}))
};
return gData;
}
// Create a three.js sphere mesh.
var sphereMesh = function(id) {
var mesh = new THREE.Mesh(
[
new THREE.SphereGeometry(10, 32, 32)
][id%1],
new THREE.MeshLambertMaterial({
color: '#277ec9',
transparent: true,
opacity: 1.0
})
)
// Make it glow.
var glowMesh = new THREEx.GeometricGlowMesh(mesh);
mesh.add(glowMesh.object3d);
var insideUniforms = glowMesh.insideMesh.material.uniforms;
insideUniforms.glowColor.value.set('yellow');
var outsideUniforms = glowMesh.outsideMesh.material.uniforms;
outsideUniforms.glowColor.value.set('yellow');
return mesh
}
const Graph = ForceGraph3D()
(document.getElementById('3d-graph'))
.graphData(generateData())
.nodeThreeObject(({ id }) => sphereMesh(id))
.nodeLabel('id');
/*
The following three snippets of code are the minimum required from the THREEx library.
*/
// ========== threex.dilategeometry.js =============
/**
* @namespace
*/
var THREEx = THREEx || {}
/**
* dilate a geometry inplace
* @param {THREE.Geometry} geometry geometry to dilate
* @param {Number} length percent to dilate, use negative value to erode
*/
THREEx.dilateGeometry = function(geometry, length){
// gather vertexNormals from geometry.faces
var vertexNormals = new Array(geometry.vertices.length);
geometry.faces.forEach(function(face){
if( face instanceof THREE.Face4 ){
vertexNormals[face.a] = face.vertexNormals[0];
vertexNormals[face.b] = face.vertexNormals[1];
vertexNormals[face.c] = face.vertexNormals[2];
vertexNormals[face.d] = face.vertexNormals[3];
}else if( face instanceof THREE.Face3 ){
vertexNormals[face.a] = face.vertexNormals[0];
vertexNormals[face.b] = face.vertexNormals[1];
vertexNormals[face.c] = face.vertexNormals[2];
}else console.assert(false);
});
// modify the vertices according to vertextNormal
geometry.vertices.forEach(function(vertex, idx){
var vertexNormal = vertexNormals[idx];
vertex.x += vertexNormal.x * length;
vertex.y += vertexNormal.y * length;
vertex.z += vertexNormal.z * length;
});
};
// ========== threex.atmospherematerial.js =============
var THREEx = THREEx || {}
/**
* from http://stemkoski.blogspot.fr/2013/07/shaders-in-threejs-glow-and-halo.html
* @return {[type]} [description]
*/
THREEx.createAtmosphereMaterial = function(){
var vertexShader = [
'varying vec3 vVertexWorldPosition;',
'varying vec3 vVertexNormal;',
'varying vec4 vFragColor;',
'void main(){',
' vVertexNormal = normalize(normalMatrix * normal);',
' vVertexWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;',
' // set gl_Position',
' gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);',
'}',
].join('\n')
var fragmentShader = [
'uniform vec3 glowColor;',
'uniform float coeficient;',
'uniform float power;',
'varying vec3 vVertexNormal;',
'varying vec3 vVertexWorldPosition;',
'varying vec4 vFragColor;',
'void main(){',
' vec3 worldCameraToVertex= vVertexWorldPosition - cameraPosition;',
' vec3 viewCameraToVertex = (viewMatrix * vec4(worldCameraToVertex, 0.0)).xyz;',
' viewCameraToVertex = normalize(viewCameraToVertex);',
' float intensity = pow(coeficient + dot(vVertexNormal, viewCameraToVertex), power);',
' gl_FragColor = vec4(glowColor, intensity);',
'}',
].join('\n')
// create custom material from the shader code above
// that is within specially labeled script tags
var material = new THREE.ShaderMaterial({
uniforms: {
coeficient : {
type : "f",
value : 1.0
},
power : {
type : "f",
value : 2
},
glowColor : {
type : "c",
value : new THREE.Color('pink')
},
},
vertexShader : vertexShader,
fragmentShader : fragmentShader,
//blending : THREE.AdditiveBlending,
transparent : true,
depthWrite : false,
});
return material
}
// ========== threex.geometricglowmesh.js =============
var THREEx = THREEx || {}
THREEx.GeometricGlowMesh = function(mesh){
var object3d = new THREE.Object3D
var geometry = mesh.geometry.clone()
THREEx.dilateGeometry(geometry, 0.01)
var material = THREEx.createAtmosphereMaterial()
material.uniforms.glowColor.value = new THREE.Color('cyan')
material.uniforms.coeficient.value = 1.1
material.uniforms.power.value = 1.4
var insideMesh = new THREE.Mesh(geometry, material );
object3d.add( insideMesh );
var geometry = mesh.geometry.clone()
THREEx.dilateGeometry(geometry, 0.1)
var material = THREEx.createAtmosphereMaterial()
material.uniforms.glowColor.value = new THREE.Color('cyan')
material.uniforms.coeficient.value = 0.1
material.uniforms.power.value = 1.2
material.side = THREE.BackSide
var outsideMesh = new THREE.Mesh( geometry, material );
object3d.add( outsideMesh );
// expose a few variable
this.object3d = object3d
this.insideMesh = insideMesh
this.outsideMesh= outsideMesh
}
<script src="https://threejs.org/build/three.js"></script>
<head>
<style> body { margin: 0; } </style>
<script src="//unpkg.com/3d-force-graph"></script>
</head>
<body>
<div id="3d-graph"></div>
</body>
То же самое относится к jsfiddle . Вы можете увидеть результаты лучше здесь.