vladseroff
@vladseroff
Front-End Developer

Из за чего низкий FPS three.js?

Здравстуйте, начал изучать webGL в частности three.js и столкнулся с проблемой!
При добавлении LensFlares сразу падает fps до 30, как можно это пофиксить?
Вот ссылка на демку
smaple.ru/earth
Весь скрипт в файле main.js.
Если есть знающие люди помогите пожалуйста)

Так же прикладываю сюда код из main.js

(function () {

	// INIT CONTAINER
	var webglEl = document.getElementById('container');
	// 

	// DETECT webGL
	if (!Detector.webgl) {
		Detector.addGetWebGLMessage(webglEl);
		return;
	}
	// 

	// vars
	var width = window.innerWidth,
		height = window.innerHeight,
		mouseX = 0, mouseY = 0,
		windowHalfX = window.innerWidth / 2,
		windowHalfY = window.innerHeight / 2,
		width  = window.innerWidth,
		height = window.innerHeight,
		radius   = 0.5,
		segments = 32,
		rotation = 6,
		stats;
	
	// Var Scene
	var scene = new THREE.Scene();
	//

	// 

	// STATS
	stats = new Stats();
	stats.domElement.style.position = 'absolute';
	stats.domElement.style.bottom = '0px';
	stats.domElement.style.zIndex = 100;
	container.appendChild( stats.domElement );
	
	// RESIZE FUNCTION
	function onWindowResize() {
		windowHalfX = window.innerWidth / 2;
		windowHalfY = window.innerHeight / 2;
		camera.aspect = window.innerWidth / window.innerHeight;
		camera.updateProjectionMatrix();
		webglRenderer.setSize( window.innerWidth, window.innerHeight );
	}

	window.addEventListener( 'resize', onWindowResize, false );
	// 


	// Var Camera
	var camera = new THREE.PerspectiveCamera(45, width / height, 0.01, 1000);
	camera.position.z = 2;
	// 

	// Var Render
	webglRenderer = new THREE.WebGLRenderer({antialias: true, alpha: true });
	webglRenderer.setSize(width, height);
	webglRenderer.domElement.style.position = "relative";
	webglRenderer.setClearColor( 0x000000 );
	webglEl.appendChild(webglRenderer.domElement);
	// 

	// Ambient Light
	scene.add(new THREE.AmbientLight(0x070707));
	// 

	// DirectionalLight
	var light = new THREE.DirectionalLight(0xffffff, 1);
	light.position.set(120,10,80);
	light.shadowCameraVisible = true;
	scene.add(light);
	// 

	// Earth Sphere
    var sphere = createSphere(radius, segments);
	sphere.rotation.y = rotation; 
	scene.add(sphere);
	// 

	// scene.add(sun);
	var transparentmaterial = new THREE.MeshLambertMaterial( {
    color: 0xfff,
    shading: THREE.SmoothShading,
    opacity: .6, transparent: true } );
	transparentmaterial.depthWrite = false;
	var sphereGeo = new THREE.SphereGeometry( 1, 5, 5 );
	var sun = new THREE.Mesh( sphereGeo,transparentmaterial);
	sun.position.x = 65; 
	sun.position.z = 50; 
	sun.position.y = 0; 
	scene.add(sun);
	// 

	// Clouds Sphere
    var clouds = createClouds(radius, segments);
	clouds.rotation.y = rotation;
	scene.add(clouds);
	// 

	// Stars BG
	var stars = createStars(90, 64);
	scene.add(stars);
	// 

	// OrbitControls
	var controls = new THREE.OrbitControls(camera);
	controls.enableDamping = true;
	controls.dampingFactor = 0.25;
	controls.enableZoom = true;
	controls.enablePan = false;
	controls.rotateSpeed = 0.1;
	controls.zoomSpeed = 0.3;
    controls.panSpeed = 0.4;
	controls.minDistance = 1.3;
	controls.maxDistance = 2;
	// 

	// lens flares
	var textureLoader = new THREE.TextureLoader();
	var textureFlare0 = textureLoader.load(	"flare1.jpg" );
	var textureFlare2 = textureLoader.load( "flare2.jpg" );
	var textureFlare3 = textureLoader.load( "flare3.jpg" );
	var textureFlare4 = textureLoader.load( "flare4.jpg" );
	var textureFlare5 = textureLoader.load( "flare5.jpg" );
	addLight( 22, 0.9, 0.5, 5000, 0, -5000 );
	addLight( 22, 0.8, 0.5,    0, 0, -5000 );
	addLight( 22, 0.5, 0.9, 5000, 5000, -5000 );
	function addLight( h, s, l, x, y, z ) {
		var light = new THREE.PointLight( 0xffffff, 0.5, 1000 );
		light.color.setHSL( h, s, l );
		light.position.set( x, y, z );
		scene.add( light );
		var flareColor = new THREE.Color( 0xffffff );
		flareColor.setHSL( h, s, l + 0.5 );
		var lensFlare = new THREE.LensFlare( textureFlare0, 240, 0.0, THREE.AdditiveBlending, flareColor );
		lensFlare.add( textureFlare2, 20, 0, THREE.AdditiveBlending );
		lensFlare.add( textureFlare5, 312, 0, THREE.AdditiveBlending );
		// lensFlare.add( textureFlare3, 22, 0.0, THREE.AdditiveBlending );
		lensFlare.add( textureFlare3, 160, 0.6, THREE.AdditiveBlending );
		lensFlare.add( textureFlare4, 270, 0.3, THREE.AdditiveBlending );
		// lensFlare.add( textureFlare3, 120, 0.7, THREE.AdditiveBlending );
		// lensFlare.add( textureFlare2, 870, 0.9, THREE.AdditiveBlending );
		lensFlare.customUpdateCallback = lensFlareUpdateCallback;
		lensFlare.position.copy( sun.position );
		scene.add( lensFlare );
	}

	// RENDERER

	render();

	function render() {
		requestAnimationFrame(render);
		controls.update();
		stats.update();
		sphere.rotation.y += 0.0003;
		clouds.rotation.y += 0.0005;
		// clouds.rotation.z += 0.0005;	
		webglRenderer.render(scene, camera);
	}

	// FlareUpdate
	function lensFlareUpdateCallback( object ) {
		var f, fl = object.lensFlares.length;
		var flare;
		var vecX = -object.positionScreen.x * 2;
		var vecY = -object.positionScreen.y * 2;
		for( f = 0; f < fl; f++ ) {
			flare = object.lensFlares[ f ];
			flare.x = object.positionScreen.x + vecX * flare.distance;
			flare.y = object.positionScreen.y + vecY * flare.distance;
			flare.rotation = 0;
		}
		object.lensFlares[ 2 ].y += 0.025;
		object.lensFlares[ 3 ].rotation = object.positionScreen.x * 0.5 + THREE.Math.degToRad( 45 );
	}
	//

	var loader = new THREE.TextureLoader();

	// Creating Functions
	function createSphere(radius, segments) {
		return new THREE.Mesh(
			new THREE.SphereGeometry(radius, segments, segments),
			new THREE.MeshPhongMaterial({
				map:         THREE.ImageUtils.loadTexture('earth.jpg'),
				bumpMap:     THREE.ImageUtils.loadTexture('bump.jpg'),
				bumpScale:   0.001,
				specularMap: THREE.ImageUtils.loadTexture('specular.jpg'),
				specular:    new THREE.Color('#343434'),				
			})
		);
	}

	function createSun(radius, segments) {
		return new THREE.Mesh(
			new THREE.SphereGeometry(5, segments, segments),
			new THREE.MeshPhongMaterial({
				map:         THREE.ImageUtils.loadTexture('sun.png'),
				emissive: 0xffffff,
				transparent: false,		
			})
		);
	}
	
	function createClouds(radius, segments) {
		return new THREE.Mesh(
			new THREE.SphereGeometry(radius + 0.003, segments, segments),			
			new THREE.MeshPhongMaterial({
				map:         THREE.ImageUtils.loadTexture('clouds.png'),
				transparent: true
			})
		);		
	}

	function createStars(radius, segments) {
		return new THREE.Mesh(
			new THREE.SphereGeometry(radius, segments, segments), 
			new THREE.MeshBasicMaterial({
				map:  THREE.ImageUtils.loadTexture('galaxy_starfield.png'), 
				side: THREE.BackSide,
				transparent: true,
				opacity: 0.3
			})
		);
	}
	// 

	
}());
  • Вопрос задан
  • 992 просмотра
Пригласить эксперта
Ответы на вопрос 1
svaa1982
@svaa1982
Web разработчик с трёхмерным уклоном
Судя по профайлеру хрома, скорее всего приложение интенсивно использует видеокарту, возможно проблема в неоптимизированном шейдере LensFlares.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы