Welcome back. Last time we did a quick introduction to Game Maker 3D using Game Maker Studio 2. Before we can continue to create 3D objects and the rest of the stuffs, we need to discuss about shaders.

(If you missed part 1 of the tutorials, you can read it here)

First of all shaders are a whole topic on their own. So this will be just an overview of how shaders work and what sort of things we may encounter when working with them using GMS2

Default shaders used by GMS2
This is the shader by default used by GMS2

By default, GMS2 creates a shader using a language very similar to GLSL ES. You can follow the official specifications to get a whole overview of the language.

You can also change the language to GLSL and HLSL 11 If you are targeting a specific platform. Because GLSL ES is supported by all platforms and it is also the default selection by GMS, this is the language that we are going to use.

Types of variables

GLSL ES is a strongly-typed language, this means that all the variables must have a type that specifies what kind of data it can handle.

Definition of a variable in GLSL
The order is: type variable = value;

There are several types and modifiers you can apply to it. This is a list of the basic types, but please refer to the official documentation for the full explanation.

To put it in simple words, there are just a few types that you need to think about:

  • Your basic variables from all languages:
    • bool – for conditionals.
    • int – for integer numbers.
    • float – for numbers with a floating-point.
  • Vectors – they can be of different dimensions:
    • 2 dimentional (x,y)
    • 3 dimentional (x,y,z)
    • 4 dimentional (x,y,z,w)
    • They can also have different accesors for when you are dealing with different types of data.
      • The general use accesors are: (x,y,z,w).
      • If you are dealing with colors you can use: (r,g,b,a).
      • If you are dealing with texture data then: (s,t,p,q).
      • so basically x==r==s and y==g==t and so on.
    • They can be of different types depending on the first letter:
      • vec is used for float vectors.
      • ivec is used for integer vectors.
      • bvec is used for boolean vectors.
  • Matrices – The basic usage is to represent things like transformations and projections. They can also have many dimensions.
  • Samplers – Used for texture data. They can also have many dimensions.

To get a full overview of how you can use vectors and matrices you can see a tutorial in lineal algebra. This tutorial from wolfire explains how to use lineal algebra for game development: Link to his blog

Vertex and Fragment Shaders

First, there are 2 types of scripts that we have to work on for every shader.

Vertex Shader

Default Vertex Shader
The default vertex shader created by GMS

The vertex shader has 2 main tasks:

  • Set the position of the geometry to be displayed in the screen. This is achieved by multiplying the geometry data with the object translation and camera projection (we’ll look at this in the next tutorial). The result must be put in gl_Position
  • Pass data to the fragment shader. This data is interpolated between vertices. For example: if one vertex is red and the one next to is green, then it will be interpolate between red and green having yellow in  the middle (which is why our triangle in the last tutorial displays many colors by only having red, green and blue assigned to the vertices).

Fragment Shader

Default Fragment Shader
The default fragment shader created by GMS

The fragment shader has only one task and that is to say which color should a pixel in the screen be, this is done by combining different techniques such as: reading texture data, calculating lightning and shadow information and putting it into the gl_FragColor.


Definition of attributes in GLSL
Definition of an attribute.

We can only work with attributes in the vertex shader.

They represent the data from the vertices of the geometry. For example, the vertices position, colors, texture coordinates, joints weights, indices, among others. It can be used in creative ways to send different data to the GPU but those are the usual uses.

The trick is that you can only handle one vertex per operation. So for example, in our example from the previous tutorial we drew a triangle. It had 3 vertices but in the vertex shader we can only handle one vertex and we don’t have any sort of access or information about the other vertices (or even what vertex are we working in).

The reason for this is that the GPU needs to work on as many vertices in parallel as possible to complete the operation.

Attributes In Game Maker

Usually when you work with shaders you can create as many attributes as you want and you can name them however you want. In Game Maker instead we only have a bunch of attributes created and we cannot change their name.

This are the basic ones you can use (You can extend them to have more with a bit of trickery, but for now this would be enough).

GMS2 attributes
Basic attributes in GM Shaders

In order of lines they are for the vertices positions, the normals (for lightning calculations), colors (per vertex) and texture coordinates. We’ll work with them in the next tutorials.

Passing attributes in GMS2

The way we pass the attributes from Game Maker to the GPU is through a vertex format and a primitive. We already saw this in the previous tutorial:

