Exemple #1
0
def setup_lighting(the_base):

    global PICKER_RAY, TRAVERSER, COLLISION_HANDLER
    # fancy_rendering = False

    alight = core.AmbientLight('alight')
    alight.setColor(core.VBase4(0.6, 0.6, 0.6, 1))
    alnp = the_base.render.attachNewNode(alight)
    the_base.render.setLight(alnp)
    slight = core.Spotlight('slight')
    slight.setColor(core.VBase4(1, 1, 1, 1))
    lens = core.PerspectiveLens()
    slight.setLens(lens)
    slnp = the_base.render.attachNewNode(slight)
    slnp.setPos(8, -9, 128)
    slnp.setHpr(0, 270, 0)
    the_base.render.setLight(slnp)

    # I have no idea what this does, so it must not be important...
    # if fancy_rendering:
    #     # Use a 512x512 resolution shadow map
    #     slight.setShadowCaster(True, 512, 512)
    #     # Enable the shader generator for the receiving nodes
    #     the_base.render.setShaderAuto()

    TRAVERSER = core.CollisionTraverser()
    COLLISION_HANDLER = core.CollisionHandlerQueue()

    picker_node = core.CollisionNode('mouseRay')
    picker_np = the_base.camera.attachNewNode(picker_node)
    picker_node.setFromCollideMask(core.GeomNode.getDefaultCollideMask())
    PICKER_RAY = core.CollisionRay()
    picker_node.addSolid(PICKER_RAY)
    TRAVERSER.addCollider(picker_np, COLLISION_HANDLER)
Exemple #2
0
 def setup_lights(self):
     '''Adds lights to the scene '''
     # ambient
     self.ambient_light = self.render.attach_new_node(p3d.AmbientLight('ambient'))
     self.ambient_light.node().set_color((0.1, 0.1, 0.1, 1.0))
     self.render.set_light(self.ambient_light)
     # directional
     self.dir_light = self.render.attach_new_node(p3d.DirectionalLight('directional'))
     self.dir_light.node().set_color((0.1, 0.1, 0.25, 1.0))
     self.dir_light.node().set_direction(p3d.Vec3(0.2,0.4,-1.0))
     self.render.set_light(self.dir_light)
     # spot
     self.spot_light = self.render.attach_new_node(p3d.Spotlight('spot'))
     self.spot_light.node().set_color((1.0, 1.0, 1.0, 1.0))
     self.spot_light.node().set_shadow_caster(True, 1024, 1024)
     self.spot_light.node().get_lens().set_near_far(0.1, 20.0)
     self.spot_light.node().get_lens().set_fov(25)
     self.spot_light.node().set_exponent(120.0)
     self.spot_light.set_pos(-8, 0, 8)
     self.spot_light.look_at(p3d.Point3(3,-3,0))
     self.render.set_light(self.spot_light)
    def __init__(self):
        # Preliminary capabilities check.

        if not ape.base().win.getGsg().getSupportsBasicShaders():
            self.t = addTitle(
                "Shadow Demo: Video driver reports that shaders are not supported."
            )
            return
        if not ape.base().win.getGsg().getSupportsDepthTexture():
            self.t = addTitle(
                "Shadow Demo: Video driver reports that depth textures are not supported."
            )
            return

        self.inst_p = addInstructions(0.06,
                                      'P : stop/start the Panda Rotation')
        self.inst_w = addInstructions(0.12, 'W : stop/start the Walk Cycle')
        self.inst_t = addInstructions(0.18, 'T : stop/start the Teapot')
        self.inst_l = addInstructions(0.24,
                                      'L : move light source far or close')
        self.inst_v = addInstructions(0.30,
                                      'V : View the Depth-Texture results')
        self.inst_u = addInstructions(0.36,
                                      'U : toggle updating the shadow map')
        self.inst_x = addInstructions(
            0.42, 'Left/Right Arrow : switch camera angles')

        ape.base().setBackgroundColor(0, 0, 0.2, 1)

        ape.base().camLens.setNearFar(1.0, 10000)
        ape.base().camLens.setFov(75)
        ape.base().disableMouse()

        # Load the scene.
        floorTex = ape.loader().loadTexture('maps/envir-ground.jpg')

        cm = p3dc.CardMaker('')
        cm.setFrame(-2, 2, -2, 2)
        floor = ape.render().attachNewNode(p3dc.PandaNode("floor"))
        for y in range(12):
            for x in range(12):
                nn = floor.attachNewNode(cm.generate())
                nn.setP(-90)
                nn.setPos((x - 6) * 4, (y - 6) * 4, 0)
        floor.setTexture(floorTex)
        floor.flattenStrong()

        self.pandaAxis = ape.render().attachNewNode('panda axis')
        self.pandaModel = Actor('panda-model', {'walk': 'panda-walk4'})
        self.pandaModel.reparentTo(self.pandaAxis)
        self.pandaModel.setPos(9, 0, 0)
        self.pandaModel.setScale(0.01)
        self.pandaWalk = self.pandaModel.actorInterval('walk', playRate=1.8)
        self.pandaWalk.loop()
        self.pandaMovement = self.pandaAxis.hprInterval(
            20.0, p3dc.LPoint3(-360, 0, 0), startHpr=p3dc.LPoint3(0, 0, 0))
        self.pandaMovement.loop()

        self.teapot = ape.loader().loadModel('teapot')
        self.teapot.reparentTo(ape.render())
        self.teapot.setPos(0, -20, 10)
        self.teapotMovement = self.teapot.hprInterval(
            50, p3dc.LPoint3(0, 360, 360))
        self.teapotMovement.loop()

        self.accept('escape', sys.exit)

        self.accept("arrow_left", self.incrementCameraPosition, [-1])
        self.accept("arrow_right", self.incrementCameraPosition, [1])
        self.accept("p", self.toggleInterval, [self.pandaMovement])
        self.accept("t", self.toggleInterval, [self.teapotMovement])
        self.accept("w", self.toggleInterval, [self.pandaWalk])
        self.accept("v", ape.base().bufferViewer.toggleEnable)
        self.accept("u", self.toggleUpdateShadowMap)
        self.accept("l", self.incrementLightPosition, [1])
        self.accept("o", ape.base().oobe)

        self.light = ape.render().attachNewNode(p3dc.Spotlight("Spot"))
        self.light.node().setScene(ape.render())
        self.light.node().setShadowCaster(True)
        self.light.node().showFrustum()
        self.light.node().getLens().setFov(40)
        self.light.node().getLens().setNearFar(10, 100)
        ape.render().setLight(self.light)

        self.alight = ape.render().attachNewNode(p3dc.AmbientLight("Ambient"))
        self.alight.node().setColor(p3dc.LVector4(0.2, 0.2, 0.2, 1))
        ape.render().setLight(self.alight)

        # Important! Enable the shader generator.
        ape.render().setShaderAuto()

        # default values
        self.cameraSelection = 0
        self.lightSelection = 0

        self.incrementCameraPosition(0)
        self.incrementLightPosition(0)
Exemple #4
0
    def start(self):
        # The main initialization of our class
        # This creates the on screen title that is in every tutorial
        self.title = OnscreenText(text="Panda3D: Tutorial - Lighting",
                                  style=1, fg=(1, 1, 0, 1), shadow=(0, 0, 0, 0.5),
                                  pos=(0.87, -0.95), scale = .07)

        # Creates labels used for onscreen instructions
        self.ambientText = self.makeStatusLabel(0)
        self.directionalText = self.makeStatusLabel(1)
        self.spotlightText = self.makeStatusLabel(2)
        self.pointLightText = self.makeStatusLabel(3)
        self.spinningText = self.makeStatusLabel(4)
        self.ambientBrightnessText = self.makeStatusLabel(5)
        self.directionalBrightnessText = self.makeStatusLabel(6)
        self.spotlightBrightnessText = self.makeStatusLabel(7)
        self.spotlightExponentText = self.makeStatusLabel(8)
        self.lightingPerPixelText = self.makeStatusLabel(9)
        self.lightingShadowsText = self.makeStatusLabel(10)

        self.disco = self.loader.loadModel("disco_lights_models/disco_hall")
        self.disco.reparentTo(self.render)
        self.disco.setPosHpr(0, 50, -4, 90, 0, 0)

        # First we create an ambient light. All objects are affected by ambient
        # light equally
        # Create and name the ambient light
        self.ambientLight = self.render.attachNewNode(p3dc.AmbientLight("ambientLight"))
        # Set the color of the ambient light
        self.ambientLight.node().setColor((.1, .1, .1, 1))
        # add the newly created light to the lightAttrib

        # Now we create a directional light. Directional lights add shading from a
        # given angle. This is good for far away sources like the sun
        self.directionalLight = self.render.attachNewNode(
            p3dc.DirectionalLight("directionalLight"))
        self.directionalLight.node().setColor((.35, .35, .35, 1))
        # The direction of a directional light is set as a 3D vector
        self.directionalLight.node().setDirection(p3dc.LVector3(1, 1, -2))
        # These settings are necessary for shadows to work correctly
        self.directionalLight.setZ(6)
        dlens = self.directionalLight.node().getLens()
        dlens.setFilmSize(41, 21)
        dlens.setNearFar(50, 75)
        # self.directionalLight.node().showFrustum()

        # Now we create a spotlight. Spotlights light objects in a given cone
        # They are good for simulating things like flashlights
        self.spotlight = self.camera.attachNewNode(p3dc.Spotlight("spotlight"))
        self.spotlight.node().setColor((.45, .45, .45, 1))
        self.spotlight.node().setSpecularColor((0, 0, 0, 1))
        # The cone of a spotlight is controlled by it's lens. This creates the lens
        self.spotlight.node().setLens(p3dc.PerspectiveLens())
        # This sets the Field of View (fov) of the lens, in degrees for width
        # and height.  The lower the numbers, the tighter the spotlight.
        self.spotlight.node().getLens().setFov(16, 16)
        # Attenuation controls how the light fades with distance.  The three
        # values represent the three attenuation constants (constant, linear,
        # and quadratic) in the internal lighting equation. The higher the
        # numbers the shorter the light goes.
        self.spotlight.node().setAttenuation(p3dc.LVector3(1, 0.0, 0.0))
        # This exponent value sets how soft the edge of the spotlight is.
        # 0 means a hard edge. 128 means a very soft edge.
        self.spotlight.node().setExponent(60.0)

        # Now we create three colored Point lights. Point lights are lights that
        # radiate from a single point, like a light bulb. Like spotlights, they
        # are given position by attaching them to NodePaths in the world
        self.redHelper = self.loader.loadModel('disco_lights_models/sphere')
        self.redHelper.setColor((1, 0, 0, 1))
        self.redHelper.setPos(-6.5, -3.75, 0)
        self.redHelper.setScale(.25)
        self.redPointLight = self.redHelper.attachNewNode(
            p3dc.PointLight("redPointLight"))
        self.redPointLight.node().setColor((.35, 0, 0, 1))
        self.redPointLight.node().setAttenuation(p3dc.LVector3(.1, 0.04, 0.0))

        # The green point light and helper
        self.greenHelper = self.loader.loadModel('disco_lights_models/sphere')
        self.greenHelper.setColor((0, 1, 0, 1))
        self.greenHelper.setPos(0, 7.5, 0)
        self.greenHelper.setScale(.25)
        self.greenPointLight = self.greenHelper.attachNewNode(
            p3dc.PointLight("greenPointLight"))
        self.greenPointLight.node().setAttenuation(p3dc.LVector3(.1, .04, .0))
        self.greenPointLight.node().setColor((0, .35, 0, 1))

        # The blue point light and helper
        self.blueHelper = self.loader.loadModel('disco_lights_models/sphere')
        self.blueHelper.setColor((0, 0, 1, 1))
        self.blueHelper.setPos(6.5, -3.75, 0)
        self.blueHelper.setScale(.25)
        self.bluePointLight = self.blueHelper.attachNewNode(
            p3dc.PointLight("bluePointLight"))
        self.bluePointLight.node().setAttenuation(p3dc.LVector3(.1, 0.04, 0.0))
        self.bluePointLight.node().setColor((0, 0, .35, 1))
        self.bluePointLight.node().setSpecularColor((1, 1, 1, 1))

        # Create a dummy node so the lights can be spun with one command
        self.pointLightHelper = self.render.attachNewNode("pointLightHelper")
        self.pointLightHelper.setPos(0, 50, 11)
        self.redHelper.reparentTo(self.pointLightHelper)
        self.greenHelper.reparentTo(self.pointLightHelper)
        self.blueHelper.reparentTo(self.pointLightHelper)

        # Finally we store the lights on the root of the scene graph.
        # This will cause them to affect everything in the scene.
        self.render.setLight(self.ambientLight)
        self.render.setLight(self.directionalLight)
        self.render.setLight(self.spotlight)
        self.render.setLight(self.redPointLight)
        self.render.setLight(self.greenPointLight)
        self.render.setLight(self.bluePointLight)

        # Create and start interval to spin the lights, and a variable to
        # manage them.
        self.pointLightsSpin = self.pointLightHelper.hprInterval(
            6, p3dc.LVector3(360, 0, 0))
        self.pointLightsSpin.loop()
        self.arePointLightsSpinning = True

        # Per-pixel lighting and shadows are initially off
        self.perPixelEnabled = False
        self.shadowsEnabled = False

        # listen to keys for controlling the lights
        self.accept("escape", sys.exit)
        self.accept("a", self.toggleLights, [[self.ambientLight]])
        self.accept("d", self.toggleLights, [[self.directionalLight]])
        self.accept("s", self.toggleLights, [[self.spotlight]])
        self.accept("p", self.toggleLights, [[self.redPointLight,
                                              self.greenPointLight,
                                              self.bluePointLight]])
        self.accept("r", self.toggleSpinningPointLights)
        self.accept("l", self.togglePerPixelLighting)
        self.accept("e", self.toggleShadows)
        self.accept("z", self.addBrightness, [self.ambientLight, -.05])
        self.accept("x", self.addBrightness, [self.ambientLight, .05])
        self.accept("c", self.addBrightness, [self.directionalLight, -.05])
        self.accept("v", self.addBrightness, [self.directionalLight, .05])
        self.accept("b", self.addBrightness, [self.spotlight, -.05])
        self.accept("n", self.addBrightness, [self.spotlight, .05])
        self.accept("q", self.adjustSpotlightExponent, [self.spotlight, -1])
        self.accept("w", self.adjustSpotlightExponent, [self.spotlight, 1])

        # Finally call the function that builds the instruction texts
        self.updateStatusLabel()
