Hour 15. Materials and Shaders
What You’ll Learn in This Hour:
Making 2D materials inGodot
Making 3D materials
Applying multiple material passes
Writing simple shaders
In this hour, you’ll learn about materials inGodot. First, you’ll see the simple 2D materials, then you’ll learn about the complex but powerful 3D
materials. You’ll also learn how to write shaders and add nice effects to your scenes.
Canvas Item Materials
Materials are special resources that change the appearance of the objects, which are especially useful for 3D models. The 2D materials are
extremely simple. There’s nothing much you can do in this matter, because the 2D engine is based in pixels and textures drawn directly into the
screen and without the need to process vertex positions and lighting, which is needed in 3D.
To add a material to a node, it must be derived from
Node2D or
Control. Then, using Inspector, you can set the material property to
a new
CanvasItemMaterial resource. If you click to edit it, you’ll notice there’s only two properties.
Blend mode sets up how the node will be inserted into the canvas. It’s like what you can see in graphical editing software. The options are not
as extensive, but they are enough for most of the games. Table 15.1 shows the different blending modes, and the effects are shown in Figure
15.1.
TABLE 15.1 Blend Modes
PropertyDescription
Mix
Mixes the image in the regular way, i.e., renders it on top of the background, replacing the pixels.
Add
Sets the color as the addition between the background and the texture, summing the RGB values.
Sub
Subtracts the color values of the texture from the background. It can generate an effect of a negative if the background is transparent.
Mul
Multiplies the values of the background and the texture colors
.
Premult
Alpha
Pre-multiplies the alpha values of the texture. Usually, the RGB values are independent from the alpha, but with this mode, the final
output is the color values multiplied by the alpha value. This is used to achieve a more correct blending between objects, but it has to
be set in the texture at import time as well as in the material.
FIGURE 15.1
Effects of different blending modes.
The other option for this type of material is the Light mode. It indicates how lights interact with an object, and is useful for creating a masking
effect, as will be seen in the next hour.
NOTE
Render Priority and Next Pass
These two options are common in every type of material, including the shader and particle types. The Render Priority is used for objects with
no depth test to decide which will be shown in front (higher priority objects are shown first).
The Next Pass property allows you to set up a chain of materials that are used in order. This allows you to make more complex effects and, for
instance, add a shader code to regular material.
Other Canvas Item Properties
Despite not being part of materials, there are a few properties in the
CanvasItem node that have functions to change the appearance of
objects.
The Visible property name speaks for itself. This is the property with which you interact when clicking the eye icon in the Scene dock. Another
simple property is the Show Behind Parent. Usually, the nodes lower in the tree are shown on top, so this property allows you to reverse the
behavior for certain items.
The Modulate and Self Modulate settings apply a tint to an object, and the alpha value can be used to make it transparent. The difference
between the two is that Self Modulate applies only to the object, while Modulate also applies to the object’s children.
Spatial Materials
Spatial materials are applied to 3D models, so the project can become quite complex and full of options. Still, most of the options are quite
common for 3D artists and can be found on modeler software. Godot 3 uses a physically based rendering (PBR) workflow, the current modern
111111111
22222222standard for 3D shading, as opposed to the classic Phong shading.
SpatialMaterial can be either imported from an external model such as a GL Transfer Format (GLTF) file exported from a 3D modeler
software or developed directly inGodot itself using Inspector. You can create a new
SpatialMaterial resource by setting the Material
property of an object that accepts it (such as the MeshInstance node or the Mesh resource).
Flags
The first section of the material properties is called Flags (see Table 15.2). It sets a few options that change how the material behaves in
general. These options may take a hit on performance, so you’ll need to consider what you really need when changing them (see Figure 15.2).
TABLE 15.2 SpatialMaterial Flags
Property
Description
TransparentIf enabled, the material will be treated as transparent. This is not enabled by default, because transparent objects are rendered
with a different, more expensive technique. Some effects need opaque materials to work (such as SSAO), and won’t be available
for transparent items.
Unshaded Disables the effect of light onto the object and shows its own default color.
Vertex
Lighting
Godot uses a per-pixel lighting by default, which usually gives better results. But this can be too costly in some cases, especially
on low-end devices, so you can enable per-vertex lighting, which needs less computational power. Note that only directional lights
produce shadows if this is enabled.
No Depth
Test
Usually, objects appear in front of the ones in the back. You can change this behavior by enabling this option so that objects are
drawn in front of everything else, independent of position. With this, you can make use of the Render Priority property presented in
the last note.
Use Point
Size
If the imported geometry is made of points (instead of triangles, as is more usual), you can use point size to render. Check the
Parameters section to specify the point size.
World
Triplanar
If you’re using triplanar mapping, this makes the material use coordinates in world-space instead of the default local-space.
Fixed Size When this is enabled, the object is always drawn in the same size, irrespective to its distance to the camera.
FIGURE 15.2
The sphere has a fixed size and no depth test, so it’s always in front and doesn’t get smaller with distance unlike the cube. This can be used for
visual indicators.
Vertex Color
Usually, Godot ignores the vertex colors of the geometry. If you want to use them, you’ll need to enable the Use as Albedo property. Many 3D
modeling software uses the SGRB color space when exporting, so if the vertex colors are in this format, you’ll need to tell the engine to correct
the colors.
Parameters
The following section in the material configuration has several parameters to set up rendering details. You can use this to tweak the material or
achieve special effects.
Diffuse Mode
In this mode, you can select a different algorithm for diffuse. This changes how the light is scattered when it hits an object. Table 15.3 lists the
available modes, and Figure 15.3 shows the modes.
TABLE 15.3 SpatialMaterial Diffuse Modes
Mode
Description
LambertThe default mode. It reflects the light equally from all viewing angles, and isn’t affected by roughness.
Lambert
Wrap
Extends the previous algorithm to cover a larger area when roughness increases.
Oren
Nayar
Creates a virtual roughness to the material and treats the surface as imperfect, which changes the reflection of light depending on the
angle (from the viewer’s position). This is an interesting effect to apply on clothing and clay.
Burley
Uses the original physically based shading (PBS) material developed by Brent Burley at Walt Disney Animation Studios.
Toon
In this mode, the light is cut hard (like a cartoon). The smoothness can be tweaked with the roughness property.
FIGURE 15.3
Different diffuse modes (in the order presented in Table 15.3).
Specular Mode
This affects the specular highlight point on the object. This is an important detail in determining the shape and position of objects by the human
eye, and also represents the shape of the light source.
The Schlick-GGX mode is the most common in modern PBR engines, and is a sane default for most applications. Blinn and Phong modes are
used by old renderers and are available for compatibility purposes, but they aren’t very useful unless you’re going for a retro feel. Toon mode
111111111
22222222creates a cartoon-like specular blob, and its size varies with the roughness property.
TIP
Disabling the Specular Highlight
While the Specular highlight is a cool effect that gives a somewhat realistic feel to your scene, sometimes it gets in the way. You can disable it
completely by selecting this option in the Specular mode property.
Blend Mode
Determines how the material will be mixed into the scene. This is the same as the one available in
CanvasItemMaterial, so you can refer
to Table 15.1 to see what each mode does.
Other Parameters
You can change the Culling mode of the objects too. The default is Back mode, which hides the back faces of the object. If set to Front mode,
only the back faces will be visible. Disabled mode makes the object double-sided.
You can also specify depth rendering using the Depth Draw mode property. This especially affects how partially transparent objects, such as
foliage or hair, will look and cast shadows. You can set to draw depth for opaque only, which is the sane default. It’s possible to set it to Always
or Never, too. The remaining option is the Opaque Pre-Pass mode, which will make a pass for opaque parts and a second pass on top for
transparent parts.
Line Width and Point Size adjust the size of the lines and points, respectively. Line Width is usually not available on modern hardware, and
Point Size only makes sense for point-based geometry.
Billboard mode specifies how an object faces the camera. Enabled mode will make the negative Z-axis of an object always face the camera.
The Y-Billboard option will align the X-axis instead. There’s also a mode specific for particles, which enables animation options.
The Grow option makes the vertices of the objects move away, following their normal vectors. This can be useful in a second-pass material for
some effects. The Alpha Scissor option cuts the alpha of the material based on a threshold, so it’s rendered always as 0 or 1, never in
between. This can also be useful, as the material can be treated as opaque and receive the mid- and post-processing effects that rely on this
(such as SSAO and SSR).
Albedo
This is where the main colors of the object are defined. This was done in the Diffuse channel in previous rendering engine generations, but the
Albedo does more than diffuse light. This is the only thing visible if the Unshaded option is enabled.
There’s both a color and a texture, which can be used together since th
e
ir values are multiplied to get the final color. If the color is white, the
albedo texture will be shown as is. The resulting alpha value will be used from a transparent if either the Transparent flag or the Alpha Scissor
option is active.
Metallic and Roughness
These are the main parameters of the PBR workflow used byGodot 3. They are important settings in the PBR workflow, and most materials
can be reproduced by fine-tuning them.
The Metallic property determines the reflectivity of a material. A higher value makes it reflect more light. Note that it’s impossible to make a
material totally unreflective. Even if you set this property to 0, Godot will use the minimum reflectivity of four percent.
Roughness indicates how the reflection happens. A material without roughness acts as a perfect mirror (see Figure 15.4). As you add to this
value, it starts blurring the reflection, mimicking the effects of a micro-surface as in real life.
FIGURE 15.4
Different values for Metallic and Roughness properties. The first row shows 0 Metallic with both 0 and 1 Roughness. The second row shows the
same values for Roughness but with Metallic set to 1.
NOTE
Specular/Glossiness versus Metallic/Roughness
You may have heard this discussion if you searched the web for PBR. Godot 3 supports only the Metallic/Roughness approach, which is more
closely related to how materials work in the real world. Other game engines use the Specular/Glossiness workflow, while some support both.
This is something to keep in mind when designing your assets, since the conversion between the two systems isn’t straightforward.
Other Properties
There’s a lot of detail in the
SpatialMaterial properties. Table 15.4 shows properties not mentioned so far. You can get more information
by looking at Godot’s documentation.
TABLE 15.4 Remaining SpatialMaterial Properties
Property
Description
Emission
Makes the object emit light. It will not illuminate its surroundings unless used within a GIProbe.
Normal Map
Changes the angle of the reflecting light, allowing for greater detail without making the geometry more complex.
111111111
22222222Rim
Makes a micro rim around the object, like the fur around some types of fabric. Note that this depends on incident light.
Clear Coat
Simulates the effect of coating or waxing the object.
Anisotropy
Changes the Specular highlight to make it follow the surface. It works better when combined with a flow map (which can be set
in the same section).
Ambient
Occlusion
Lets you set a texture with the baked occlusion from ambient light. This can make the scene look better than with a generated
occlusion (such as SSAO).
Depth
Allows you to add a depth map, which can increase the effectiveness of a normal map by giving the illusion of depth without
complex geometry.
Subsurface
Scattering
Simulates how light penetrates a surface and is reflected back to the exterior after being scattered. This is very useful in
creating realistic-looking skin.
Transmission
Sets up the transmission of light from the lit side to the dark side. It’s useful for thin objects.
Refraction
Changes the alpha blend mode to show the content behind the object in a distorted way, similar to how refracted light would
behave in the real world.
Detail
Uses a secondary albedo and normal map to achieve detailed textures, allowing you to combine them in interesting ways.
UV1 and UV2
Lets you change the scale, offset, and triplanar properties of the two UV channels supported byGodot.
Proximity and
Distance Fade
Adds effects that change the transparency of objects based on their proximity to other objects or the distance from the viewer.
Can be used for interesting effects, but should be used with care because of the added transparency.
Shader Basics
Shaders are programs that run directly in the GPU. They change the appearance of items on the screen and dictate how they should be drawn.
Internally, every material inGodot is a shader, but this is abstracted away from you for the sake of simplicity and flexibility. Still, Godot gives you
the ability to create custom shaders that complement or replace the regular material.
NOTE
Shader Language
If you’re familiar with the graphics pipeline or with other engines, you might be used to writing shader code inGLSL or HLSL (the shader
languages for OpenGL and DirectX, respectively). Godot does not allow you to write the code directly for the GPU.
Instead, it provides its own shading language very similar to GLSL by letting you write simple shaders without having to worry about the entire
pipeline. This has the added benefit of letting you see the shader changes in real-time in the editor and detect errors as you type.
Shader Material
The first step to take when you want to write shaders is to create a new
ShaderMaterial resource and apply it to the Material property of
the node. This can be done for 3D and 2D objects alike. Then you’ll need to set the Shader property to a new
Shader resource, which will
show the editor for your code.
Shader Language
Since the language is like GLSL, it follows the same conventions, which are akin to C++ too. The code is case-sensitive, and each statement
needs to end with a semicolon (;). Variables are declared by stating the type followed by the variable name (see LIsting 15.1). Similarly,
functions are declared using the return type followed by the function name, then all the need arguments are placed between parentheses. The
function body is delimited by curly braces ({ }).
The first line of your shader code must specify the shader type. Three possible values are available: spatial (for 3D objects),
canvas_item (for 2D and Control items), and particles (for the particle system). After that, you can optionally specify the render modes.
There are three phases of the shading process, which can be accessed by using specially named functions. The Vertex processor alters each
vertex in the object. The Fragment function runs for every pixel before the output. Finally, the Light function affects how the light is applied to the
object. For particle shaders, only the Vertex function is used.
LISTING15.1 Shader Structure
Click here to view code image
shader_type spatial;
render_mode cull_disabled, diffuse_toon;
void vertex() {
// Vertex Processing
VERTEX.x += sin(TIME);
VERTEX.y += cos(TIME);
}
void fragment() {
// Fragment processing
ALBEDO.r = 1.0;
}
void light() {
// Light processing
DIFFUSE_LIGHT = ALBEDO ATTENUATION;
}
111111111
22222222TIP
Uniforms
Uniforms are used to pass values from the outside world into the shader code. These are variables declared on the top level of the code, and
their values are available in all the shader processing functions.
Once a Uniform is declared, its value can be edited in Inspector on the
ShaderMaterial resource properties. It can also be set via code
using the set_shader_param() method.
Vertex Processing
The first step in the shader process is vertex shading, which handles both the position and the vertex in the geometry. For instance, you can
create waves in an ocean by changing the position of vertices over time.
TRY IT YOURSELF
Simple Vertex Shader
In this simple exercise, we will make a very basic vertex shader to manipulate the geometry of a primitive mesh.
1. Create a new scene in the editor.
2. Add a
Spatial node as the root.
3. Add a
MeshInstance node. Set the Mesh property to a new
SphereMesh.
4. In Inspector, set the Material property of the
MeshInstance to a new
ShaderMaterial.
5. Create a new
Shader for the material’s shader property.
6. The shader editor will show up. Paste the following code there:
Click here to view code image
shader_type spatial;
render_mode cull_disabled;
void vertex() {
VERTEX.z = sin(TIME);
}
7. Observe the mesh change in the editor over time. This shader simply multiplies the Z-position of each vertex by the sine of the
TIME variable, which is generated byGodot. Since the sine will always return a value between −1 and 1, it will collapse the
sphere into a flat surface then revert its direction, repeating over time. Hence, the cull_disabled mode is enabled, because
otherwise the sphere will look different when the faces are in the opposite direction (you can try to remove the render mode
definition to see how it looks).
Vertex shaders are useful in altering the geometry of objects. You can use it to create motion effects and deformation. Note that if an object is
intended to interact with other objects via the physics engine, changing its geometry will do nothing to its physical shape. Shaders are only
useful for visual effects.
NOTE
Geometry Shaders
Godot 3 supports only the OpenGL ES 3.0 specification, which does not include modern geometry shaders. While the modern geometry
shader is more appropriate for changing the geometry of meshes, it’s not supported by low-end hardware, especially on mobile devices.
Godot values better flexibility for all types of hardware over focusing on more powerful machines.
Fragment Shader
The next step of the shader process is Fragment processing. This is called by every pixel in the render, and can be used to alter how the pixels
are shown.
This type of shader is used to set the final color of the object, which can be a calculated color result or part of a texture to be applied over the
geometry. This can also be used to move the texture over time, making the detail of an object change (Figure 15.5).
FIGURE 15.5
A simple fragment shader that replaces the Albedo with the Normal vector. This can also be used to debug geometry or other material
properties.
Light Shader
The final step in this chain is the Light processor. Like Fragment processing, this is called for every pixel but is also called per light in the
111111111
22222222scene. If there are no lights, it will never be called. This processing is completely optional, and does not directly affect performance if set, so
there’s no extra cost for using Light shaders.
This can be used to change how light interacts with the material. You can change how the final lighting looks by writing to the diffuse_light
variable. It’s possible to completely ignore the light and act as an unshaded material. It’s also possible to change the specular reflection by
writing to the specular_light variable.
TIP
Converting SpatialMaterial to ShaderMaterial
Godot offers an interesting option to convert regular
SpatialMaterial into shader code. This way, you can see basically how the material
behaves and tweak usage of the parameters.
To do this, click on the little down arrow beside the Material property in the inspector (or right-click it) and select the
Convert to
ShaderMaterial option. You cannot convert it back, so be careful with this option.
Summary
In this hour, you learned about materials inGodot. You saw how to make the simple materials for 2D objects, then you learned about the
different options for 3D materials. Finally, you saw the basic concepts for writing your own custom shaders.
Q&A
Q. Can I set multiple materials to a mesh?
A. If the imported geometry has multiple material slots, you can set each one individually in Inspector.
Q. Why does Godot not use GLSL directly?
A. Godot uses its own shading language for usability and portability purposes. It’s much easier to write a shader inGodot, because you don’t
need to deal directly with attributes or color buffers (among other things), as the engine already deals with it. This also allows the editor to
have code completion, error checking, and real-time visualization. It is also possible to use the same shader in different rendering
backends, such as DirectX and Vulkan, if they are eventually supported.
Workshop
Try to answer the following questions to better grasp the contents of thi
s
hour.
Quiz
1. How can you add custom material to an object?
2. Where can you set the main texture of a 3D object?
3. True or False: You can’t pass values from the script to a shader.
4. True or False: You can convert a
SpatialMaterial to a
ShaderMaterial.
Answers
1. By setting its Material property in Inspector.
2. In the Albedo property of the material.
3. False. You can add a Uniform variable in the shader and set it via script with the set_shader_param() method.
4. True. Godot has a built-in function to convert a
SpatialMaterial to a
ShaderMaterial.
Exercises
Follow this exercise to gain some insight into materials and shaders.
1. Create a new scene and add a
Spatial node as the root. Save the scene.
2. Add a
MeshInstance node.
3. Set the Mesh property to a new
SphereMesh.
4. Add a
DirectionalLight to the scene. Rotate it to change the default angle, making the light come from above and move down.
5. Set the Material property of the node to a new
SpatialMaterial.
6. Change the Albedo color to something other than the default white.
7. Set both the Metallic and Roughness properties to 0.5.
8. Change the Diffuse and Specular modes to watch the difference between them.
9. Experiment with other parameters and properties.
111111111
2222222210. Convert the material to a
ShaderMaterial.
11. Look at the code.
12. Try changing some of the operations, and see how they affect the object.
13. Try to use the TIME parameter to change some properties over time.
111111111
22222222