Pavel Galaton
Pavel Galaton

Reputation: 593

Point SpotLight in same direction as camera three.js (Flashlight)

I'm really new in this stuff. I want to make a simple 3D scene, where i can fly around with PointerLockControls, but i want also to have some kind of flashlight. So spot light should point same direction as camera does.

I have made spotlight to follow camera but its target is bound to 0,0,0.

What is the best way to achieve this?

Thank you.

Upvotes: 8

Views: 13905

Answers (3)

Elias Hasle
Elias Hasle

Reputation: 667

Inspired by WestLangley's solution above, I found out that spotlight.target and spotlight itself can be added as children to the same object, whether that is the camera or another object, like a car or a gun. Then they are positioned relative to the parent object, so that there is no need to keep copying the position from one object to another.

You could, for instance, do something like this:

scene.add(camera);
camera.add(gun);
gun.position.set(-30,-30,0);
gun.add(spotlight);
spotlight.position.set(0,0,30);
gun.add(spotlight.target);
spotlight.target.position.set(0,0,31);

And now the gun will, by default, follow the camera, and the spotlight will light up along the gun. If the gun is for some reason rotated (deflecting a bullet or crawling on the ground or whatever), the spotlight will rotate too. THREE is a nice piece of software. :-)

If you attach the spotlight to the camera and point it in the same direction as the camera and don't position it away from the center, then the light cone will look constantly circular. For many applications it looks cooler and more realistic that it changes shape dynamically in the projection. A small offset is all it takes (such as in my example above, though I haven't tested that one).

Upvotes: 2

WestLangley
WestLangley

Reputation: 104783

The SpotLight target is an Object3D, not a Vector3.

spotlight.target = myObject;

The best solution in your case is to use a PointLight instead, and use this pattern:

scene.add( camera );
camera.add( pointLight );

If you still want to use a spotlight, then do something like this:

scene.add( camera );
camera.add( spotLight.target );
spotLight.target.position.set( 0, 0, -1 );
spotLight.position.copy( camera.position ); // and reset spotlight position if camera moves

It is not generally required that the camera be added as a child of the scene, but it is required in this case because the light is added as a child of the camera.

three.js r.69

Upvotes: 13

Tim
Tim

Reputation: 761

I had the same problem which I solved as follows:

flashlight = new THREE.SpotLight(0xffffff,4,40);
camera.add(flashlight);
flashlight.position.set(0,0,1);
flashlight.target = camera;

Since a SpotLight's .target needs to be an object (and not a position) I found it mentally easier to simply place the flashlight directly behind the camera, and then aim it at the camera. Thus the light shines through the camera and lights up the things in front of it.

This approach is fine if you are after a flashlight effect where the flashlight is held close to the chest (central to the body) and not off on one side.

Upvotes: 14

Related Questions