getting spotlights to work

hey all

i’m trying to get a spotlight, attached to a moving object, to work so it looks kinda like car headlights.

inside the object instance i’ve made a setLights function with the following code:

	ambient = AmbientLight('ambient')
	ambient.setColor(Vec4(.5,1,.5,1))
	ambientNP = myobj.attachNewNode(ambient.upcastToPandaNode())
	
	spotlight = Spotlight('spotlight')
	spotlight.setColor(Vec4(1,1,1,1))
	spotlight.setLens(PerspectiveLens())
	spotlight.getLens().setFov(25,25)
	spotlight.setAttenuation(Vec3(1,0,0))
	spotlight.setExponent(1)

	spotlightNP = myobj.attachNewNode(spotlight.upcastToLensNode())		
	spotlightNP.setHpr(180,0,0)
	spotlightNP.setPos(Vec3(50,50,50))
	
	myobj.setLightOff()
	myobj.setLight(ambientNP)
	myobj.setLight(spotlightNP)

the ambient light is showing up but not the spotlight.

initially i did all the lighting in another class which creates an instance of the “game” and used the

	lightAttribute = LightAttrib.makeAllOff()
	ambientLight = AmbientLight( 'ambientLight' )
	ambientLight.setColor( Vec4( 0.1, 0.1, 0.1, 1 ) )
	ambientLightNP = render.attachNewNode( ambientLight.upcastToPandaNode() )				
	lightAttribute = lightAttribute.addLight(ambientLight)
	render.node().setAttrib(lightAttribute)

but the trouble is that i want the spotlight to be attached to myobj

any ideas?

The default heading of spotlight is toward to Y+ axis.
What objects you want to be illuminated ?
Looking at your script, you only set your spotlight to illuminate myobj :

myobj.setLight(spotlightNP)

Try to illuminate all things :

render.setLight(spotlightNP)

And you can play with it’s exponent value.

With your original code, is the spotlight didn’t affect myobj, maybe it simply illuminate myobj’s interior, which is consist of backfaces, which are not rendered by default.

You’ve attached it to myobj, by calling :

spotlightNP = myobj.attachNewNode(spotlight.upcastToLensNode())

what i want is the spotlight to be pointing outwards from myobj. so it looks like there are lights fixed onto the object…kinda like a flashlight

eh, sorry, i edited my last post.
Where is actually your spotlight position, relative to myobj ?
FYI, the lighting tutorial does the same thing, but the spotlight is parented to the camera instead.

i also thought maybe the light may be originating from within myobj but i already tried repositioning the spotlight node with

spotlightNP.setPos(Vec3(100,0,0))

but i still can’t see it

Ok, try to attach the Z-up-axis model just to locate your spotlight easily :

axis = loader.loadModel('zup-axis.egg')
axis.reparentTo(spotlightNP)

By doing so, the Y+ axis will show the illumination direction.

Note that you can do this handy call:

spotlight.showFrustum()

to make your spotlight’s frustum visible, and help identify which direction your spotlight is facing.

tokingmonkey, you did catch ynjh_jo’s point that:

myobj.setLight(spotlightNP)

means that only myobj is illuminated by the spotlight, right? I doubt this is what you intended, but it means that nothing in the world will show the effects of your spotlight except for myobj, which is what the spotlight is parented to (and thus is almost certainly behind the spotlight)!

David

thanks for the replies guys

i get the fact that it would only illuminate the object now, which is a big problem because I would like the spotlights to be attached to my obj so when it moves around it looks like it has headlights attached to it, like a car or something. how would i go about doing that without attaching the lighting node to the object itself?

You should understand the difference between:

spotlightNP = myobj.attachNewNode(spotlight)

which attaches your spotlight to myobj, so that it moves around with the object, and:

myobj.setLight(spotlightNP)

which specifies the set of nodes (in this case, myobj) that are illuminated by your spotlight.

