Working with UV Channels

A UV Channel is a set of data within a Static Mesh that maps each of the mesh's vertices to coordinates in 2D space. These mappings define how 2D texture maps get wrapped around the 3D geometry when the mesh is rendered.

You typically create and manage your UV mappings in a dedicated modeling tool — the same tool you use to create the geometry of your Static Mesh. However, the Unreal Editor does offer a few possibilities for working with the UV Channels of your models, outlined below on this page.

UV Channels have two main purposes in the Unreal Engine:

  • Texture coordinates in Materials - When you create a Material that samples a texture map and applies it to the surface of a Static Mesh, you can use a Texture Coordinate (or Texcoord) node to specify a UV Channel. The Material uses the mapping between 2D coordinates and 3D vertex positions contained in the selected UV Channel to determine what areas of the texture should be used to shade what triangles in the 3D model.

    For example, UV Channel 0 in this simple plane Static Mesh (shown at the top right of this image) shows the simplest way to map the two triangles of the mesh (A and B) into texture space. When you use this UV Channel (set by the Coordinate Index property of the TexCoord node), the Material applies the full width and height of a texture to the plane.
    texture-mapping-1-1.png
    On the other hand, the image below shows UV Channel 1, which rotates and skews the mapping between the triangles and the UV texture space. When the same image texture is applied to the Static Mesh, it changes what parts of the texture get applied to what parts of the Static Mesh.
    texture-mapping-2.png
    Triangles in the UV mapping can overlap. An overlap just means that the same part of the texture gets applied to multiple parts of the 3D Static Mesh geometry.

    The U in "UV channel" refers to the horizontal axis of the texture; the V refers to the vertical axis. Texture coordinates are usually kept between 0 and 1, where (0,0) represents the bottom left of the texture, and (1,1) represents the top right. However, this is not always true. By default, when a U or V value exceeds 1 or is below 0, the Material will "wrap" around to the other side of the texture. For example, a V value of 1.25 is usually treated as 0.25. However, you can choose to clamp these values instead in your Material, limiting them to a minimum value of 0 and a maximum value of 1.

  • Lightmaps - UV channels are also used to store and apply lightmaps. A lightmap is a special kind of texture that stores pre-computed lighting information for Static Meshes. When you have lights in your Level that have their Mobility setting set to Stationary or Static, and you build the lighting for your Level, the Lightmass tool saves the indirect lighting (and direct lighting for Static lights) to lightmap textures, using a UV channel to determine the mapping between the 3D geometry of the Static Mesh and the 2D texture space.

    UV channels used for lightmaps have to follow some special rules. Because every part of an object usually receives different amounts of lighting, no two triangles in the mesh can overlap in the 2D texture space. Each triangle must cover its own area in the texture. In addition, all UV coordinate values must fall between 0 and 1. Lightmap textures can not "wrap around" the same way as regular texture mappings.
    For these reasons, lightmap UVs are typically generated — or packed — from simpler UV mappings.

    For example, this pillar's texture mapping UV channel maps the geometry of each of the four sides to the same overlapping areas of the texture. When you use this UV channel to apply a texture to the geometry, each of the sides uses the same parts of the texture.
    texture-mapping-pillar.png
    However, in the object's lightmap UV, each side needs to cover its own unique area of 2D space:
    texture-mapping-pillar-packed.png
    For more information on lightmap UVs and how to generate them, see Unwrapping UVs for Lightmaps and Generating Lightmap UVs.

Each Static Mesh in the Unreal Engine can have up to seven different UV Channels, so that you can set up multiple different ways of wrapping textures for different Materials (or for different texture sampling nodes within a single Material).

UV Channels in the Static Mesh Editor

In the Static Mesh Editor UI, you can list, visualize, and remove UV Channels.

Listing UV Channels

When you have any Static Mesh Asset open in the Static Mesh Editor, you can use the UV button in the Toolbar to list all the UV Channels in use by the current Static Mesh.

List UV Channels

Visualizing a UV Channel

Select any UV Channel in the list to visualize the mapping of the mesh's triangles into 2D texture space as an overlay in the Viewport:

Visualize UV Channels

Select None at the top of the list to hide the UV overlay.

Removing a UV Channel

When you have a channel selected in the list, you can remove it. Each UV Channel stores texture coordinates for each vertex as part of the Static Mesh, so you may be able to save some runtime memory by removing any mappings you don't use.

Remove selected UV channel

All other UV Channels that were present in the list after the deleted channel are moved up one spot, to fill the empty space left by the removed channel.

