UE4 - Pipeline

General

  • System Units
    • UE uses centimeter (1 UE unit = 1cm)

Naming Convention

Using a good naming convention is important to make the project more efficient to work with. For instance, if we have a good naming convention we can understand just by looking at the file name what the purpose of a texture is. It also helps when filtering the content browser, and make the project easier to understand by organizing the content in a logical way. It will also allow for the assets to be more easily processed with python. Here are some examples of how we could name textures:

  • SM_LargeRock_00 : Static Mesh for a large rock asset version 0
  • T_LargeRock_00_BC : Texture with Base Color channel for a large rock asset version 0
  • SKM_LargeRock_00 : SKeletal Mesh for a large rock asset version 0

Textures

Importing

  • You can drag and drop or use the import button in the content browser.
  • Unreal will detect if the imported texture is a normal map and apply appropriate settings.

Texture Groups

Texture groups is a way to organize textures in groups. We can then use this texture groups to non destructively change texture resolution by setting the lod bias to use a smaller size. This could be done to see if we can get better performance by reducing the size of certain groups.

Size

  • Textures should always be a power of two
    • 2, 4, 8, 16, 32…
  • Textures do not need to be square, just a power of 2:
    The reaseon that the textures needs to be square is because how they will be packed into memory and how they will be optimized using texture streaming and mipmapping.
    • 16x128, 2048x64, …

Compression

  • Change compression

    • We can change the compression for certain textures, for instance if we want to display a texture to be used as a ui element we might want to change it to UserInterface2D(RGBA) the texture will be much larger but also of much higher quality.
  • Disable SRGB

    • Normal maps and masks should have this turned off.
      (When importing a normal map the engine should do this automatically, but if it is missed we can do it manually here)

Alpha

There are 2 ways of using an alpha channel, embedded or separate.

  • Embedded
    • Cost 2 times more than a separate alpha.
      This is because the embedded alpha will come in as uncompressed.
  • Separate
    • Gives control of the size of the alpha texture independently of the base color texture.

Texture Packing

We can store multiple textures in one texture by packing it.

  • Texture Packing
    • Make sure that sRGB is disabled on the texture property.
      This is because we dont want the channels to be gamma corrected. Since we will use the separate channels as masks, possibly multiplied with a color, we dont want it to be gamma corrected.
    • Make sure that the Sampler Type is set to Masks on the material.

Formats

  • PNG - (Embedded Alpha support)
  • PSD - (Embedded Alpha support)
  • TGA - (Embedded Alpha support)
  • BMP
  • FLOAT
  • PCX
  • IPG
  • EXR
  • DDS - Cubemap Texture (32 Bits/Channel 8.8.8.8 ARGB 32 bpp, unsigned)
  • HDR - Cubemap Texture (LongLat Unwrap)
    • The only texture that do not need to comply with power of 2 when importing a hdr texture used for lighting.

Tips

If you get artifacts from the mipmaps (thin lines, chain link fences etc) you could try to change the Mip Gen Settings on the texture node. This will sharpen, blur etc the mips which might help with the artifacts.

Static Meshes

Lightmaps

  • UVs need to be in 0-1 space
  • Needs to be unique, i.e. no overlap
  • Needs to be stored in the second uv channel
  • You can set the light map resolution and the light map coordinate index inside the static mech editor under the tab static mesh settings.
  • You can also override the light map resolution in the main editor 3d view by selecting the static mesh and scrolling to lighting section.

Collision

  • Collision mesh
    • Can be created inside your DCC
      • If we want to create the collision mesh inside our DCC we first model it.
      • Then we need to name it **UCX_[full name of mesh]_Number**
      • for instance UCX_MyMesh_00
    • Or created inside Unreal Engine
      • Go into the static mesh editor
      • From the main toolbar menu you can use various functions found in the Collision menu to create a collision mesh
      • You can also use convex decomposition. Make sure that the convex decomposition window is open (Main Menu > Window > Convex Decomposition)
      • Then we can hit apply (if you do not get the collision mesh you want chnange the parameters and hit apply again)