Two completely unrelated concepts. As ynjh_jo pointed out, if you want your spotlight to illuminate everything, then instead of the above, do:

render.setLight(spotlightNP)

which makes it light up render and everything below it, i.e. everything in the world. But it’s still attached to your car. So when you drive your car around, it will light up whatever’s in front of your car.

However, the spotlights themselves will be invisible. Lights in Panda (as in any 3-D engine) are not themselves visible; they only illuminate geometry. So if you want to be able to see the headlights themselves on the car, as white disks maybe with visible cones of light streaming out from them, you will have to create separately the white disks to stick to your car there, and semitransparent cones to represent the cones of light.

David

i’ll give it a try. thanks. will let you know how it goes!

hey again guys, i tried doing the adjustments as suggested so that the spotlight is attached to the object but it is set so it illuminates the entire world but i still can’t see the light. i’m not sure if maybe it’s because i am setting a spotlight and ambient light on an object in one class file (the object’s class) and then also setting some lights and fog in the world class…? any ideas?

	ambient = AmbientLight('ambient')
	ambient.setColor(Vec4(.5,1,.5,1))
	ambientNP = obj.attachNewNode(ambient.upcastToPandaNode())
	
	spotlight = Spotlight('spotlight')
	spotlight.setColor(Vec4(4,4,4,1))
	spotlight.setLens(PerspectiveLens())
	spotlight.getLens().setFov(25,25)
	spotlight.setAttenuation(Vec3(1.0,0.0,0.0))
	spotlight.setExponent(1)

	spotlightNP = obj.attachNewNode(spotlight.upcastToLensNode())		
	spotlightNP.setHpr(180,0,0)
	
	obj.setLightOff()
	obj.setLight(ambientNP)
	render.setLight(spotlightNP)

that code is in a function that is called when the object is created. then in the world class which is created once at the beginning this code is run

	lightAttribute = LightAttrib.makeAllOff()
	
	
	ambientLight = AmbientLight( 'ambientLight' )
	ambientLight.setColor( Vec4( 0.1, 0.1, 0.1, 1 ) )
	ambientLightNP = render.attachNewNode( ambientLight.upcastToPandaNode() )				
	lightAttribute = lightAttribute.addLight(ambientLight)
	
	sunLight = DirectionalLight("sunLight")
	sunLight.setColor(Vec4(0.3,0.1,0.1,1))
	sunLight.setDirection(Vec3(1,1,-2))
	lightAttribute = lightAttribute.addLight(sunLight)
	sunLightNP = render.attachNewNode(sunLight.upcastToPandaNode())
	sunLightNP.setPos(0,0,50000)
	
	sunLightNP.setHpr(0, 0, -20)
	
	
	render.node().setAttrib(lightAttribute)

maybe there is some conflict here? i also can’t seem to see the directional light which i want to act as a sun from above either. sorry for the shower of questions guys i’m still a super noob with panda :cry:

Your lights are awfully bright. If all of the lights that are in effect on a particular object sum to greater than (1, 1, 1, 1), then they will clamp at (1, 1, 1, 1). That means that it will look exactly the same as if you had only an ambient light of brightness (1, 1, 1, 1), and no other lights–or, to put it another way, exactly the same as if you had lighting disabled altogether.

Try reducing the brightness of all of your lights.

David

i tried turning off all the lights and now i can see the spotlight! problem is it’s kinda random where it is lighting up at the moment…well not random i know but i have to play around with the values that setup the brightness and stuff like that of it i guess. do you guys know where i can get a look at the functions that can be used to control these values? i know there’s stuff abt it on this site in the documentation but it’s all kinda confusing for me

currently the game is split screen so there are two subs and i want the lights to look nice so you can sorta see ahead where the other sub is if you know what i mean

thanks for all the help as usual

You can set the spotlight’s Exponent to go above 1, and try to set other lights with lower intensity. First, try it with larger FOV to illuminate larger area, then once you’ve satisfied, you can shrink the FOV.