3D_for_GML:_Directional_lights - hpgDesigns/hpgdesigns-dev.io GitHub Wiki

1.1 About light types

Game Maker 6 allows you to create two types of lights: point lights and directional lights. Roughly speaking, point lights are lights that emit light from a single point in all directions. Think of a point light as a lit candle in a dark room, its light revealing the walls, ceiling and floor. Its light shines in all directions more or less equally. That’s the one type of lights you can create in GM6. The other type of lights is: directional lights. Directional lights are the opposite of points. They don’t emit light from a single point. If you think of a point light as one point emitting many rays in all directions, you can think of a directional light as many points emitting rays in one direction. It’s quite the opposite. In this tutorial we will look at directional lights.

1.2 Setting up lights

It’s time to take a look at the first editable file (gm6 file). Take a look at the script init_camera. In it, we set up 3d Mode (see Getting Started With 3D) like we are used to. But this time we will want to use lights, so:

//switch lighting on
d3d_set_lighting(true);

Also, to focus on lighting a bit better, we’ll disable fog:

//draw fog
d3d_set_fog(false, c_black, 1, 1024);

The rest is business as usual. What we have basically done now is telling GM that we want to use lighting but we have not defined any lights yet. It’s like sitting in a restaurant but not having ordered yet. So, let’s order:

//define light
d3d_light_define_direction(0, 0, 0, -1, c_white);

We have now defined a light with index 0. It’s best to number your lights in a simple way: 0 for the first light, 1 for the second and so on. The first value defines the light index which is the number of the light in the order of all lights you will create. The next three values (0,0,-1) define the light’s direction (dx,dy,dz). You can see that the light has no x or y direction but only a z direction (value of -1). This means the light points down (negative z). In other words, the light will shine from the top down. The direction of the light is downwards along the z axis because we want to shine light on a ground object from the top. Aha, here’s our order:

//draw lights
d3d_light_enable(0, true);

This script will be running in the Draw event of the object obj_lights. The first argument (or value) defines the light we want to draw and the second argument works like a light switch. Set it to true and the light will be switched on, set it to false, light will be switched off. That’s all it takes to set up lights. I’ve added a camera and ground to allow the player to walk around in a virtual space and have a look around (see First Person Mouselook).

1.3 Colored lights

Remember to the previous paragraph where we ordered a light? We ordered a white light. What if we wanted a colored light? I’ve put some keyboard events in the object ‘obj_lights’ (A, S and D keys) to switch between light colors. Using argument0 to set the color, we will run the script init_lights again whenever a key is pressed:

//define light
d3d_light_define_direct ion(0, 0, 0, -1, argument0);

Now, pressing a key will change this light’s color. By the way, the color is entered in the Action of the keypress event, as you can see in this image: Setting the color of light as an argument. Note that to change the color of a light, you do not need to change the drawing code. It remains unchanged no matter what color you set for the light.

1.4 Multiple lights

If you take a look at the gm6 file (of Part C), you will find the code in script init_lights slightly changed:

//define light
d3d_light_define_direction(0, d3d_light_define_direction(1, 0, 0, -1, c_white);
0 ,0, 1, c_lime);

You can see that a second light has been defined with index 1, a direction of (0,0,1) which means point straight upwards, using a lime color. Also, a ball object has been added that runs the following code in its Draw event:

//draw lights
d3d_light_enable(0,true);
d3d_light_enable(1,true);

//get texture
tex=background_get_texture(bac_Leaves);

//draw ball
d3d_draw_ellipsoid(x-32, y-32, z-32, x+32, y+32, z+32, tex, 1, 1, 32);

As you can see, both lights are enabled when drawing the ball. This means the ball will be lighted from the top (light 0) and the bottom (light 1). In other words, the object will be lighted by multiple lights. Note that the script to draw the ground (draw_ground) has been changed too:

//draw lights
d3d_light_enable(0, true);
d3d_light_enable(1, false);

The ground will only be lighted from the top (light with index 0). The second light (index 1) is not enabled. In this way you can create a whole range of objects with their own lights and choose which ones to enable or disable in each object’s Draw event. Let’s take a closer look at creating multiple lights and combining them.

1.5 Combined lights

In this gm6 file a range of lights has been defined (in init_lights):

//define l ight
d3d_light_define_direction(0, 0, 0, -1, c_white);   //from top
d3d_light_define_direction(1, 0, 0, 1, c_lime);     //from bottom
d3d_light_define_direction(2, 1, 0, 0, c_red);      //from side
d3d_light_define_direction(3, 0.25, -0.5, -0.5, c_aqua);//from angle

We will combine the lights with index 1, 2 and 3 to create combined lighting on one object, in this case our ball object. When drawing the ball object, we will enable four lights:

//draw lights
d3d_light_enable(0, true);
d3d_light_enable(1, true);
d3d_light_enable(2, true);
d3d_light_enable(3, true);

The combined lighting will be used to light the 3D shape, revealing its texture and shape. Also, it will create a shadow on one side which can be used for dramatic effects in level design. Speaking of shadows...

1.6 Fog and shading

Two things are shown in this part: fog and shading. Let’s take a look at the init_camera script (of the gm6 file of Part E):

//draw fog
d3d_set_fog(true, c_black, 240, 480);

The fog has been set in a tutorial about lights for a reason. Though limited in its use, it can create a virtual point light around the camera object. Also, using the black fog against a dark blue background gives the effect of dark outlined shadows.

To end this tutorial, if you take a close look at the ball objects, you will see that their textures are not really smooth. In some cases, this effect is desireable. In other cases, it is preferable to have the light and shadow hit the object in a smooth way. This is called shading. In the init_camera we find this code that turns shading on:

//switch shading on
d3d_set_shading(true);