Оптимизация WebGL (three.js)
Привет форумчане!
Сначала посмотрите сам проект: http://test3.stdmed.ru Пилю проект по картам (mapbox GL JS) Прикрутил сверху слой с визуализацией (Three.js) Получается вроде норм, но вот все медленнее и медленнее все ворочается в браузере. Боюсь что когда я допилю функционал, приложение совсем помрет :( Подскажите, если кто знает как мне поднять производительность? Если что вот код app2.js (правда он большой, хоть я и удалил из него половину а то не влазиет): $.getJSON('geo.json', function(info){ data = info; for (var j = 0; j<data.length; j++) { type[j] = data[j].json_geometry.type; if (type[j] == "MultiPolygon") { j++; }; latlon[j] = data[j].json_geometry.coordinates[0]; } document.getElementById("log").innerHTML += "> Json data loaded successfully. Objects loaded = " + data.length + "<br>"; buildMap(); }); function buildMap() { map.on('load', function () { document.getElementById("log").innerHTML += "> Map Loaded successfully<br>"; initGL(); function initGL() { document.getElementById("log").innerHTML += "> function initGL() started<br>"; var mapDiv = document.getElementById("map").firstChild; renderer = new THREE.WebGLRenderer( { alpha: true } ); renderer.shadowMap.enabled; renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); renderer.domElement.id = 'webGL'; //renderer.setClearColor( 0xff0000, 0.2 ); mapDiv.appendChild( renderer.domElement ); renderer.domElement.style.position = "absolute"; renderer.domElement.style.top = "0px"; renderer.domElement.style.left = "0px"; scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera( 35, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 5000 ); //camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, 1, 1000 ); camera.position.z = 4; controls = new THREE.TrackballControls( camera, container ); controls.rotateSpeed = 2; controls.zoomSpeed = 7; // controls.panSpeed = 3; controls.noZoom = false; // controls.noPan = false; controls.staticMoving = true; controls.dynamicDampingFactor = 0.3; controls.maxPolarAngle = Math.PI/2.0; // LIGHTS var light; light = new THREE.AmbientLight( 0xdddddd ); scene.add( light ); // STATS stats = new Stats(); // remember these initial values var tanFOV = Math.tan( ( ( Math.PI / 180 ) * camera.fov / 2 ) ); var windowHeight = window.innerHeight; $("#map").append( stats.dom ); plane = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2000, 2000, 8, 8 ), new THREE.MeshBasicMaterial( { visible: false, color: 0xff0000, transparent: true, opacity: 0.4 } ) ); scene.add( plane ); EventsControls2 = new EventsControls( camera, renderer.domElement ); EventsControls2.attach( plane ); EventsControls2.attachEvent( 'mouseOver', function () { controls.target0.copy( controls.target ); controls.enabled = true; }); EventsControls2.attachEvent( 'mouseOut', function () { controls.reset(); controls.target.copy( controls.target0 ); controls.object.position.copy( controls.position0 ); controls.update(); controls.enabled = true; }); EventsControls = new EventsControls( camera, renderer.domElement ); EventsControls.map = plane; EventsControls.offsetUse = true; EventsControls.attachEvent( 'mouseOver', function () { this.container.style.cursor = 'pointer'; mouseOveredObject = this.mouseOveredChild; prevOpacity = mouseOveredObject.material.opacity; }); EventsControls.attachEvent( 'mouseOut', function () { this.container.style.cursor = 'auto'; mouseOveredObject = undefined; this.mouseOveredChild.material.opacity = prevOpacity; }); EventsControls.attachEvent( 'dragAndDrop', function () { this.container.style.cursor = 'move'; }); EventsControls.attachEvent( 'onclick', function () { controls.enabled = false; }); EventsControls.attachEvent( 'mouseUp', function () { this.container.style.cursor = 'auto'; }); THREE.Triangulation.setLibrary('earcut'); /* function onWindowResize() { renderer.setSize(window.innerWidth, window.innerHeight); camera.left = -window.innerWidth / 2; camera.right = window.innerWidth / 2; camera.top = window.innerHeight / 2; camera.bottom = -window.innerHeight / 2; camera.updateProjectionMatrix(); } */ function animate() { requestAnimationFrame( animate ); render(); rotDegree = -1*(map.transform._pitch* 180 / Math.PI); camera.position.y = Math.sin(THREE.Math.degToRad( rotDegree )) * 4; camera.position.z = Math.cos(THREE.Math.degToRad( rotDegree )) * 4; camera.lookAt( scene.position ); stats.update(); if ( !mouseOveredObject ) { } else { mouseOveredObject.material.opacity += 0.02 } //console.log(map.dragPan._inertia); //map.dragPan._inertia = []; /* if ((flag == 1) && (zGrow < 2)) { zGrow += 0.01; group.scale.set(1,1,zGrow) } */ } function render() { renderer.render( scene, camera ); } setTimeout(function(){latlonToWorld()}, 0); animate(); } function latlonToPx() { for (var j = 0; j<data.length; j++) { intersectsF[j] = []; for (var i = 0; i<data[j].json_geometry.coordinates[0].length; i++) { p[j] = []; p[j][i] = map.project(new mapboxgl.LngLat( latlon[j][i][1],latlon[j][i][1] )); op.x = ( p[j][i].x / window.innerWidth ) * 2 - 1; op.y = - ( p[j][i].y / window.innerHeight ) * 2 + 1; raycaster.setFromCamera( op, camera ); intersects = raycaster.intersectObjects( objarray ); if ( intersects.length > 0 ) { if ( INTERSECTED != intersects[ 0 ].object ) { intersectsF[j][i][0] = intersects[0].point.x; intersectsF[j][i][1] = intersects[0].point.y; } } else { INTERSECTED = null; } } } } function latlonToWorld() { mapWidth = window.innerWidth; mapHeight = window.innerHeight; mapLonLeft = map.getBounds()._sw.lng; mapLonRight = map.getBounds()._ne.lng; mapLonDelta = mapLonRight - mapLonLeft; mapLatBottom = map.getBounds()._sw.lat; mapLatBottomDegree = mapLatBottom * Math.PI / 180; for (var i = 0; i < data.length; i++) { geometryF[i] = new THREE.Geometry(); coords[i] = data[i].json_geometry.coordinates; type[i] = data[i].json_geometry.type for (var j = 0; j < coords[i][0].length; j++) { //2D coordinates latitude = coords[i][0][j][1]; longitude = coords[i][0][j][0]; var x = (longitude - mapLonLeft) * (mapWidth / mapLonDelta); latitude = latitude * Math.PI / 180; var worldMapWidth = ((mapWidth / mapLonDelta) * 360) / (2 * Math.PI); var mapOffsetY = (worldMapWidth / 2 * Math.log((1 + Math.sin(mapLatBottomDegree)) / (1 - Math.sin(mapLatBottomDegree)))); var y = mapHeight - ((worldMapWidth / 2 * Math.log((1 + Math.sin(latitude)) / (1 - Math.sin(latitude)))) - mapOffsetY); var point3D = new THREE.Vector3( ( x / window.innerWidth ) * 2 - 1, -( y / window.innerHeight ) * 2 + 1, 0.5 ); var vertice3D = point3D.unproject(camera); geometryF[i].vertices.push( vertice3D ); } } setTimeout(function(){buildMesh()}, 0); } function buildMesh() { group = new THREE.Object3D(); for (var j = 0; j < geometryF.length; j++) { var vertices = geometryF[j].vertices; var holes = []; var triangles, mesh; var geometry = new THREE.Geometry(); var material = new THREE.MeshPhongMaterial( { color: 0x33D8DE, specular: 0x825AB6, shininess: 70, shading: THREE.FlatShading, transparent:true, opacity: Math.random()*0.2+0.2} ) //material.color.setHex( Math.random() * 0xffffff ); material.side = THREE.DoubleSide; geometry.vertices = vertices; if (type[j] == "MultiPolygon") { var multitriangles = earcut(vertices, holes); }; triangles = THREE.ShapeUtils.triangulateShape( vertices, holes ); for( var i = 0; i < triangles.length; i++ ){ geometry.faces.push( new THREE.Face3( triangles[i][0], triangles[i][1], triangles[i][2] )); } mesh = new THREE.Mesh( geometry, material ); objects.push( mesh ); group.add( mesh ); scene.add(group); EventsControls.attach( group ); } } }); |
Думаю, вам нужно взять только один Buffergeometry и его деформировать ) хотя мороки будет много )
|
Часовой пояс GMT +3, время: 00:33. |