November 24, 2010

ISSUE 3: Lights, Action, Camera!

6. Lighting, Fog and a Sky

Issue 3 has been quite a long ordeal! Well done for hanging in there. We’re going to close by adding some nice cosmetic changes to our code. We are not going to discuss them until Issue 4, you’ve had to take in enough for this issue already! To finish up, however, you will need to download a couple of files. A new model (your skydome) and the texture that is associated with it. The links are below. Save the files in the same directory as your game (which is now getting a little cluttered, but we’ll tidy that up in the near future!):

(you may need to right-click and ‘save-as’ depending on your browser/operating system)

There are different approaches to applying a sky. For now, we have opted for a Sky Dome, but we will discuss Sky Spheres and Sky Cubes (cube maps) in the future. If you are interested in how we built the Sky Dome head over to this post on the Panda3D Forums. Now modify your code as follows. First, add the following right at the start of your code with the other imports:

from pandac.PandaModules import CompassEffect
from panda3d.core import AmbientLight, DirectionalLight, Vec4, Vec3, Fog

Next, add a new method to your class. It doesn’t matter where in your code you position this method (relative to others) other than for readability. We put ours after the keyboard methods:

    def createEnvironment(self):
        # Fog to hide a performance tweak:
        colour = (0.0,0.0,0.0)
        expfog = Fog("scene-wide-fog")
        expfog.setColor(*colour)
        expfog.setExpDensity(0.004)
        render.setFog(expfog)
        base.setBackgroundColor(*colour)

        # Our sky
        skydome = loader.loadModel('sky.egg')
        skydome.setEffect(CompassEffect.make(self.render))
        skydome.setScale(self.maxdistance/2) # bit less than "far"
        skydome.setZ(-65) # sink it
        # NOT render - you'll fly through the sky!:
        skydome.reparentTo(self.camera) 

        # Our lighting
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor(Vec4(.6, .6, .6, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection(Vec3(0,-10,-10))
        directionalLight.setColor(Vec4(1, 1, 1, 1))
        directionalLight.setSpecularColor(Vec4(1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

Lastly, add this line as a new line to your constructor/init method:

self.createEnvironment()

Run your game and observe different levels of lighting as you fly around and the sky! Now, head over to the edges of your world and you’ll see the sky runs out! Um, a slight problem there! We need to tend to the area between the terrain edges and where our sky ends. We can’t leave it empty. So we’ll fix it, next time… 😉

7. Wrap up and Summary

Quite an intense issue but we achieved an awful lot! We have managed to make our game playable by adding keyboard controls, done some performance tweaks, controlled the camera, understood some new concepts and begun enhancing the environment our player occupies. Hope you enjoyed Issue 3 and watch out for Issue 4 soon!

Output from Issue 3

Goto Issue 4 >>>