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