Reputation: 71
I'm doing some racing game on three.js and I stuck with the following problem...
I'm having 2 cars, so we need to render 4 spotlights (minimum) for rear car lights and front car lights for each car...
Also we need some lights on the road...
So i'm having this code:
//front car1 light
var SpotLight = new THREE.SpotLight( 0xffffff, 5, 300, Math.PI/2, 1 );
SpotLight.position.set( 50, 10, 700 );
SpotLight.target.position.set(50, 0, 800);
SpotLight.castShadow = true;
SpotLight.shadowCameraVisible = false;
SpotLight.shadowDarkness = 0.5;
scene.add(SpotLight);
//front car2 light
var SpotLight = new THREE.SpotLight( 0xffffff, 5, 300, -Math.PI/2, 1 );
SpotLight.position.set( -50, 10, 40 );
SpotLight.target.position.set(-50, 0, 100);
SpotLight.castShadow = true;
SpotLight.shadowCameraVisible = false;
SpotLight.shadowDarkness = 0.5;
scene.add(SpotLight);
//rear car1 light
var SpotLight = new THREE.SpotLight( 0xff0000, 2, 200, Math.PI/2, 2 );
SpotLight.position.set( 50, 20, 660 );
SpotLight.target.position.set(50, 0, 600);
SpotLight.castShadow = true;
SpotLight.shadowCameraVisible = false;
SpotLight.shadowDarkness = 0.5;
scene.add(SpotLight);
//rear car2 light
var SpotLight = new THREE.SpotLight( 0xff0000, 2, 100, Math.PI/2, 1 );
SpotLight.position.set( -50, 20, -35 );
SpotLight.target.position.set(-50, 0, -100);
SpotLight.castShadow = true;
SpotLight.shadowCameraVisible = false;
SpotLight.shadowDarkness = 0.5;
scene.add(SpotLight);
//some road light
var SpotLight = new THREE.SpotLight( 0x404040, 3, 500, Math.PI/2, 2 );
SpotLight.position.set( 0, 300, 0 );
SpotLight.target.position.set(0, 0, 0);
SpotLight.castShadow = true;
SpotLight.shadowCameraVisible = false;
SpotLight.shadowDarkness = 0.5;
scene.add(SpotLight);
Nothing special.. but performance dropped to 20-30 FPS and it's a little bit laggy :-1: And if I add some lights in the future, the performance will be lifted even further ...
Has anyone encountered similar problems already? How to deal with this? Or maybe I'm doing something wrong?
Upvotes: 4
Views: 3734
Reputation: 2625
I had exactly same issue, beside mrdoob's & yaku's suggestions, which were really helpful, another approach is reducing number of segments & polygons in your geometries.
i.e If you have a simple cylinder in your scene, you can reduce number of segments by assigning heightSegments & radialSegments in initialization time:
As an very simple example, avoid doing something like this if you need to create a simple cylinder:
sampleCylinderGeo = new THREE.CylinderGeometry(2, 2, 5, 16, 32);
instead try:
sampleCylinderGeo = new THREE.CylinderGeometry(2, 2, 5, 8, 1);
Of course if you want smoother cylinder you can increase radial segments from 8 to something like 16 or more according to your needs, but for heightSegments its simply useless to have more than 1 segments in a simple cylinder.
So just adjust number of segments according to your needs so you will save lots of unnecessary segments and achieve a lot more FPS when working with lights, specially when you have lots of geometries in you scene.
Upvotes: 1
Reputation: 3111
Shadows are most likely the culprit in this case - under the hood, the scene needs to be rendered from the point of view of each shadow-casting light. If possible, save them for the most important ones, disable shadows on other lights.
For many lights, you could try to use WebGLDeferredRenderer, it can handle multiple lights much better than the default renderer. It's experimental work in progress though, so you are likely to run into other problems. Also I'm not sure if it helps shadow mapping performance.
Upvotes: 3
Reputation: 19602
Lights are a very consuming when doing realtime rendering. You'll need to find the cheapest approach that mimics the result you're after.
For instance, you could have a textured plane in front of your car with a texture that looks like the if there were spotlights aiming to the floor. It won't be right, but it will give the impression that is right and you will be saving 4 spotlights and your game will run at 60fps.
Upvotes: 4