提高渲染性能

时间:2016-10-27 10:54:42

标签: javascript three.js

我正在建立一个网站,显示有数千个神经元的鱼的大脑。 大脑模型从数据库加载为三角形(面),每个三角形(面)由3个点组成。

神经元从数据库中作为链接(线)加载,每个链接由2个点(线)组成。

渲染需要很长时间,我无法找到改善性能的方法。我在构建场景的网格和几何形状方面一定存在问题(因为我是WebGL的新手)。

以下图片是具有神经元子集的模型示例:

enter image description here

渲染代码:

我还没有包含完整的代码,因为该页面包含许多功能,例如搜索。 此外,我还没有包括鼠标控件和光线投射。

<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>

请您给我任何改善表现的建议或建议吗? 非常感谢你

2 个答案:

答案 0 :(得分:2)

您可能希望使用BufferGeometry。有许多以快速/有效的方式渲染许多顶点/面的例子。

  • 您在draw_brain()中创建了多少个顶点?
  • 您在draw_neurons()中创建了多少个神经元球体?
  • 您在draw_neurons()中创建了多少个神经元线?

在这方面,如果你移除脑网,它是否会提高性能?如果删除神经元网格,它会提高性能吗?

关闭蝙蝠,我可以看到你可以优化你在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);