Defining a Vertex Format

Create a vertex format
Defining a vertex format

First we need to define which attributes we are going to use. In the example above we said that we want to use vertex positions (in_Position) by calling the method vertex_format_add_position_3d() and vertex colors (in_Colour) by calling the method vertex_add_color(). We store the result in a variable to work later with it (global.VERTEX_FORMAT).

Defining a Primitive

Create a primitive in GMS2
Creating our triangle primitive

We’ll talk more about building primitives in it’s respective tutorial. But for now, the only thing you need to know is that when you build a primitive you have to follow the same order in which you specified the vertex format. You can see that first I pass a position vertex_position_3d and then I pass a color vertex_color and I always do it in that order.

You can see the constant use of the variable buffer this is the variable that contains the primitive.

Passing the Primitive to the Shader

Submitting a primitive to the shader
Drawing our triangle

To draw our primitive we only need to call the method vertex_submit and pass the variable that contains our primitive.


Defining a uniform in GLSL
Declaration of a uniform in GLSL

The next one to talk about are uniforms. We didn’t see them in our last example, but they are used to pass single data to the GPU. So for example, let’s say you want to color a character depending on how much health he has. If it’s full, then it displays the character with his normal colors, but if it’s almost dead then you may want to display him with a red color. You can pass a color through a uniform that specifies this level of damage.

uniform vec4 u_vHurt;

The uniforms are visible in both shaders, there is no limit on how you want to use them, as it is basically a variable you put a value in. The main usages that we are going to see however are: pass the projection and transformation matrices (We’ll do this in the next tutorial) and pass the image to texture our objects (we’ll do this in a later tutorial).

Passing Uniforms in GMS2

First you need to get the address of the uniform. This is done by a simple call in GML:

Getting a uniform address in GMS2
Obtaining an uniform address

Here we are obtaining the uniform u_vHurt that we defined in the shader shd3D and we are storing it’s address in the variable u_vHurt (It’s a good idea to name this variable the same as it is in your shader).

We only have to do this once, so we usually put this in a script at the beginning of the game (in our case it would be the script scrInitSystem).

Obtaining samplers (The uniforms for the texture) Is done different. But we don’t have to worry about it unless we are working with more than 1 texture.

Sending the Data to the Shader

Now that we have our uniform in a variable we need to send the data. Depending on what type of data we want to send, we’ll have to use a different function:

  • shader_set_uniform_f: This one is used to send floats into a uniform: shader_set_uniform_f(u_vHurt, hurtRed, hurtGreen, hurtBlue, hurtAlpha);
    • There is a variation called shader_set_uniform_f_array which is used to send an array of floats instead of the values themselves: shader_set_uniform_f_array(u_vHurt, hurtColor);
  • shader_set_uniform_i: The same behavior than the previous one but you can only send integer values with this. (You can also use the shader_set_uniform_i_array variation to send a array of values).
  • shader_set_uniform_matrix_array: This one is used to send a matrix through a array: shader_set_uniform_matrix_array(u_mProjection, projectionArray); It also has a version without the _array part but it has a different behavior left for the constants of GMS2, we are not going to use that version though.


The last thing we need to talk about are the varyings.

Defining a varying in GLSL
Definition of a varying

They are defined in the shaders themselves so you don’t pass data directly to it.

They need to be included in both the vertex and fragment shaders. And must be called exactly the same with the same type as well.

They are used to interpolate values between vertices (usually passed through an attribute). Reviewing our example of the triangle again. We have 3 vertices, and each vertex has a color and a position assigned to it. We used a varying to interpolate the colors. That’s why it changes from one vertex being red, going slowly to yellow and finally getting green in the next vertex

Displaying a triangle with color interpolation
In the middle it gets gray because all the colors (RGB) are the same value there

Passing a Varying from the Vertex to the Fragment shader

Using varyings in GLSL
We are interpolating the colors in this example

First you can see we defined the varying vec4 v_Colour; Then inside the main method. In line 11, we are defining which value is this vertex going to have (one is red, the other is green, the final one is blue) by assigning the varying (v_Colour) with the value obtained from the attribute (in_Colour).

Receiving the Varying in the Fragment Shader

Reciving varyings in a fragment shader
Receiving the varying