Overdraw

Overdraw is when the engine needs to process a part of a mesh that will later not be used. Lets say we have a plane that we will assign a leaf texture to. To reduce overdraw it is better to use a bit more verts to more closely hug the outline of the leaves than to have large parts that will be invisible.

We can use the view mode shader complexity to view overdraw. View mode > Optimization View Modes > Shader Complexity Alt 8

View Mode Key
Lightmap Density Alt 0
Wireframe Alt 2
Unlit Alt 3
Lit Alt 4
Detail Lighting Alt 5
Lighting Only Alt 6
Light Complexity Alt 7
Shader Complexity Alt 8

LOD

  • Manually creating LODs
    • Houdini
  • Automatic LODs

Import

  • Importing GEO
    • Mesh
      • Skeletal Mesh : OFF Turn off for static mash, on for a skeletal mesh
      • Auto Generate Collision : ON If we want the editor to do that
      • Import Mesh LODs : ON
        If we have created LODs in our DCC
      • Generate Lightmap UVs : OFF
        If we have created them in our DCC.
      • Transform Vertex to Absolute : ON
        Should be on. If not the collision meshes will all have been placed in the origin.
    • Animation : OFF
      on if it is an animation
    • Material
      • Import Materials : OFF
        We do this inside UE so no need to import
      • Import Textures : OFF
        We do this inside UE so no need to import

Re-import

  • Re-import
    • If we want to re-import we can just drag and drop in the content browser and the old file will be overritten.
    • Another way is to RMB click on the asset and choose re-import. Unreal will then use a property called Import Settings > File Path to locate the asset and reimport it. If the asset was not found a file browser will be presented.

Auto re-import

  • Auto re-import
    • If we want unreal to auto re-import assets from a folder here is how we do that.
    • Open Editor settings > General > Loading & Saving > Directories to Monitor
    • Then we click the + icon and browse to the folder
    • Then we set the Map Directory To so unreal knows where to import to.

Export

  • FBX - Static Mesh
    • Geometry options to enable
      • Smoothing Groups
        • (not needed in Houdini?)
      • Triangulate
      • Preserve Edge Orientation
        • (not needed in Houdini?)

Materials

The nodes in the material editor are HLSL (High Level Shading Language) functions. Materials needs to be compiled before they can be used in the game. In the top bar of the material editor there is a compile button. There is also a save button that both will compile and save the material. When a material is compiled it is considered static and can not change when the game is running.

  • Material
    • Material Domain:
      The Domain that trhe materials attributes will be evaluated in. Cwertain pieces of material functionality are only valid in certain domains, for example vertex normal is only valid on a surface.
      • Surface
    • Blend Mode:
      Determines how the materials color is blended with background colors.
      • Opaque
    • Shading Model:
      Determines how inputs are combined to create the materials final color.
      • Default Lit

Master Material

Inside the master material you can use parameter nodes that expose the parameter to the material instance, this can be done for color values, roughness values, textures etc.

  • Do
    • Do use multiple master materials
      • Master for environment objects
      • Master for characters
      • Master for weapons
    • Consult with the artist what parameters they need exposed
      • This makes sure that only parametrs that makes sense are exposed
      • Make it more intuitive and fast to work with the material
  • Do not
    • Do not make one master material that will work for all objects
      • It is not ppossible to make one material to meets all needs
      • It can introduce performance issues

Concepts

  • Material functions
    • Allows you to share and re-use parts of your material graph
      • If you have a piece of the node network that you need to use in multiple places, concider making a material function. (DRY)
    • RGB mask packing
      • StorĂ­ng various textures in the R,G & B channels of a texture.
        • A great way to lessen tyhe texture needed in memory
        • Important to document what are beeing expected so that the user knows what data should go in each channel.
    • Static switches
      • Allows you to enable or disbale certain parts of the code
        • If you have a part of your code that are quite expensive to run nad thsi functionality is nott needed in some places it could be a good idea to bve able to turn this part of the network off to improve performance.
    • Feature Level Switch
      • Allows you to make one material that will run on any devide that you target.