Exemple #5
0
 def construct(self):
     self.light = core.Spotlight('slight')
     self.light.setColor(self.color)
from panda3d import core

# Some dummy lights we can use for our light attributes.
spot = core.NodePath(core.Spotlight("spot"))
point = core.NodePath(core.PointLight("point"))
ambient = core.NodePath(core.AmbientLight("ambient"))


def test_lightattrib_compose_add():
    # Tests a case in which a child node adds another light.
    lattr1 = core.LightAttrib.make()
    lattr1 = lattr1.add_on_light(spot)

    lattr2 = core.LightAttrib.make()
    lattr2 = lattr2.add_on_light(point)

    lattr3 = lattr1.compose(lattr2)
    assert lattr3.get_num_on_lights() == 2

    assert spot in lattr3.on_lights
    assert point in lattr3.on_lights


def test_lightattrib_compose_subtract():
    # Tests a case in which a child node disables a light.
    lattr1 = core.LightAttrib.make()
    lattr1 = lattr1.add_on_light(spot)
    lattr1 = lattr1.add_on_light(point)

    lattr2 = core.LightAttrib.make()
    lattr2 = lattr2.add_off_light(ambient)
Exemple #7
0
    def __init__(self):
        ''' init the base class, this will give us access to all the ShowBase functionality
        If you are using python 2.x you could use:
        ShowBase.__init__(self)
        but a better solution is to use Python 3.x,
        Here's a link, go ahead, download it, I'm not going anywhere...
        https://www.python.org/downloads/ '''
        super().__init__()
        ''' By default the background is a dull grey, let's make it black
        colors in Panda3D usually are red, green, blue and alpha values
        (in a 0.0-1.0 range, where 0.0 is black and 1.1 is white )
        but in this case we only have red, green and blue'''
        self.set_background_color(0.0, 0.0, 0.0)

        # Load a model of a empty room
        self.room = self.loader.load_model('models/room_industrial')
        ''' loader returns a node (NodePath), to make it visible
        we need to parent it to 'render' -the root node of the scene graph
        we could use just 'render' but apparently that's un-pythonic'''
        self.room.reparent_to(self.render)
        ''' Now we need to add some crates
        can't have games without crates, I'm almost sure there's a law for that
        we'll load a model and copy it a few times'''
        crate_model = self.loader.load_model('models/crate')
        ''' The crate should be a 1x1x1 cube, but *someone* who knows nothing
        about Blender made the model (it's all wezu's fault!)
        and it's just a wee bit too small- wee need to fix that '''
        # First resize it, just a bit
        crate_model.set_scale(1.033)
        ''' We don't want this extra scale to persist, so we flatten the model
        flatten_light() will just apply the transformations (movement scale, rotation)
         to the vertex of the model
        flatten_strong() will try to merge meshes into as few batches as it can
        flatten_medium() will do something in between '''
        crate_model.flatten_light()
        '''We'll make a list of crates so it will be easy to access them later
        copy_to() makes a copy of a node, parents it to a given node
        and returns the NodePath with that copied node - we'll use that
        list comprehension version for the python savvy...'''
        self.crates = [crate_model.copy_to(self.render) for _ in range(5)]
        '''...for the non-savvy: the above code is equivalent to:
        self.crates = []
        for i in range(5):
            self.crates.append(crate_model.copy_to(self.render))'''
        ''' Now we have the crates all in one place, overlapping - that's no good
        let's put crate #1 on top of create #0, and twist it a bit
        the crates are 1x1x1 cubes with the pivot cantered at the bottom,
        so placing them is easy
        Panda3D uses a Z-up coordinate system (by default)

           Z     Y
            |  /
            | /
            |/____
                   X
         X is right --->

                       /\
                       /
         Y is forward /

                 ^
                 |
         Z is up |
        '''
        # First move it up
        self.crates[1].set_pos(0, 0, 1)
        ''' HPR stands for Heading, Pitch, Roll
        Heading is the rotation around a vertical axis,
        eg. the way a top spins, the way Earth spins, looking left and right
        Pitch is the rotation around a horizontal axis,
        eg. the way your jaw moves, the way a bike throttle in the handle works, looking up and down
        Roll is the rotation in the.. em.. the other axis
        eg. the way clock hands move'''
        # Rotate it a bit, 10 degrees should be fine
        self.crates[1].set_hpr(10, 0, 0)
        # Let's move crate #2 to the side and a bit back
        self.crates[2].set_pos(1, -0.3, 0)
        # Let's make the #3 and #4 crates bigger, and also move them
        self.crates[3].set_pos(3, -3, 0)
        self.crates[4].set_pos(3.1, -1.35, 0)
        self.crates[3].set_scale(1.6)
        self.crates[4].set_scale(1.3)
        ''' Still looks lame. Why don't we change the textures on the small crates?
        I think the crate uses 2 textures - a diffuse(color) texture and a normal (bump) texture
        let's just see what textures the crates have and change the textures if we find anything worth changing
        we will be using some enums defined near the top
        you can use p3d.SamplerState.FT_linear_mipmap_linear in place of FT_MIPMAP
        but first - load new textures'''
        new_diffuse_tex = self.loader.load_texture(
            'models/texture/crate_2.png')
        # loader uses some reasonable defaults, but let's play with the filter type a
        new_diffuse_tex.set_minfilter(FT_MIPMAP)
        new_diffuse_tex.set_magfilter(FT_LINEAR)
        # Same for normal map, but pass the filter types as arguments
        # both give the same result, use what you prefer
        new_normal_tex = self.loader.load_texture(
            'models/texture/crate_2_ng.png',
            minfilter=FT_MIPMAP,
            magfilter=FT_LINEAR)
        # Change the textures only on the last two crates
        for crate in self.crates[-2:]:
            # Model have textures in texture stages
            # so we iterate over all the texture stages of the model
            for tex_stage in crate.find_all_texture_stages():
                if crate.find_texture(
                        tex_stage):  #test if there is any texture to override
                    # texture stages have modes
                    if tex_stage.get_mode() in (TS_NORMAL, TS_NORMAL_GLOSS):
                        # we found ourself a normal map - replace!
                        crate.set_texture(tex_stage, new_normal_tex, 1)
                    if tex_stage.get_mode() == TS_MODULATE:
                        # we found ourself a diffuse map - replace!
                        crate.set_texture(tex_stage, new_diffuse_tex, 1)
        ''' Now it looks... wait, what?
        The texture we loaded is grey! Someone overrode it, and now it's broken!
        No panic - we'll just add some color to the models.
        make crate #3 a nice yellowish-brown color'''
        self.crates[3].set_color((0.8, 0.696, 0.496, 1.0), 1)
        # Make crate #4 a nice brown color
        self.crates[4].set_color((0.66, 0.55, 0.46, 1.0), 1)
        # That still looks bad, but at least you now know how to change colors
        '''ShowBase creates a camera for us, so we can use it without any extra setup
        ...well almost, for this scene we don't want the player to move the camera
        by default the camera can be moved and rotated using the mouse,
        we'll disable that mouse-look, using the worst named function ever:'''
        self.disable_mouse(
        )  # <- this disables the camera mouse control not the mouse!
        # Now we can place the camera in a good spot
        self.camera.set_pos(-7.0, -4.5, 4.5)
        # We could use self.camera.set_hpr() to orient the camera, but it's
        # simpler to just point it at one of the crates, (or a point in space)
        self.camera.look_at(self.crates[4])
        ''' Lets also change the field of view (FOV) for the camera
        ShowBase already has a reference to the default lens used by the default camera
        that lens is available under the name base.camLens or self.camLens
        that name uses the old camelCase naming convention and we want to avoid that
        Let's get the lens from the default camera
        here's the catch - the *actual* camera is *not* self.camera (or base.camera)
        self.camera is a extra node (NodePath class) that has the camera (Camera class)
        ...well, kind of, the camera is also wrapped in a NodePath, hence the .node() call
        ShowBase keeps a this under the name self.cam'''
        self.cam_lens = self.cam.node().get_lens()
        # The fov may change with the size of the window,
        # we'll just increase it to 125% of what it was (both horizontal and vertical)
        fov = self.cam_lens.get_fov()
        self.cam_lens.set_fov(fov * 1.25)

        #Lights
        # First we need an ambient light, else everything not illuminated will be black
        self.ambient_light = self.render.attach_new_node(
            p3d.AmbientLight('ambient'))
        # Remember the use of .node() from earlier?
        self.ambient_light.node().set_color((0.1, 0.1, 0.1, 1.0))
        # Tell Panda3D to actually use this light for anything parented to render
        self.render.set_light(self.ambient_light)
        # Next a directional light
        self.dir_light = self.render.attach_new_node(
            p3d.DirectionalLight('directional'))
        self.dir_light.node().set_color((0.1, 0.1, 0.25, 1.0))
        ''' You can think of the light direction vector as:
        'how much is the light coming from the left, back, and bottom?'
        on a -1.0 - 1.0 scale'''
        light_from_left = 0.2  # the light is a bit from the left
        light_from_back = 0.4  # the light is a bit from the back
        light_from_bottom = -1.0  # the light is coming from the top
        light_vec = p3d.Vec3(light_from_left, light_from_back,
                             light_from_bottom)
        light_vec.normalize()  # <- not needed, but it won't hurt
        self.dir_light.node().set_direction(light_vec)
        self.render.set_light(self.dir_light)
        # Last we add a spotlight, just for shadows
        self.spot_light = self.render.attach_new_node(p3d.Spotlight('spot'))
        self.spot_light.node().set_color((1.0, 1.0, 1.0, 1.0))
        # Make a light cast shadows, and set the shadow map resolution to 1024x1024
        self.spot_light.node().set_shadow_caster(True, 1024, 1024)
        ''' To get a good resolution for the shadow depth map
        you need to fit the near and far planes of the light (lense)
        the more precise the bounds, the better the shadow quality'''
        self.spot_light.node().get_lens().set_near_far(0.1, 20.0)
        # Let's set the light cone to be narrower
        self.spot_light.node().get_lens().set_fov(25)
        # and also to have a smoother falloff
        self.spot_light.node().set_exponent(120.0)
        # spotlights unlike ambient and directional lights need to be
        # placed and oriented in the scene
        self.spot_light.set_pos(-8, 0, 8)
        self.spot_light.look_at(self.crates[3])
        self.render.set_light(self.spot_light)

        # Enable the shader generator,
        # it creates Cg shaders for per pixel lights and shadows
        # It's an older code but it checks out
        self.render.set_shader_auto()
        # Enable MSAA
        self.render.set_antialias(p3d.AntialiasAttrib.M_multisample)
