My website project involves displaying a fish brain with numerous neurons, loaded as triangles and links from a database. While trying to render the models, I've encountered a performance issue that I suspect is related to how I'm handling the meshes and geometries in the scene, especially since I'm new to WebGL.
Here's an example image of the brain model with a subset of neurons:
https://i.sstatic.net/9Yiet.png
The rendering code:
Due to the complexity of the code, which includes various functionalities like search options, I've omitted certain sections such as mouse controls and raycasts.
<script>
var container;
var camera, controls, scene, renderer;
var brain;
var dirLight;
var viewport_width;
var viewport_height;
var neurons;
var line_width = 2;
var show_brain = true;
var selected_brain_resolution = {{ brain.resolution }};
init();
animate();
function init() {
{% for n in aligned_neurons %}
random_color = getRandomColor();
colors_scheme.push(random_color);
{% endfor %}
container = document.getElementById('visualization');
viewport_width = container.clientWidth;
viewport_height = 0.75 * viewport_width;
renderer_offset_rectangle = container.getBoundingClientRect();
camera = new THREE.PerspectiveCamera(60, viewport_width / viewport_height, 1, 100000);
camera.position.z = 1000;
renderer = new THREE.CanvasRenderer();
renderer.setClearColor(0xcccccc);
renderer.setPixelRatio(viewport_width / viewport_height);
renderer.setSize(viewport_width, viewport_height);
renderer.sortObjects = false;
container.appendChild(renderer.domElement);
neurons = new THREE.Group();
brain = new THREE.Group();
scene = new THREE.Scene();
draw_neurons();
if (show_brain) {
draw_brain();
}
brain.rotation.z = 3.14;
brain.add(neurons);
scene.add(brain);
draw_intersection_plane();
dirLight = new THREE.DirectionalLight(0xffffff, 1);
dirLight.position.set(camera.position.x, camera.position.y, camera.position.z);
scene.add(dirLight);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
dirLight.position.set(camera.position.x, camera.position.y, camera.position.z);
renderer.render(scene, camera);
}
function draw_brain() {
var geometry = new THREE.Geometry();
var counter = 0;
{% for face in brain.face_set.all %}
v1 = new THREE.Vector3(({{ face.pt_1.x }}-{{ brain.center.x }}), ({{ face.pt_1.y }}-{{ brain.center.y }}), {{ face.pt_1.z }}-{{ brain.center.z }});
v2 = new THREE.Vector3(({{ face.pt_2.x }}-{{ brain.center.x }}), ({{ face.pt_2.y }}-{{ brain.center.y }}), {{ face.pt_2.z }}-{{ brain.center.z }});
v3 = new THREE.Vector3(({{ face.pt_3.x }}-{{ brain.center.x }}), ({{ face.pt_3.y }}-{{ brain.center.y }}), {{ face.pt_3.z }}-{{ brain.center.z }});
geometry.vertices.push(v1);
geometry.vertices.push(v2);
geometry.vertices.push(v3);
index0 = counter;
index1 = counter + 1;
index2 = counter + 2;
geometry.faces.push(new THREE.Face3(index0, index1, index2));
counter += 3;
{% endfor %}
geometry.computeFaceNormals();
var material = new THREE.MeshPhongMaterial({
wireframe: false,
color: 0xcccccc,
specular: 0xffffff,
shininess: 30,
opacity: 0.5
});
var mesh = new THREE.Mesh(geometry, material);
brain.add(mesh)
}
function draw_neurons() {
{% for neuron in aligned_neurons %}
var color = colors_scheme[{{ forloop.counter0 }}];
var soma_material = new THREE.MeshPhongMaterial({
wireframe: false,
color: color,
specular: 0xffffff,
shininess: 30
});
var line_material = new THREE.LineBasicMaterial({color: color, linewidth: line_width});
var spheregeometry = new THREE.SphereGeometry(1, 10, 10);
var soma = new THREE.Mesh(spheregeometry, soma_material);
soma.position.set({{ neuron.view.0.start_node.position.x }}-{{ brain.center.x }},
{{ neuron.view.0.start_node.position.y }}-{{ brain.center.y }},
{{ neuron.view.0.start_node.position.z }}-{{ brain.center.z }});
var radius = 7;
{% for link in neuron.view %}
var n_position = new THREE.Vector3({{ link.start_node.position.x }} -{{ brain.center.x }}, {{ link.start_node.position.y }}-{{ brain.center.y }}, {{ link.start_node.position.z }}-{{ brain.center.z }});
var p_position = new THREE.Vector3({{ link.end_node.position.x }} -{{ brain.center.x }}, {{ link.end_node.position.y }}-{{ brain.center.y }}, {{ link.end_node.position.z }} -{{ brain.center.z }});
var line_geometry = new THREE.Geometry();
line_geometry.vertices.push(n_position, p_position);
var line = new THREE.Line(line_geometry, line_material);
neurons.add(line);
{% endfor %}
soma.scale.set(radius, radius, radius);
neurons.add(soma);
{% endfor %}
}
</script>
If you have any suggestions or advice on how to enhance the performance of this project, I would greatly appreciate it. Thank you.