Create a Master Material

  • Create the master material
    • In the content browser naviagte to where you want your material to be saved
    • RMB click > Material (in the content browser) and give it a name
    • Double click to open it in the material editor
  • Add Base Color
    • RMB click or Press tab to open the node search field
    • Start typing vector, and select Parameters > VectorParameter from the list
    • Select the parameter node and in the details panel:
      • General
        • Parameter Name : “Base_Color”
          The namne of the parameter
      • Material Expression Vector Parameter:
        • Default Value:
          This will be the default base color value
      • Material Expression
        • Group : “BaseColor”
          This is useful …
  • Add a base color texture node
    • To add a texture node we can either:
      • Drag and drop the texture from the content browser to the material editor
      • Or select the texture in the content browser, click one time in the material editor (to give it focus) hold T and LMB click in the material editor.
    • To be able to use the texture sample node as a parameter we need to RMB click it > Convert to Parameter
    • On the texture sample node
      • General
        • Parameter Name : “Base_Color_Texture”
        • Group : “BaseColor”
          This should be found in the dropdown since we already created a group called the same.
  • Create a Static Switch node (base color)
    • In this material we want the ability to switch between a base color or to use a texture for the base color.
    • RMB click or press tab, then start typing “switch” in the node search field
    • Select Parameters > StaticSwitchParameter and press enter.
    • As the parameter name use something that describes what the switch does for instance “UseTextureAsBasecolor”
    • Also make sure that the group is set to “BaseColor”
    • Then we connect the output from the texture sample node to the True input of the switch node and the output from the vectorParameter node (that we use for base color) to the False input.
  • Create a parameter to control Metallic
    • Hold the 1 key and LMB click in the material editor, this will create a 1D constant node
    • RMB click > Convert to Parameter.
      • General
        • Parameter Name : “Metallic”
      • Material Expression Scalar Parameter:
        • Default Value: 0.0
          This will be the default metallic value
        • Slider Min : 0.0
          Because the min of a metallic shopuld be 0.0
        • Slider Max : 1.0
          Because the max of a metallic shopuld be 1.0
      • Material Expression
        • Group : “Metallic”
    • Connecdt to the Metallic slot of the material.
  • Setup a packed texture to be used as roughness
    • Drag and drop the texture (that have packed channels) in the material editor
    • RMB click the texture sample node > Convert to Parameter
    • Set the parameter name
      • General > Parameter Name : “Roughness_Texture”
    • Set the group
      • Material Expression > Group : “Roughness”
    • Change the sampler type to masks since we want to access a packed channel
      • Material Expression Texture Base > Sampler Type : Masks
      • NOTE
        • I get an error when the smapler type is set to masks, look into this…
        • [SM5] (Node TextureSampleParameter2D) TextureSampleParameter> Sampler type is Masks, should be Color for /Game/StarterContent/Textures/T_Brick_Clay_New_M.T_Brick_Clay_New_M
    • Then we want to create a mask parameter node that let us choose which channel of the texture we want to use as our roughness
      • RMB click, tab > Parameters > StaticComponentMaskParameter
      • On the node give it the name “Roghness Masks”
      • In the Material Expression > group field we also add “Roughness”
    • Connect the output from the texture sample node to the input of the mask parameter.
    • Then we will create a lerp node that will let us adjust the roughness texture
      • Hold the L key and click in the material editor
      • Connect the output from the mask parameter to the input of the lerp node
      • then we will create to 1D constants that we will use as parameter for the A (min) and B (max) of the lerp node.
      • Hold thw 1 key and click to times in the material editor
      • Select both of the nodes, RMB > Convert to Parameter.
      • Select one of the parameter nodes
        • Set the parameter name
          • General > Parameter Name : “Roughness_Low”
        • Set the group
          • Material Expression > Group : “Roughness”
        • Set min, max and default values
          • Material Expression Scalar Parameter
            • Default Value : 0.0
            • Slider Min : 0.0001
            • Slider Max : 1.0
      • Select the other parameter nodes
        • Set the parameter name
          • General > Parameter Name : “Roughness_High”
        • Set the group
          • Material Expression > Group : “Roughness”
        • Set min, max and default values
          • Material Expression Scalar Parameter
            • Default Value : 0.5
            • Slider Min : 0.001
            • Slider Max : 1.0
      • Then we will connect “roughness_low” to the A on the lerp node and “roughness_high” to the B.
    • Then we will connect the output of the lerp node to the roughness input of our material.
  • Add a normal map
    • Drag and drop the normal texture in the material editor
    • RMB click the texture node > Convert to Parameter
    • Set the parameter name
      • General > Parameter Name : “Normal_Map”
    • Set the group
      • Material Expression > Group : “Normal”
    • Make sure the the sampler tyoe is set to Normal
    • Then we connect the output of this node to the Normal input of the material. Note that we can RMB click the output pin > Connect to Normal