You can't delete a UV Channel if your Static Mesh Asset is set up to generate lightmap UVs, and the UV Channel you have selected is already in use as the source or destination channel for lightmap UVs. Either deactivate the Build Settings > Generate Lightmap UVs option, or change the Build Settings > Source Lightmap Index and Build Settings > Destination Lightmap Index settings to point to different UV Channels.

Choose your language

Blueprints

Python

UV Channels in Editor Scripting

You can also work with UV Channels in Blueprint and Python scripts that you run in the Unreal Editor. You can do everything that you can do in the Static Mesh Editor, plus you can add new channels and generate new UV mappings.

Prerequisite: If you haven't already done so, you'll need to install the Editor Scripting Utilities Plugin. For details, see Scripting and Automating the Editor.

You'll find the nodes you'll need to manage UV Channels under the Editor Scripting > Static Mesh category.

To use these nodes, your Blueprint class must be derived from an Editor-only class, such as the PlacedEditorUtilityBase class. For details, see Scripting the Editor using Blueprints.

All of these functions work with a Static Mesh Asset, which you'll typically need to load by calling the Editor Scripting > Asset Library > Load Asset node.

Modifying UV Channels modifies the Asset. Assuming you want to keep the changes you make, you'll also need to use a node like Editor Scripting > Asset Library > Save Asset or Save Loaded Asset afterward. See the examples below.

Listing UV channels

You can use the Get Num UV Channels node to find out how many UV Channels currently exist in a given Static Mesh Asset.

For example:

Removing a UV Channel

Each UV Channel stores texture coordinates for each vertex as part of the Static Mesh, so you may be able to save some runtime memory by removing any mappings you don't use.

To remove a UV Channel, call the Remove UV Channel node. Pass it the Static Mesh Asset and the index of the UV Channel that you want to remove.

For example:

All other UV Channels that were already present in the list after the specified index are moved up one spot, to fill the empty space left by the removed entry.

You can't delete a UV Channel if your Static Mesh Asset is set up to generate lightmap UVs, and the UV Channel you have selected is already in use as the source or destination channel for lightmap UVs. Either deactivate the Build Settings > Generate Lightmap UVs option, or change the Build Settings > Source Lightmap Index and Build Settings > Destination Lightmap Index settings to point to different UV Channels.

Adding a New UV Channel

You can add a new UV Channel to your Static Mesh Asset by calling either of the following nodes:

  • Add UV Channel - Adds the new channel at the end of the existing list of channels.
  • Insert UV Channel - Adds the new channel at the index you specify, moving each other UV Channel down one number in the list. Note that the array of UV Channels can't be sparse: you can only insert a new channel at a position in the list that is next to another existing channel. For example, if there are three UV Channels in the list (indices 0, 1, and 2), you can add a new one with index 3, but not with index 4.

The new mapping is empty. You'll want to fill it somehow before you use it — either by projecting the mesh geometry (see below) or by using it as the destination for lightmap generation.

Projecting Mesh Geometry into a UV Channel

You can create new UV mappings by projecting the triangles in the Static Mesh onto a 2D plane or a simple 3D volume.

This is currently only exposed in the Unreal Editor scripting APIs, not in the UI of the Static Mesh Editor. However, the process and the settings required by the API are easier to understand if you are already familiar with visual tools for mesh projection, such as those in 3ds Max. See the UVW Map Modifier in the 3ds Max Help for background.

Each of the nodes described below saves the UV mapping it creates into a UV Channel that you specify. This UV Channel must already exist; if it doesn't exist, the function will not create it.

Planar Projection

Use the Generate Planar UV Channel node to project your Static Mesh geometry onto a plane. Use this kind of projection if only one side of your Static Mesh needs to have textures wrapped around it.

For example:

Cylindrical Projection

Use the Generate Cylindrical UV Channel node to project your Static Mesh geometry onto the sides, top and bottom of a cylinder.

For example:

Box Projection

Use the Generate Box UV Channel node to project your Static Mesh geometry onto the faces of a cube.

For example, the following script creates a box the same approximate size as the Static Mesh, then creates a new UV mapping by projecting the geometry of the Static Mesh onto the sides of that box:

You'll find the LOD management functions in the unreal.EditorStaticMeshLibrary class.

All of these functions work with a Static Mesh Asset, which you'll typically need to load by calling a function like unreal.EditorAssetLibrary.load_asset().

Modifying UV Channels modifies the Asset. Assuming you want to keep the changes you make, you'll also need to use a function like unreal.EditorAssetLibrary.save_asset() or unreal.EditorAssetLibrary.save_loaded_asset() afterward.

