我正在建立一个网站,显示有数千个神经元的鱼的大脑。 大脑模型从数据库加载为三角形(面),每个三角形(面)由3个点组成。
神经元从数据库中作为链接(线)加载,每个链接由2个点(线)组成。
渲染需要很长时间,我无法找到改善性能的方法。我在构建场景的网格和几何形状方面一定存在问题(因为我是WebGL的新手)。
以下图片是具有神经元子集的模型示例:
我还没有包含完整的代码,因为该页面包含许多功能,例如搜索。 此外,我还没有包括鼠标控件和光线投射。
<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>
请您给我任何改善表现的建议或建议吗? 非常感谢你
答案 0 :(得分:2)
您可能希望使用BufferGeometry。有许多以快速/有效的方式渲染许多顶点/面的例子。
在这方面,如果你移除脑网,它是否会提高性能?如果删除神经元网格,它会提高性能吗?
关闭蝙蝠,我可以看到你可以优化你在draw_neurons()中构建THREE.Line的方式。如果我理解正确,每个神经元中的线共享相同的材质,因此在这种特定情况下,您只需要一个几何体和一个THREE.LineSegments网格(而不是每个线/线段的单独几何/ THREE.Line)。
答案 1 :(得分:1)
对msun的回答只是一个小小的注释。 BufferGeometry()有一个非常有用的方法
.fromGeometry ( Geometry )
使用Geometry对象中的数据填充此BufferGeometry。因此,只需对代码进行少量更改即可
var bufgeometry = new THREE.BufferGeometry().fromGeometry( geometry );
var mesh = new THREE.Mesh(bufgeometry, material);
brain.add(mesh);