Modify our master material

As said before, it is wise to create different master materials for different use cases instead of trying to create a one size fits all master material. One quick way to create a new master material is to edit an existing master material. Lets edit the one we just created so that we can use it as a glass material.

  • RMB click the master material > Duplicate (Ctrl W)
  • Lets call it MAT_Glass_Master
  • To make a material “transparent” we need to change the Blend Mode to Translucent or Masked the difference is
    • Translucent
      • The material can have a varying range of transparency.
      • This is more expensive than using a mask, but looks better
      • If the Blend Mode is set to Translucent the Opacity slot on the material is available
    • Masked
      • The material transparency is either on or off, based on the mask channel.
      • If the Blend Mode is set to Masked the Opacity Mask slot on the material is available
  • Set Material > Blend Mode > Translucent
  • Set Translucency > Lighting Mode > Surface ForwardShading
    • This gives the best light / translucency interaction but is also the most expensive.
    • NOTE this is inside the translucency tab
  • Hold 1 key and LMB click in the material editor to create a float constant
  • RMB click and convert it to a parameter
  • Edit properties
    • Set the parameter name
      • General > Parameter Name : “Opacity”
    • Set the group
      • Material Expression > Group : “Opacity”
    • Set min, max and default values
      • Material Expression Scalar Parameter
        • Default Value : 0.25
        • Slider Min : 0.0001
        • Slider Max : 1.0
  • Lets remove the base color setup we did (delete base color texture and the static switch) and just plug the base color (vec3 parm) directly into the base color input of the material.
  • We will keep our roughness setup since that gives a lot of flexibility
  • We can obviously change the roughness texture aswell as the normal map to better fit the glass material. This can also be changed in the material instance at a later stage.

Material Function

A material function is a way to share code between materials and keeping the behaviour consistent across materials.

  • In the content browser, navigate to the desired location.
  • RMB > Materials & Textures > Material Function
  • Give it the name “MF_tile_uv”
  • Double click to go inside
  • Select the Output Result node
    • Material Expression Function Output
      • Output Name : TilingOut
      • Description : Texture tiling utility
  • Add a Texture Coordinate (Coordinates)
  • Add a Functions Input (Functions)
    • Material Expression Function Input
      • Input Name : “Texture Scale”
      • Input Type : Function Input Scalar
      • Preview Value : X 1.0
        • To preview this input when editing the material function we set the x value (of the XYZW) inputs to 1.0
  • Add a multiply, hold M and LMB click.
  • Connect the output of the Texture Coordinate to the A input of the multiply node and the output of the Function Input to thr B input.
  • Connect the output from the Multiply node to the input of the Output node
  • Then press apply and save (I think it is enough tp press save?)

