const particles = this.numNodesValue;
if (particles > 0) {
const particle_system_geometry = new THREE.BufferGeometry();
// Buffers
const positionBuffer = new Float32Array(new ArrayBuffer(particles 12)); // For positioning
const colorBuffer = new Uint8Array(new ArrayBuffer(particles 3)); // For giving color to nodes
const sizeBuffer = new Float32Array(new ArrayBuffer(particles 4)); // For giving size to nodes
const highlightBuffer = new Float32Array(new ArrayBuffer(particles 4)); // For giving highlight
const subjectsBuffer = new Float32Array(new ArrayBuffer(particles 4)); // For subjects
const selectedBuffer = new Float32Array(new ArrayBuffer(particles 4)); // For selected
this.radius = Math.min(1000, Math.max(100, Math.sqrt(particles Math.PI 20)));
this.innerDistance = Math.sqrt(Math.pow(this.radius - this.camera.position.x, 2) +
Math.pow(0 - this.camera.position.y, 2) + Math.pow(0 - this.camera.position.z, 2));
const dispersion = this.radiusDispersion;
for (let i = 0; i < particles; i++) {
let particularDispersion = 0;
if (dispersion > 0) {
particularDispersion = (((Math.ceil(Math.random() 11) - 1) / 10) dispersion) + Math.random(); // [0…1] * dispersion
}
highlightBuffer[i] = 1.0;
const angleX = (Math.random() - 0.5) 2 Math.PI;
const angleY = (Math.random() - 0.5) 2 Math.PI;
const posX = (this.radius + particularDispersion) Math.sin(angleX) Math.cos(angleY);
const posY = (this.radius + particularDispersion) Math.sin(angleX) Math.sin(angleY);
const posZ = (this.radius + particularDispersion) * Math.cos(angleX);
positionBuffer[(i 3)] = posX;
positionBuffer[(i 3) + 1] = posY;
positionBuffer[(i * 3) + 2] = posZ;
colorBuffer[(i 3)] = (Math.random() 255);
colorBuffer[(i 3) + 1] = (Math.random() 255);
colorBuffer[(i 3) + 2] = (Math.random() 255);
subjectsBuffer[i] = Math.random() < 0.3 ? 1.0 : 0.0;
selectedBuffer[i] = 0.0;
if (particularDispersion !== 0) {
sizeBuffer[i] = Math.floor((Math.pow(particularDispersion, 2) / Math.pow(dispersion, 2)) * this.sizeDiff);
} else {
sizeBuffer[i] = 0;
}
}
const nodeBufferPosition = new THREE.InterleavedBuffer(positionBuffer, 3);
const nodeBufferColor = new THREE.InterleavedBuffer(colorBuffer, 3);
const nodeBufferSize = new THREE.InterleavedBuffer(sizeBuffer, 1);
const nodeBufferHighlight = new THREE.InterleavedBuffer(highlightBuffer, 1);
const nodeBufferSubject = new THREE.InterleavedBuffer(subjectsBuffer, 1);
const nodeBufferSelected = new THREE.InterleavedBuffer(selectedBuffer, 1);
particle_system_geometry.addAttribute(‘position’, new THREE.InterleavedBufferAttribute(nodeBufferPosition, 3, 0, false));
particle_system_geometry.addAttribute(‘color’, new THREE.InterleavedBufferAttribute(nodeBufferColor, 3, 0, true));
particle_system_geometry.addAttribute(‘size’, new THREE.InterleavedBufferAttribute(nodeBufferSize, 4, 0, true));
particle_system_geometry.addAttribute(‘highlighted’, new THREE.InterleavedBufferAttribute(nodeBufferHighlight, 4, 0, true));
particle_system_geometry.addAttribute(‘subject’, new THREE.InterleavedBufferAttribute(nodeBufferSubject, 4, 0, true));
particle_system_geometry.addAttribute(‘selected’, new THREE.InterleavedBufferAttribute(nodeBufferSelected, 4, 0, true));
const vertexShader = [
‘precision highp float;’,
‘’,
‘uniform mat4 modelViewMatrix;’,
‘uniform mat4 projectionMatrix;’,
‘’,
‘attribute vec3 position;’,
‘attribute vec3 color;’,
‘attribute float size;’,
‘attribute float highlighted;’,
‘attribute float subject;’,
‘attribute float selected;’,
‘’,
‘varying vec3 vColor;’,
‘varying float vHighlighted;’,
‘varying float vSubject;’,
‘varying float vSelected;’,
‘’,
‘void main() {’,
‘’,
’ vColor = color;’,
’ vHighlighted = highlighted;’,
’ vSubject = subject;’,
’ vSelected = selected;’,
’ gl_Position = projectionMatrix modelViewMatrix vec4(position.xyz , 1.0);’,
‘’,
’ if (subject > 0.0) {’,
‘’,
’ gl_PointSize = (10.0 + (size 2.0)) (300.0 / length(gl_Position.xyz));’,
‘’,
’ } else {’,
‘’,
’ gl_PointSize = (15.0 + (size 2.0)) (300.0 / length(gl_Position.xyz));’,
‘’,
’ }’,
‘’,
‘}’
].join(’\n’);
const fragmentShader = [
‘precision highp float;’,
‘’,
‘uniform sampler2D map;’,
‘uniform sampler2D map2;’,
‘uniform sampler2D mapSelected;’,
‘’,
‘varying vec3 vColor;’,
‘varying float vHighlighted;’,
‘varying float vSubject;’,
‘varying float vSelected;’,
‘’,
‘void main() {’,
‘’,
’ vec2 uv = vec2(gl_PointCoord.x, 1.0 - gl_PointCoord.y);’,
‘’,
’ if (vSelected > 0.0) {’,
‘’,
’ vec4 textureColor = vec4(texture2D(mapSelected, uv));’,
’ gl_FragColor = vec4(textureColor vec4(vColor, 1.0));’,
‘’,
’ } else {’,
’ if (vSubject > 0.0) {’,
‘’,
’ vec4 textureColor = vec4(texture2D(map2, uv));’,
’ gl_FragColor = vec4((vec3(1) - textureColor.rgb) vColor, textureColor.a);’,
‘’,
’ } else {’,
‘’,
’ gl_FragColor = vec4(texture2D(map, uv) * vec4(vColor, 1.0));’,
‘’,
’ if (vHighlighted == 0.0) {’,
’ gl_FragColor = vec4(0.3, 0.3, 0.3, gl_FragColor.a);’,
’ }’,
‘’,
’ if (gl_FragColor.a > 0.6) gl_FragColor.a = 1.0;’,
‘’,
’ }’,
’ }’,
‘’,
’ if (gl_FragColor.a < 0.6) discard;’,
‘’,
‘}’
].join(’\n’);
const uniforms = {
map: { type: ‘t’, value: new THREE.TextureLoader().load(’…/…/assets/transparent_sphere.png’)},
map2: { type: ‘t’, value: new THREE.TextureLoader().load(’…/…/assets/reach.svg’)},
mapSelected: { type: ‘t’, value: new THREE.TextureLoader().load(’…/…/assets/Design1.png’)},
};
const nodeMaterial = new THREE.RawShaderMaterial( {
uniforms: uniforms,
vertexShader: vertexShader,
fragmentShader: fragmentShader,
defines: {
USE_MAP: true
},
transparent: true
});
particle_system_geometry.boundingBox = null;
particle_system_geometry.computeBoundingSphere();
this.mesh = new THREE.Points( particle_system_geometry, nodeMaterial );
this.scene.add( this.mesh );const particles = this.numNodesValue;
if (particles > 0) {
const particle_system_geometry = new THREE.BufferGeometry();
// Buffers
const positionBuffer = new Float32Array(new ArrayBuffer(particles 12)); // For positioning
const colorBuffer = new Uint8Array(new ArrayBuffer(particles 3)); // For giving color to nodes
const sizeBuffer = new Float32Array(new ArrayBuffer(particles 4)); // For giving size to nodes
const highlightBuffer = new Float32Array(new ArrayBuffer(particles 4)); // For giving highlight
const subjectsBuffer = new Float32Array(new ArrayBuffer(particles 4)); // For subjects
const selectedBuffer = new Float32Array(new ArrayBuffer(particles 4)); // For selected
this.radius = Math.min(1000, Math.max(100, Math.sqrt(particles Math.PI 20)));
this.innerDistance = Math.sqrt(Math.pow(this.radius - this.camera.position.x, 2) +
Math.pow(0 - this.camera.position.y, 2) + Math.pow(0 - this.camera.position.z, 2));
const dispersion = this.radiusDispersion;
for (let i = 0; i < particles; i++) {
let particularDispersion = 0;
if (dispersion > 0) {
particularDispersion = (((Math.ceil(Math.random() 11) - 1) / 10) dispersion) + Math.random(); // [0…1] * dispersion
}
highlightBuffer[i] = 1.0;
const angleX = (Math.random() - 0.5) 2 Math.PI;
const angleY = (Math.random() - 0.5) 2 Math.PI;
const posX = (this.radius + particularDispersion) Math.sin(angleX) Math.cos(angleY);
const posY = (this.radius + particularDispersion) Math.sin(angleX) Math.sin(angleY);
const posZ = (this.radius + particularDispersion) * Math.cos(angleX);
positionBuffer[(i 3)] = posX;
positionBuffer[(i 3) + 1] = posY;
positionBuffer[(i * 3) + 2] = posZ;
colorBuffer[(i 3)] = (Math.random() 255);
colorBuffer[(i 3) + 1] = (Math.random() 255);
colorBuffer[(i 3) + 2] = (Math.random() 255);
subjectsBuffer[i] = Math.random() < 0.3 ? 1.0 : 0.0;
selectedBuffer[i] = 0.0;
if (particularDispersion !== 0) {
sizeBuffer[i] = Math.floor((Math.pow(particularDispersion, 2) / Math.pow(dispersion, 2)) * this.sizeDiff);
} else {
sizeBuffer[i] = 0;
}
}
const nodeBufferPosition = new THREE.InterleavedBuffer(positionBuffer, 3);
const nodeBufferColor = new THREE.InterleavedBuffer(colorBuffer, 3);
const nodeBufferSize = new THREE.InterleavedBuffer(sizeBuffer, 1);
const nodeBufferHighlight = new THREE.InterleavedBuffer(highlightBuffer, 1);
const nodeBufferSubject = new THREE.InterleavedBuffer(subjectsBuffer, 1);
const nodeBufferSelected = new THREE.InterleavedBuffer(selectedBuffer, 1);
particle_system_geometry.addAttribute(‘position’, new THREE.InterleavedBufferAttribute(nodeBufferPosition, 3, 0, false));
particle_system_geometry.addAttribute(‘color’, new THREE.InterleavedBufferAttribute(nodeBufferColor, 3, 0, true));
particle_system_geometry.addAttribute(‘size’, new THREE.InterleavedBufferAttribute(nodeBufferSize, 4, 0, true));
particle_system_geometry.addAttribute(‘highlighted’, new THREE.InterleavedBufferAttribute(nodeBufferHighlight, 4, 0, true));
particle_system_geometry.addAttribute(‘subject’, new THREE.InterleavedBufferAttribute(nodeBufferSubject, 4, 0, true));
particle_system_geometry.addAttribute(‘selected’, new THREE.InterleavedBufferAttribute(nodeBufferSelected, 4, 0, true));
const vertexShader = [
‘precision highp float;’,
‘’,
‘uniform mat4 modelViewMatrix;’,
‘uniform mat4 projectionMatrix;’,
‘’,
‘attribute vec3 position;’,
‘attribute vec3 color;’,
‘attribute float size;’,
‘attribute float highlighted;’,
‘attribute float subject;’,
‘attribute float selected;’,
‘’,
‘varying vec3 vColor;’,
‘varying float vHighlighted;’,
‘varying float vSubject;’,
‘varying float vSelected;’,
‘’,
‘void main() {’,
‘’,
’ vColor = color;’,
’ vHighlighted = highlighted;’,
’ vSubject = subject;’,
’ vSelected = selected;’,
’ gl_Position = projectionMatrix modelViewMatrix vec4(position.xyz , 1.0);’,
‘’,
’ if (subject > 0.0) {’,
‘’,
’ gl_PointSize = (10.0 + (size 2.0)) (300.0 / length(gl_Position.xyz));’,
‘’,
’ } else {’,
‘’,
’ gl_PointSize = (15.0 + (size 2.0)) (300.0 / length(gl_Position.xyz));’,
‘’,
’ }’,
‘’,
‘}’
].join(’\n’);
const fragmentShader = [
‘precision highp float;’,
‘’,
‘uniform sampler2D map;’,
‘uniform sampler2D map2;’,
‘uniform sampler2D mapSelected;’,
‘’,
‘varying vec3 vColor;’,
‘varying float vHighlighted;’,
‘varying float vSubject;’,
‘varying float vSelected;’,
‘’,
‘void main() {’,
‘’,
’ vec2 uv = vec2(gl_PointCoord.x, 1.0 - gl_PointCoord.y);’,
‘’,
’ if (vSelected > 0.0) {’,
‘’,
’ vec4 textureColor = vec4(texture2D(mapSelected, uv));’,
’ gl_FragColor = vec4(textureColor vec4(vColor, 1.0));’,
‘’,
’ } else {’,
’ if (vSubject > 0.0) {’,
‘’,
’ vec4 textureColor = vec4(texture2D(map2, uv));’,
’ gl_FragColor = vec4((vec3(1) - textureColor.rgb) vColor, textureColor.a);’,
‘’,
’ } else {’,
‘’,
’ gl_FragColor = vec4(texture2D(map, uv) * vec4(vColor, 1.0));’,
‘’,
’ if (vHighlighted == 0.0) {’,
’ gl_FragColor = vec4(0.3, 0.3, 0.3, gl_FragColor.a);’,
’ }’,
‘’,
’ if (gl_FragColor.a > 0.6) gl_FragColor.a = 1.0;’,
‘’,
’ }’,
’ }’,
‘’,
’ if (gl_FragColor.a < 0.6) discard;’,
‘’,
‘}’
].join(’\n’);
const uniforms = {
map: { type: ‘t’, value: new THREE.TextureLoader().load(’…/…/assets/transparent_sphere.png’)},
map2: { type: ‘t’, value: new THREE.TextureLoader().load(’…/…/assets/reach.svg’)},
mapSelected: { type: ‘t’, value: new THREE.TextureLoader().load(’…/…/assets/Design1.png’)},
};
const nodeMaterial = new THREE.RawShaderMaterial( {
uniforms: uniforms,
vertexShader: vertexShader,
fragmentShader: fragmentShader,
defines: {
USE_MAP: true
},
transparent: true
});
particle_system_geometry.boundingBox = null;
particle_system_geometry.computeBoundingSphere();
this.mesh = new THREE.Points( particle_system_geometry, nodeMaterial );
this.scene.add( this.mesh );
This example is very complicated though. Can you strip down the shader / buffers until you render something with no issues?