Skip to content
← Back to Blog guide

Material Functions in Unreal Engine 5: Reusable PBR Shader Logic

By BitSoul3D4 min read108 views

Packaging shader logic into named, reusable blocks is the kind of discipline that separates a rushed prototype from a maintainable game codebase. Material Functions in Unreal Engine 5 give you exactly that — a container for any node sub-graph you want to call from multiple Materials without copy-pasting. Every tweak propagates automatically to every asset that references the function.

Material Functions in Unreal Engine 5: Reusable PBR Shader Logic

What Material Functions are (and why solo devs need them)

A Material Function is a UE5 asset (MaterialFunction) that holds a self-contained node graph with explicit inputs and outputs. You build it once in the Material Function editor, then place FunctionInput and FunctionOutput nodes at its boundary. Any Material that references it via a Call Material Function node gets the encapsulated logic compiled inline — there is no runtime overhead compared to duplicating the nodes by hand.

The productivity payoff is immediate. If you have 40 GLB props from BitSoul's marketplace all using a dirt-layer blend, fixing the blend formula in one Material Function updates every prop simultaneously. Without functions, the same fix is 40 manual edits.

When to reach for a Material Function:

What Material Functions are (and why solo devs need them) — illustrated

Building your first Material Function in UE5

Create a Material Function in the Content Browser → Add → Material & Textures → Material Function. Name it with a MF_ prefix by convention — MF_DirtBlend, MF_PBRCore, MF_EmissiveMask.

Inside the editor you have three key boundary node types:

NodePurpose
FunctionInputExposes a parameter slot on the Call node
FunctionOutputSends a value back to the parent Material
SetMaterialAttributesPacks full PBR channels into a single wire

A minimal dirt-blend function in pseudocode:

FunctionInput: BaseColor (Vector3)
FunctionInput: DirtMask  (Scalar, 0–1)
FunctionInput: DirtColor (Vector3, default = 0.05, 0.04, 0.03)

LinearInterpolate(BaseColor, DirtColor, DirtMask)
        ↓
FunctionOutput: BlendedColor

Pin the FunctionInput nodes to a LinearInterpolate, then route the result to FunctionOutput. Set a Preview Value on each input so the function renders correctly when edited in isolation.

Exposing scalar inputs as Material Parameters

Inside a function you can use ScalarParameter and VectorParameter nodes exactly like in a regular Material. These bubble up as exposed parameters when a calling Material Instance is opened, so you can vary DirtIntensity per-prop in the Instance without touching the function graph:

ScalarParameter(DirtIntensity, default=0.5)
        ↓
Multiply(DirtMask, DirtIntensity)
        ↓
FunctionOutput: ScaledDirtMask

Connecting Material Functions to your GLB asset library

Once your GLB props are in engine, create one Master Material per surface category — metal, painted plastic, stone, fabric — and have each one call the relevant Material Functions. All per-asset variation lives in Material Instances that override scalar and vector parameters, not in duplicated Material graphs.

A three-layer master setup that covers most game environments:

  1. MF_PBRCore — passes BaseColor, Roughness, Metallic, and Normal through with optional intensity multipliers
  2. MF_DirtBlend — overlays a world-space dirt layer driven by a scalar mask
  3. MF_EmissiveMask — gates emissive glow through a packed texture channel (often stored in the ORM alpha)

Each function is a separate asset; swap or update any layer independently. When you pull new free props from bitsoulhosting.com/marketplace, they slot into this system with a single Material Instance assignment — no rework required.

Connecting Material Functions to your GLB asset library — illustrated

Optimizing Material Function shader complexity

Material Functions compile inline — the HLSL they generate is identical to hand-placed nodes. There is no call overhead, but there is also no automatic reduction in instruction count. Keep these rules in mind:

Approximate instruction-count targets to benchmark against:

Simple surface    < 60 instructions
Standard PBR     60–120 instructions
Complex layered  120–200 instructions  ← profile before shipping
Mobile budget    < 80 instructions

Functions that stay under these ceilings are safe to stack. Above 200 instructions, profile on target hardware before committing to the design.

Material Functions are among the highest-ROI patterns in UE5 shader work — build them early and every new 3D asset you import snaps into a coherent, maintainable shader system without redundant graph maintenance. Browse and download game-ready reusable GLB assets at bitsoulhosting.com/marketplace to put your new function library to work immediately.


This post is part of the Ultimate Guide to Free 3D Game Assets — BitSoul's complete reference for formats, texturing, rigging, optimization, and engine integration.


Need drop-in assets for this workflow? Grab the Architecture Western Bundle on the BitSoul marketplace and drop them straight into your project.

Tags: architecture

Skip the modeling — download it instead

A free BitSoul3D account gets you 2 GLB downloads every month for personal use plus 25 one-time AI Engine credits, no card required. PBR-textured GLB downloads with a full 3D preview before you buy, for Unreal, Unity, Godot or Blender — OBJ and 3D-printable STL come with any purchase or paid plan.

Browse 1,051 models — from $4.99 → or start free (2 downloads a month)