Listing UV channels

You can use the unreal.EditorStaticMeshLibrary.get_num_uv_channels() function to find out how many UV Channels currently exist in a given Static Mesh Asset.

For example:

import unreal
asset_name = '/Game/Path/MyStaticMeshAsset'
# Load the Static Mesh Asset. loaded_asset = unreal.EditorAssetLibrary.load_asset(asset_name)
# Get the number of UV channels saved in the Asset. num_uv_channels = unreal.EditorStaticMeshLibrary.get_num_uv_channels(asset_name) print("Number of UV channels: " + str(num_uv_channels))

Removing a UV Channel

Each UV Channel stores texture coordinates for each vertex as part of the Static Mesh, so you may be able to save some runtime memory by removing any mappings you don't use.

To remove a UV Channel, call the unreal.EditorStaticMeshLibrary.remove_uv_channel() function. Pass it the Static Mesh Asset and the index of the UV Channel that you want to remove.

For example:

import unreal
asset_name = '/Game/Path/MyStaticMeshAsset'
# Load the Static Mesh Asset. loaded_asset = unreal.EditorAssetLibrary.load_asset(asset_name)
# Get the number of UV channels saved in the Asset. num_uv_channels = unreal.EditorStaticMeshLibrary.get_num_uv_channels(asset_name)
# Remove the last one in the list. channel_to_remove = num_uv_channels - 1 unreal.EditorStaticMeshLibrary.remove_uv_channel(asset_name, channel_to_remove)
# Save the modified Asset. unreal.EditorAssetLibrary.save_asset(asset_name)

All other UV Channels that were already present in the list after the specified index are moved up one spot, to fill the empty space left by the removed entry.

You can't delete a UV Channel if your Static Mesh Asset is set up to generate lightmap UVs, and the UV Channel you have selected is already in use as the source or destination channel for lightmap UVs. Either deactivate the Build Settings > Generate Lightmap UVs option, or change the Build Settings > Source Lightmap Index and Build Settings > Destination Lightmap Index settings to point to different UV Channels.

Adding a New UV Channel

You can add a new UV Channel to your Static Mesh Asset by calling either of the following functions:

  • unreal.EditorStaticMeshLibrary.add_uv_channel() - Adds the new channel at the end of the existing list of channels.
  • unreal.EditorStaticMeshLibrary.insert_uv_channel() - Adds the new channel at the index you specify, moving each other UV Channel down one number in the list. Note that the array of UV Channels can't be sparse: you can only insert a new channel at a position in the list that is next to another existing channel. For example, if there are three UV Channels in the list (indices 0, 1, and 2), you can add a new one with index 3, but not with index 4.

For example:

import unreal
asset_name = '/Game/Path/MyStaticMeshAsset'
# Load the Static Mesh Asset. loaded_asset = unreal.EditorAssetLibrary.load_asset(asset_name)
# Get the number of UV channels saved in the Asset. num_uv_channels = unreal.EditorStaticMeshLibrary.get_num_uv_channels(asset_name) print("Number of UV channels before: " + str(num_uv_channels))
# Add one to the end of the list. unreal.EditorStaticMeshLibrary.add_uv_channel(asset_name)
# Add one at the beginning of the list. unreal.EditorStaticMeshLibrary.insert_uv_channel(asset_name, 0)
# Get the new number of UV channels saved in the Asset. num_uv_channels = unreal.EditorStaticMeshLibrary.get_num_uv_channels(asset_name) print("Number of UV channels after: " + str(num_uv_channels))
# Save the modified Asset. unreal.EditorAssetLibrary.save_asset(asset_name)

The new mapping is empty. You'll want to fill it somehow before you use it — either by projecting the mesh geometry (see below) or by using it as the destination for lightmap generation.

Projecting Mesh Geometry into a UV Channel

You can create new UV mappings by projecting the triangles in the Static Mesh onto a 2D plane or a simple 3D volume.

This is currently only exposed in the Unreal Editor scripting APIs, not in the UI of the Static Mesh Editor. However, the process and the settings required by the API are easier to understand if you are already familiar with visual tools for mesh projection, such as those in 3ds Max. See the UVW Map Modifier in the 3ds Max Help for background.

Each of the functions described below saves the UV mapping it creates into a UV Channel that you specify. This UV Channel must already exist; if it doesn't exist, the function will not create it.

Planar Projection

Use the unreal.EditorStaticMeshLibrary.generate_planar_uv_channel() function to project your Static Mesh geometry onto a plane. Use this kind of projection if only one side of your Static Mesh needs to have textures wrapped around it.

