diff --git a/tutorials/3d/img/decals_blob_shadow.webp b/tutorials/3d/img/decals_blob_shadow.webp new file mode 100644 index 00000000000..442fb7f07ef Binary files /dev/null and b/tutorials/3d/img/decals_blob_shadow.webp differ diff --git a/tutorials/3d/img/decals_dirt.webp b/tutorials/3d/img/decals_dirt.webp new file mode 100755 index 00000000000..c46252c9c32 Binary files /dev/null and b/tutorials/3d/img/decals_dirt.webp differ diff --git a/tutorials/3d/index.rst b/tutorials/3d/index.rst index 3fa3885087f..3fda2b75fa7 100644 --- a/tutorials/3d/index.rst +++ b/tutorials/3d/index.rst @@ -20,6 +20,7 @@ Rendering 3d_rendering_limitations standard_material_3d lights_and_shadows + using_decals physical_light_and_camera_units high_dynamic_range global_illumination/index diff --git a/tutorials/3d/using_decals.rst b/tutorials/3d/using_decals.rst new file mode 100644 index 00000000000..869172e9db2 --- /dev/null +++ b/tutorials/3d/using_decals.rst @@ -0,0 +1,234 @@ +.. _doc_using_decals: + +Using decals +============ + +.. note:: + + Decals are only supported in the Clustered Forward and Forward Mobile + rendering backends, not the Compatibility backend. + + If using the Compatibility backend, consider using Sprite3D as an alternative + for projecting decals onto (mostly) flat surfaces. + +Decals are projected textures that apply on opaque or transparent surfaces in +3D. This projection happens in real-time and doesn't rely on mesh generation. +This allows you to move decals every frame with only a small performance impact, +even when applied on complex meshes. + +While decals cannot add actual geometry detail onto the projected surface, +decals can still make use of physically-based rendering to provide similar +properties to full-blown :abbr:`PBR (Physically-Based Rendering)` materials. + +On this page, you'll learn: + +- How to set up decals in the 3D editor. +- How to create decals during gameplay in a 3D scene (such as bullet impacts). +- How to balance decal configuration between performance and quality. + +.. seealso:: + + The Godot demo projects repository contains a + `3D decals demo `__. + + If you're looking to write arbitrary 3D text on top of a surface, use + :ref:`doc_3d_text` placed close to a surface instead of a Decal node. + +Use cases +--------- + +Static decoration +^^^^^^^^^^^^^^^^^ + +Sometimes, the fastest way to add texture detail to a scene is to use decals. +This is especially the case for organic detail, such as patches of dirt or sand +scattered on a large surface. Decals can help break up texture repetition in +scenes and make patterns look more natural. On a smaller scale, decals can also +be used to create detail variations for objects. For example, decals can be used +to add nuts and bolts on top of hard-surface geometry. + +Since decals can inject their own :abbr:`PBR (Physically-Based Rendering)` +properties on top of the projected surfaces, they can also be used to create +footprints or wet puddles. + +.. figure:: img/decals_dirt.webp + :align: center + :alt: Dirt added on top of level geometry using decals + + Dirt added on top of level geometry using decals + +Dynamic gameplay elements +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Decals can represent temporary or persistent gameplay effects such as bullet +impacts and explosion scorches. + +Using an AnimationPlayer node or a script, decals can be made to fade over time +(and then be removed using ``queue_free()``) to improve performance. + +Blob shadows +^^^^^^^^^^^^ + +Blob shadows are frequently used in mobile projects (or to follow a retro art +style), as real-time lighting tends to be too expensive on low-end mobile +devices. However, when relying on baked lightmaps with fully baked lights, +dynamic objects will not cast *any* shadow from those lights. This makes dynamic +objects in lightmapped scenes look flat in comparison to real-time lighting, +with dynamic objects almost looking like they're floating. + +Thanks to blob shadows, dynamic objects can still cast an approximative shadow. +Not only this helps with depth perception in the scene, but this can also be a +gameplay element, especially in 3D platformers. The blob shadow's length can be +extended to let the player know where they will land if they fall straight down. + +Even with real-time lighting, blob shadows can still be useful as a form of +ambient occlusion for situations where SSAO is too expensive or too unstable due +to its screen-space nature. For example, vehicles' underside shadows are +well-represented using blob shadows. + +.. figure:: img/decals_blob_shadow.webp + :align: center + :alt: Blob shadow under object comparison + + Blob shadow under object comparison + +Quick start guide +----------------- + +Creating decals in the editor +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +1. Create a Decal node in the 3D editor. +2. In the inspector, expand the **Textures** section and load a texture in + **Textures > Albedo**. +3. Move the Decal node towards an object, then rotate it so the decal is visible + (and in the right orientation). If the decal appears mirrored, try to rotate + it by 180 degrees. You can double-check whether it's in the right orientation + by increasing **Parameters > Normal Fade** to 0.5. This will prevent the Decal + from being projected on surfaces that are not facing the decal. +4. If your decal is meant to affect static objects only, configure it to prevent + affecting dynamic objects (or vice versa). To do so, change the decal's + **Cull Mask** property to exclude certain layers. After doing this, modify + your dynamic objects' MeshInstance3D nodes to change their visibility layers. + For instance, you can move them from layer 1 to layer 2, then disable layer 2 + in the decal's **Cull Mask** property. + +Decal node properties +--------------------- + +- **Extents:** The size of the decal. The Y axis determines the length of the + decal's projection. Keep the projection length as short as possible to improve + culling opportunities, therefore improving performance. + +Textures +^^^^^^^^ + +- **Albedo:** The albedo (diffuse/color) map to use for the decal. In + most situations, this is the texture you want to set first. If using a normal + or ORM map, an albedo map *must* be set to provide an alpha channel. This + alpha channel will be used as a mask to determine how much the normal/ORM maps + will affect the underlying surface. +- **Normal:** The normal map to use for the decal. This can be used + to increase perceived detail on the decal by modifying how light reacts to it. + The impact of this texture is multiplied by the albedo texture's alpha channel + (but not **Albedo Mix**). +- **ORM:** The Occlusion/Roughness/Metallic map to use for the decal. + This is an optimized format for storing PBR material maps. Ambient Occlusion + map is stored in the red channel, roughness map in the green channel, metallic + map in the blue channel. The impact of this texture is multiplied by the + albedo texture's alpha channel (but not **Albedo Mix**). +- **Emission:** The emission texture to use for the decal. Unlike + **Albedo**, this texture will appear to glow in the dark. + +Parameters +^^^^^^^^^^ + +- **Emission Energy:** The brightness of the emission texture. +- **Modulate:** Multiplies the color of the albedo and emission textures. Use + this to tint decals (e.g. for paint decals, or to increase variation by + randomizing each decal's modulation). +- **Albedo Mix:** The opacity of the albedo texture. Unlike using an albedo + texture with a more transparent alpha channel, decreasing this value below + ``1.0`` does *not* reduce the impact of the normal/ORM texture on the + underlying surface. Set this to ``0.0`` when creating normal/ORM-only decals + such as footsteps or wet puddles. +- **Normal Fade:** Fades the Decal if the angle between the Decal's + :abbr:`AABB (Axis-Aligned Bounding Box)` and the target surface becomes too large. + A value of ``0.0`` projects the decal regardless of angle, while a value of ``0.999`` + limits the decal to surfaces that are nearly perpendicular. Setting **Normal + Fade** to a value greater than ``0.0`` has a small performance cost due to the + added normal angle computations. + +Vertical Fade +^^^^^^^^^^^^^ + +- **Upper Fade:** The curve over which the decal will fade as the surface gets + further from the center of the :abbr:`AABB (Axis-Aligned Bounding Box)` + (towards the decal's projection angle). Only positive values are valid. +- **Lower Fade:** The curve over which the decal will fade as the surface gets + further from the center of the :abbr:`AABB (Axis-Aligned Bounding Box)` (away + from the decal's projection angle). Only positive values are valid. + +Distance Fade +^^^^^^^^^^^^^ + +- **Enabled:** Controls whether distance fade (a form of :abbr:`LOD (Level of Detail)`) + is enabled. The decal will fade out over **Begin + Length**, after which it + will be culled and not sent to the shader at all. Use this to reduce the number + of active decals in a scene and thus improve performance. +- **Begin:** The distance from the camera at which the decal begins to fade away + (in 3D units). +- **Length:** The distance over which the decal fades (in 3D units). The decal + becomes slowly more transparent over this distance and is completely invisible + at the end. Higher values result in a smoother fade-out transition, which is + more suited when the camera moves fast. + +Cull Mask +^^^^^^^^^ + +- **Cull Mask:** Specifies which VisualInstance3D layers this decal will project + on. By default, decals affect all layers. This is used so you can specify which + types of objects receive the decal and which do not. This is especially useful + so you can ensure that dynamic objects don't accidentally receive a Decal + intended for the terrain under them. + +Tweaking performance and quality +-------------------------------- + +Decal rendering performance is mostly determined by their screen coverage, but +also their number. In general, a few large decals that cover up most of the +screen will be more expensive to render than many small decals that are +scattered around. + +To improve rendering performance, you can enable the **Distance Fade** property +as described above. This will make distant decals fade out when they are far +away from the camera (and may have little to no impact on the final scene +rendering). Using node groups, you can also prevent non-essential decorative +decals from spawning based on user configuration. + +The way decals are rendered also has an impact on performance. The **Rendering > +Textures > Decals > Filter** advanced project setting lets you control how decal +textures should be filtered. **Nearest/Linear** does not use mipmaps. However, +decals will look grainy at a distance. **Nearest/Linear Mipmaps** will look +smoother at a distance, but decals will look blurry when viewed from oblique +angles. This can be resolved by using **Nearest/Linear Mipmaps Anisotropic**, +which provides the highest quality but is also slower to render. + +If your project has a pixel art style, consider setting the filter to one of the +**Nearest** values so that decals use nearest-neighbor filtering. Otherwise, +stick to **Linear**. + +Limitations +----------- + +Decals cannot affect material properties other than the ones listed above, +such as height (for parallax mapping). + +For performance reasons, decals use purely fixed rendering logic. This means +decals cannot use custom shaders. However, custom shaders on the projected +surfaces are able to read the information that is overridden by decals on top of +them, such as roughness and metallic. + +When using the Forward Mobile backend, only 8 decals can be applied on each +individual Mesh *resource*. If there are more decals affecting a single mesh, +not all of them will be rendered on the mesh.