Creating Materials from Scratch

Building a custom material is complicated, but the Complex Material template doesn't fit every use case.

This is an advanced workflow. Extending the Complex Material Sample is preferred.

1. Working with Material Definitions

For a straight-forward example, download and explore the BasicMaterial sample.

A material definition, or an instance of one, is an asset that represents a texture layer on the terrain. It defines a set of parameters to be used, generally float data or textures, and a material that reads the parameters for the asset's preview. These parameters will then be sent through to the material being used on the terrain as needed.

Material Definition Instances use a Material Definition as template. These are similar to material instances in Unreal Engine. They inherit from their parent, and can override the values assigned to the parameters. Each customized MDI can then be used as a layer on the terrain.

Material definitions and instances are similar to Multi-Index Layers from Voxel Plugin 1.2.

A material definition's preview material can be configured in the Details panel when no parameters are selected. This material will only be used for previewing the definition and its instances in editor viewports. It should usually be the same material as the terrain has assigned.

1.1 Configuring Parameters

Float-based parameter types are straight-forward to use; just click the plus button, set the name and type, and then set a default value. No other configuration is needed.

Material and material definitions like the one shown throughout this article are available for download through the Voxel Content menu.

Texture parameters have a few extra configuration settings that can be important to consider, which can be found in the Value dropdown underneath the Default Value. Most Material Definitions will have quite a few texture parameters configured, and these settings will vary across them.

1.1.1 Texture and Mip Size

Texture Size and Last Mip Texture Size affect the VRAM (GPU memory) overhead of the texture in the final material.

We recommend keeping texture size as low as possible to minimize VRAM use (A single 4k texture takes up as much space as sixteen 1k textures). If more detail is needed, consider adding it with another texture overlay in the material graph.

The Last Mip Texture Size value should generally be left at its default, unless you understand the impacts of MipMaps on a technical level.

1.1.2 Texture Compression Settings

The Compression type is the most important of these three values. If it is configured incorrectly, instances will throw errors when assigning textures, and your materials might not compile. Currently, the following compression types are available:

  • DXT1

    • Colour textures without alpha channel.

  • DXT5

    • Colour textures with alpha channel. Twice as much memory use.

  • BC5

    • Used exclusively for normal maps.

The compression type picked here has to match whichever compression method is selected in a texture asset's texture settings. If there is a mismatch, the plugin will throw errors.

1.1.3 Using Alpha Channels

Because DXT5 (color with alpha) uses twice as much VRAM as DXT1 (color without alpha), DXT1 should be used for color textures wherever possible. Only set the compression to DXT5 if the alpha channel is really necessary. Doing so doubles the VRAM usage of the entire array, not just for the textures that have an alpha.

Attempting to assign a texture asset with an alpha channel when DXT1 compression is selected on the material definition will cause errors. When this happens, just tick the "Compress Without Alpha" tickbox in the asset's compression settings and save it - this will switch the texture to DXT1.

Color textures without alpha can be assigned without issues when the texture parameter is set to DXT5.

2. Configuring a Custom Material

With a material definition configured as above, instances can be created and configured, and they can be assigned to surfaces in a Voxel Graph. A material definition by itself won't make a material appear on the terrain though; for this, an accompanying master material needs to be created.

2.1 Reading Data from Material Definitions

Data from a Material Definition and its instances can be accessed in materials using a handful of helper nodes. To do so, a combination of a Voxel Parameter node and a Get Voxel ... Parameter node is used.

When working with Material Functions, Voxel Parameter nodes can be passed as input pin. The input type needs to be set to Function Input TextureExternal.

The Voxel Parameter node can be configured in the details panel when selected; it takes a reference to a Material Definition, and will then show a dropdown with all the parameters from that Material Definition. The output from this node can then be plugged into the Parameter pin on a Get Voxel ... Parameter. Use the appropriate Get node for the type the parameter has in the Material Definition. For example, if a parameter is a Linear Color, use the Get Voxel Color Parameter node.

2.2 How Layers Blend

The Get Voxel ... Parameter nodes can be used without plugging anything into the MaterialId pin. When used like this, they will do a lerp (linear blend) between the top three layers' value for this parameter.

If a standard linear blend isn't enough, the blend can be done manually by using the MaterialId pin. The relevant MaterialIds and their weights can be retrieved with the Get Voxel Material ID node. In this context, the Layer0/Layer1/Layer2 pins are the indexes of the three highest-weighted layers, and the LerpAlphas are the relevant weights between them.

Last updated