For example:

import unreal
asset_name = '/Game/Path/MyStaticMeshAsset'
# Load the Static Mesh Asset. loaded_asset = unreal.EditorAssetLibrary.load_asset(asset_name)
# Specify the LOD to project. lod_index = 0
# Add a new UV channel for our projection. num_uv_channels = unreal.EditorStaticMeshLibrary.get_num_uv_channels(asset_name) unreal.EditorStaticMeshLibrary.add_uv_channel(asset_name) channel_index = num_uv_channels
# Set up the projection plane, or "gizmo". bbox = loaded_asset.get_bounding_box() gizmo_pos = ((bbox.min + bbox.max) * 0.5) # Find the center of the object's bounding box.
# Set the rotation angles in degrees. pitch = 0 # Around the X axis yaw = 0 # Around the Y axis roll = 0 # Around the Z axis gizmo_orientation = unreal.Rotator(pitch, yaw, roll)
# Increase or decrease values to make the projection larger or smaller. tiling = unreal.Vector2D(1, 1)
# Project the Static Mesh geometry into the UV Channel. unreal.EditorStaticMeshLibrary.generate_planar_uv_channel(loaded_asset, lod_index, channel_index, gizmo_pos, gizmo_orientation, tiling)
# Save the modified Asset. unreal.EditorAssetLibrary.save_asset(asset_name)

Cylindrical Projection

Use the unreal.EditorStaticMeshLibrary.generate_cylindrical_uv_channel() function to project your Static Mesh geometry onto the sides, top and bottom of a cylinder.

For example:

import unreal
asset_name = '/Game/Path/MyStaticMeshAsset'
# Load the Static Mesh Asset. loaded_asset = unreal.EditorAssetLibrary.load_asset(asset_name)
# Specify the LOD to project. lod_index = 0
# Add a new UV channel for our projection. num_uv_channels = unreal.EditorStaticMeshLibrary.get_num_uv_channels(asset_name) unreal.EditorStaticMeshLibrary.add_uv_channel(asset_name) channel_index = num_uv_channels
# Set up the projection cylinder, or "gizmo". bbox = loaded_asset.get_bounding_box() gizmo_pos = ((bbox.min + bbox.max) * 0.5) # Find the center of the object's bounding box.
# Set the rotation angles in degrees. pitch = 0 # Around the X axis yaw = 0 # Around the Y axis roll = 0 # Around the Z axis gizmo_orientation = unreal.Rotator(pitch, yaw, roll)
# Increase or decrease values to make the projection larger or smaller. tiling = unreal.Vector2D(1, 1)
# Project the Static Mesh geometry into the UV Channel. unreal.EditorStaticMeshLibrary.generate_cylindrical_uv_channel(teapot, lod_index, channel_index, gizmo_pos, gizmo_orientation, tiling)
# Save the modified Asset. unreal.EditorAssetLibrary.save_asset(asset_name)

Box Projection

Use the unreal.EditorStaticMeshLibrary.generate_box_uv_channel() function to project your Static Mesh geometry onto the faces of a cube.

For example, the following script creates a box the same approximate size as the Static Mesh, then creates a new UV mapping by projecting the geometry of the Static Mesh onto the sides of that box:

import unreal
asset_name = '/Game/Path/MyStaticMeshAsset'
# Load the Static Mesh Asset. loaded_asset = unreal.EditorAssetLibrary.load_asset(asset_name)
# Specify the LOD to project. lod_index = 0
# Add a new UV channel for our projection. num_uv_channels = unreal.EditorStaticMeshLibrary.get_num_uv_channels(asset_name) unreal.EditorStaticMeshLibrary.add_uv_channel(asset_name) channel_index = num_uv_channels
# Set up the projection volume, or "gizmo". bbox = loaded_asset.get_bounding_box() gizmo_pos = ((bbox.min + bbox.max) * 0.5) # Find the center of the object's bounding box.
# Set the rotation angles in degrees. pitch = 0 # Around the X axis yaw = 0 # Around the Y axis roll = 0 # Around the Z axis gizmo_orientation = unreal.Rotator(pitch, yaw, roll)
# Get the size of the box. gizmo_size = bbox.max - bbox.min
# Project the Static Mesh geometry into the UV Channel. unreal.EditorStaticMeshLibrary.generate_box_uv_channel(box, channel_index, lod_index, gizmo_pos, gizmo_orientation, gizmo_size)
# Save the modified Asset. unreal.EditorAssetLibrary.save_asset(asset_name)