In the first line you can see the same definition of the varying vec4 v_Colour; Same type, same name.

In this step the variable is already interpolated. We may have a red value, a yellow, a green or a gray.

The final step is in line 5 where we output that color to the screen (gl_FragColor).

Wrapping up

There is still a lot to be written about shaders. As I said at the beginning they are a full topic on their own. But with this little info we can start sending data to the GPU and have all sort of interesting effects going on.

This is going to be all for this tutorial. In the next one we are going to talk about the projection and transformation matrix.

Thanks for stopping by.

I always wanted to talk about 3D development using game maker but I never really found a format that I liked. I made some small courses in spanish over Youtube but I never was quite happy with how it was scalling, so this is a new attempt to bring this topic to the people.

Now, I know, why would you even attempt to create 3D games with Game Maker when tools like Unity, Unreal and Godot are much better for this task and have very good license deals?

Well, I don’t really have an answer to that, those engines are obviously much better than Game Maker will ever be for 3D. with that being said, there is still knowledge to be gained with this experiment.

While Unity and the others are really powerful, they remove a big chuck of the pipeline involved in the 3D rendering. This is great for businesses obviously, since you want to use the shortest path possibble to release your product, but if you want to improve your skills as a programmer then you should really tackle this and many other difficult tasks.

This mini course is just going to talk about how to set up a 3D dev environment using Game Maker Studio 2, any tutorial beyond that will be made in a general OpenGL/WebGL engine.

You don’t need any previous experience doing 3D, but you should be confortable using the Game Maker Engine before continuing.


It may sound like a simple task, but this is the most important step. It happens more often than not that when you set up your 3D environment you don’t get to see anything you drew to the screen. Debugging an OpenGL application can be a real pain. That’s why it’s important to make sure you can draw things.

You can find a Github repo for this course in at the end of this post.

Let’s start by creating our assets in the project. Open Game Maker Studio 2, create a new project and add this files:

  • A script called scrInitSystem, this one will be used to initialize all the global variables needed for this project.
  • A shader called shd3D, Since Game Maker uses a 2D shader by default, we will create our own shader.
  • An object called objSystem, this is the main object for the game, it’s going to handle all the 3D functions.
  • An object called objTriangle, This is our object to be displayed.
  • room should be added by default by the engine.

By now, your hierarchy should look like this:

The hierarchy of the project showing all the assets created so far.
This is how your project should look so far


Let’s start by modifying our shader. Now, if you don’t know how to use shaders, they are a whole topic on their own. We will discuss them on time but for now I just want you to copy what I’m going to show you.

This is how a shader looks by default when you create a new one:

Default shader created by Game Maker
Vertex Shader of a new Shader

What we are going to do is to eliminate all of the unnecesary data and leave only the attributes needed to place our triangle, and then add color to it.

Make sure you are on the first tab shd3D.vsh this is the vertex shader, and paste this code.

Custom Vertex shader that receives a color and a position
Vertex shader

Then, go to the second tab shd3D.fsh which is the fragment shader, and add this.

Custom Fragment shader that draws a color to the screen
Fragment shader

As I said, don’t worry too much about what we just added, because we will talk about shaders in detail in another post. Basically what this shader does is: It receives 2 types of parameters: a position, and a color. Then, it interpolates between the colors from vertex (position) to vertex. Finally it draws it to the screen.


Let’s continue with this script, the objective is to initialize all the global variables that we are going to need, this script should be executed at the beginning of the game by the objSystem. This is how it should look:

Initialize the vertex format to be used in the 3D application.

Since we added a custom shader that receives a position and a color, we need to make sure that we are going to send that same data. So what this script does is to create a new format (vertex format) and then we tell it that we are going to first send a position (vertex_format_add_position_3d) and then a color (vertex_format_add_color). This order is extremely important because later when adding our primitives (the triangle in this case) we need to create it using the same order.


This is the object that will control how things are going to be draw in the future. For now it is a really simple object.

Add the create event for this object and add this lines:

Event Create for the objSystem
Event Create for the objSystem

The first line calls the scrInitSystem script and the second line creates the objTriangle. Nothing more.


Finally, the star of this tutorial. The objTriangle Is going to create the primitive and then it will send it to the shader where it will be draw.

Add the create event and add the next content:

Event Create for the objTriangle
Event Create for the objTriangle