Use a material function

Lets use the material function we just created to control the uv tiling of our master material.

  • From the content browser drag and drop the material function into our master material.
  • Create a 1D constant that we can use to control the texture scale. (Hold 1 key and LMB click to create the node)
  • RMB click > Convert to Parameter
  • Set parameters
    • General
      • Parameter Name : “Texture Scale”
    • Material Expression Scalar Parameter
      • Default Value : 1.0
      • Slider Min: 0.5
      • Slider Max : 25.0
    • Material Expression
      • Group : “UV”
  • Then we will connect the output of our material function to the UV input of all our texture parameter nodes.

Material Instance

A material can not change during runtime, this is where material instances comes in. A Material Instance can change properties during runtime (color values, textures, etc) and we don not have to recompile that material when we do this. There is a slight performance advantage to use material instances over materials, but this is minimal and only noticable if we use thousands of materials. The main advantage is the flexibility to edit the material properties in runtime and without the need to recompile. You can setup a master material that have tweakable properties that are exposed and editable in the material instances.

Creating a material instance

  • Creating

    • RMB click the master material > Create Material Instance
    • RMB click the content browser > Materials & Textures > Material Instance
      • This will create an “empty material instance”
      • Then we can drag and drop the master material in the parent slot of the material instance (when it is opened in the material editor)
  • Material instance

    • Parameter Groups
      • BaseColor
      • Roughness
      • Etc…
        The parameters that we createed inside the master material will be placed in the group that we specify on the parameter. If no groups were specified they will end up inside the Global Scalar Parameter Values. Using groups is a nice way to organize the material.
    • General
      • Phys Material
        Used for sounds, effects etc
      • Parent Material The master Material (can be set/changed here)
    • Light Mass Settings
    • Material Property Overrides
      This should only be used to test/try out things. Mayabe quickly test two sided etc. If checges are needed here it is an indication that the master material is probably not a good fit to be used as a parent for this material insatnce.
      • Blend Mode
      • Shading Model
      • Two sided
      • Etc…
    • Previewing
      Here we can specify which mesh to use for previewing inside the amterial editor.
      • Preview Mesh

Vertex Animation

Vertex animation is a really cheap way to add complex animation to a mesh. It is run on the GPU and is basically offsetting the vertex positions over time. One limitation of vertex animation is since it is run on the GPU the CPU has no/(limited?) access so it is basically used as eyecandy since we can not easily “interact” with the animation in gameplay/realtime.

Setup Vertex animation

  • In the content browser navigate to where you want to save the material
  • RMB click > Material (Create Basic Asset)
  • Give it a good name, and double click to jump in.
  • We need to change our blend mode to masked, since we are going to use a texture for the leaves that have a mask for the transparency.
    • Material
      • Blend Mode : Masked
  • If we are going to use this as texture for leaves we probably want to use a two sided material
    • Material
      • Two Sided : ON
  • Lets drag and drop a texture to use for the base color and alpha
    • Connect the RGB to BaseColor
    • Connect the alpha to Opacity Mask
  • If we have a normal map, drag and drop, connect to Normal
  • Lets add a parameter for roughness
    • Hold 1 and LMB click to create a 1D constant, RMB click convert to parameter
    • Set the parameter name & group to “roughness”
    • Default value 0.5, min 0.0, max 1.0
  • Add the material function that will create the vertex animation
    • RMB or tab and start typing “simple…”
    • Select Misc > SimplGrassWind from the list. (I guess this is part of the starter content)
    • Connect to the World Position Offset on the material
    • Then we need to add some inputs to our simple grass wind material function
    • We need 2 scalar and 1 vector constant.
      • Hold 1 and click 2 times in the editor to create the scalar constants
      • Hold 3 and LMB click to create the vector constant.
      • If we want to expose this for our material instance we can convert the inputs to parameters, give them nice names, add to suitable groups, set some nice defaults, min and max.