Exemple #8
0
    def setupLights(
        self
    ):  # This function sets up some default lighting with simple shadows
        #ambientLight = p3dc.AmbientLight("ambientLight")
        #ambientLight.setColor((.8, .8, .8, 1))
        #directionalLight = p3dc.DirectionalLight("directionalLight")
        #directionalLight.setDirection(p3dc.LVector3(0, 45, -45))
        #directionalLight.setColor((0.2, 0.2, 0.2, 1))
        #render().setLight(render().attachNewNode(directionalLight))
        #render().setLight(render().attachNewNode(ambientLight))

        # Shadows
        self.light = p3dc.Spotlight("Spot")
        self.light_node = render().attachNewNode(
            self.light)  # generates instance of p3dc.NodePath
        self.light.setScene(render())
        self.light.setShadowCaster(True, 1024 * 4,
                                   1024 * 4)  #.setShadowCaster(True)
        #self.light.showFrustum()
        # This exponent value sets how soft the edge of the spotlight is.
        # 0 means a hard edge. 128 means a very soft edge.
        #self.light.setExponent(60.0)
        # Attenuation controls how the light fades with distance.
        # The three values represent the three attenuation constants (constant, linear and quadratic)
        # in the internal lighting equation. The higher the numbers the shorter the light goes.
        self.light.setAttenuation(p3dc.LVector3(0.3, 0.0, 0.0))
        # The cone of a spotlight is controlled by it's lens. This creates the lens
        self.light.setLens(p3dc.PerspectiveLens())
        # This sets the Field of View (fov) of the lens, in degrees for width
        # and height.  The lower the numbers, the tighter the spotlight.
        self.light.getLens().setFov(40, 40)
        #self.light.getLens().setFov(40)
        self.light.getLens().setNearFar(0.5, 500)
        self.light.setColor((0.6, 0.6, 0.8, 1))
        ############################################################
        ####\/########\/########\/########\/########\/########\/####
        #self.light_node.setPosHpr(0, -10, 15, 0, -50, 0) #This does not light the tiles... (similar to https://discourse.panda3d.org/t/shadows-with-directional-light-source-strange-behaviour/10025 )
        #self.light_node.setPosHpr(0, 10, 15, 180, -50, 0) #This works as intended
        #self.light_node.setPosHpr(0, 0, 8, 0, -80, 0) #This lights half the tiles but I don't know why this works to a degree but the first one doesn't at all
        self.light_node.setPosHpr(0, 8, 12, 180, -50, 0)  #This is now used
        ####/\########/\########/\########/\########/\########/\####
        ############################################################
        render().setLight(self.light_node)
        #
        #
        #
        #self.light2 = p3dc.Spotlight("Spot")
        #self.light2_node = render().attachNewNode(self.light2) # generates instance of p3dc.NodePath
        #self.light2.setScene(render())
        #self.light2.setShadowCaster(True, 1024, 1024)#.setShadowCaster(True)
        ##self.light.showFrustum()
        ## This exponent value sets how soft the edge of the spotlight is.
        ## 0 means a hard edge. 128 means a very soft edge.
        #self.light2.setExponent(60.0)
        ## Attenuation controls how the light fades with distance.
        ## The three values represent the three attenuation constants (constant, linear and quadratic)
        ## in the internal lighting equation. The higher the numbers the shorter the light goes.
        #self.light2.setAttenuation(p3dc.LVector3(0.3, 0.0, 0.0))
        ## The cone of a spotlight is controlled by it's lens. This creates the lens
        #self.light2.setLens(p3dc.PerspectiveLens())
        ## This sets the Field of View (fov) of the lens, in degrees for width
        ## and height.  The lower the numbers, the tighter the spotlight.
        #self.light2.getLens().setFov(40, 40)
        ##self.light2.getLens().setFov(40)
        #self.light2.getLens().setNearFar(0.5, 50)
        #self.light2.setColor((0.6, 0.6, 0.8, 1))
        #self.light2_node.setPosHpr(0, -10, 15, 0, -50, 0)
        #render().setLight(self.light2_node)

        self.alight = render().attachNewNode(p3dc.AmbientLight("Ambient"))
        self.alight.node().setColor(p3dc.LVector4(0.1, 0.1, 0.1, 1))
        render().setLight(self.alight)

        # Important! Enable the shader generator.
        render().setShaderAuto()