Lines 2 and 3 are used to tell Game Maker that we are going to build a primitive. Note the use of global.VERTEX_FORMAT this is the format we created in the script scrInitSystem. Remember that it has an order that we need to respect.

The lines 6-7, 10-11 and 14-15 are used to create the geometry of the triangle, we will talk more about this in another post, but you can see that we kept the same order always: first position_3d, then color

The last line is to indicate that we are done building our object.

Now, let’s move onto the draw event

Draw Event for the objTriangle
Draw event for the objTriangle

First, in line 2: we are setting our custom shader to be used.

After that in line 4: we are submitting our geometry (created in the create event of the objTriangle) to the shader, (don’t worry about the pr_trianglelist and the -1, we’ll talk about that in the primitives tutorial).

Finally we reset the shader to use the default of Game Maker, this is so to avoid any conflicts with other things being draw.

Adding things to the Room

The last thing left to do is to add the instances to the room. You only need to add the objSystem since that object is the one that creates the triangle after the global variables are initialiazed.

Objects added to the room
Note that the only object added is the objSystem

And that’s it! if everything was added correctly, this is how your game should look when you run it:

The result of this tutorial
So  awesome!

It may not look like much, but as I said, this is the most important step. The next tutorials will talk more in focus about specific topics: Matrices, Shaders, Cameras, Primitives, etc.

Congrats if you made it this far! If something maybe didn’t work then you can ask me in the comments section or you can download the source code for this and the other tutorials:


Continue now to part 2

Thanks for stopping by and have a nice day!

I was busy last week doing a game for a little challenge that took place over the YoYoGames forums. The idea was to create a pseudo 3D game using Game Maker without using any of the d3d functions that the program offers.
So I decided to go with something simple, a raycaster engine in GML, I’ve done many raycasters previously in JS so I’m very familiar to how it works, since the other participants were doing amazing 3D projects I decided to aim to the “fun” category so I took one of the pieces of my last current project (also in GM) Wraith and did a First Person Shooter / Tower Defense mix.
There were 3 categories in which the games were qualified and I made it at the top 3 of those 3 categories:

3D Rendering
1. Xor
2. orange451
3. Jucarave

1. RoundCircleandSphere314628
2. Jucarave
3. Klong

speed/performance (In no particular order)

So I’m very pleased with the results 🙂

The versión of the contest can be found here:

I continued the development of this project (now called Wraith) This is the end of the 3rd week and most of the work has been directed towards the optimization of the engine, it was running pretty well but I don’t really enjoy having so many instances doing nothing.
The first thing I did is to modify the way the geometry and solid instances were handled in GM, I had before one instance per block and the geometry was the same size of the block:
Each individual color is a collision mask and 3D geometry:
I merged the horizontal and vertical collisions and the geometry is merged by texture.
Finally, I started working on a single level to test enemies encounters and the gameplay elements. If everything goes well then I will have a demo version towards the end of February.

So this new year I decided to start a new project and take a step back from the RPGs I’ve been trying to develop for the last years… My favorite games are the first person shooter and they are actually what got me into game development in the beginning, since I had an old license for Game Maker Studio I decided to give it a try and start a new project.
I know there are far better tools than Game Maker to make a 3D game, but that’s also the reason I picked GMS, it’s because I know it has a great potential for this kind of task, I already tried to develop a 3D game with GM 6 years ago and it failed, but it was done with GM8 and it was poorly optimised so I want to make it better now.
I’ve been developing it for 2 weeks now, most of the time has been working in the engine itself but I’m aiming to have something playable towards the middle or end of February
The gameplay will be based on old fps (Doom, Quake, etc) in which the action is faster and there is few story elements during gameplay, the game itself will have a story although I’m still thinking on how to present it without taking much of the game. It will have a single player campaign and a multiplayer mode, the weapons and game are going to be futuristics but in a wasteland environment.
The textures I have now (except for the gun) are from the game hexen but I’m going to replace all of them with custom made textures, I’ve done so far the collision detection in 3D (very simplistic for now since the maps are made on a grid), picking up weapons and firing making bullet holes on the walls, a terminal (like quake) to make modifications to the game and system messages for when picking weapons or making actions.
That would be all for now, I will be posting updates on this game hopefully every week with the new features I added to it.