Skip to content
← Back to Blog 3d-modeling

Unity URP Shader Graph: Build a Custom PBR Material for Any Imported GLB Model

By BitSoul3D6 min read126 views

If you've imported a GLB model into a Unity URP project and slapped the default Lit material on it, you've already hit the wall: blown-out highlights, missing roughness data, no vertex color support, and zero control over how your textures connect. The default Lit material assumes a specific texture slot layout that GLB assets often don't match. Shader Graph fixes this — you wire exactly what you have to exactly what you need, and the result is a fully PBR-correct material that works across every imported model in your project.

Unity URP Shader Graph: Build a Custom PBR Material for Any Imported GLB Model

This guide walks through building that Shader Graph from scratch: setting up the asset, wiring albedo/normal/metallic/roughness, adding vertex color tint support, and making the whole thing SRP Batcher compatible so you don't blow your draw call budget.

Why Unity's Default Lit Material Fails on Imported GLB Assets

The standard Lit shader in URP expects textures in Unity's internal format: a packed mask texture (metallic in R, AO in G, detail mask in B, smoothness in A). GLB files from Blender, Sketchfab, or BitSoul's marketplace pack their data differently — metallic-roughness is a two-channel texture where roughness lives in G and metallic in B, following the glTF 2.0 spec.

Plugging a glTF metallic-roughness texture directly into Unity's Lit material metallic slot gives you garbage output. You either manually re-pack the texture in Photoshop (slow, breaks your pipeline) or you build a Shader Graph that reads the channels correctly.

Why Unity's Default Lit Material Fails on Imported GLB Assets — illustrated

There's a second problem: vertex colors. GLB models exported from Blender frequently carry vertex color data for tinting, AO baking, or foliage wind data. The default Lit shader ignores vertex colors entirely. A Shader Graph reads them in two lines.

Setting Up Shader Graph in URP

Before you start, confirm your project is on URP. In Edit > Project Settings > Graphics, the Scriptable Render Pipeline Settings field should point to a URP asset. If it's empty, you're on Built-in — stop here and migrate first.

Install Shader Graph via Window > Package Manager > Unity Registry > Shader Graph. Create your first graph:

  1. Right-click in the Project window → Create > Shader Graph > URP > Lit Shader Graph
  2. Name it GLBLitCustom
  3. Double-click to open the Shader Graph editor

In the Graph Inspector (top-right), set:

Check Enable GPU Instancing in the Graph Inspector — this is critical for performance when you have hundreds of the same model in a scene.

Wiring GLB Textures: Albedo, Normal, Metallic, and Roughness

Add these nodes to your graph (Space to open the search panel):

Albedo (Base Color)

Texture2D [_BaseMap] → Sample Texture 2D → Base Color (fragment)

Normal Map

Texture2D [_NormalMap] → Sample Texture 2D (Normal mode) → Normal (Tangent Space) (fragment)

Set the Sample Texture 2D node type to Normal so Unity applies the correct decoding.

Metallic-Roughness from glTF

glTF packs roughness in the Green channel and metallic in the Blue channel of a single ORM texture:

Texture2D [_MetallicRoughness] → Sample Texture 2D
  ├─ G channel → [1 - x] (Subtract from 1) → Smoothness (fragment)
  └─ B channel → Metallic (fragment)

The 1 - roughness conversion is the key step. Unity's Lit shading model uses smoothness (the inverse of roughness), so skipping this step makes every imported asset look like wet clay.

Ambient Occlusion

If your GLB includes a separate AO texture (common in Blender exports):

Texture2D [_AOMap] → Sample Texture 2D → R channel → Ambient Occlusion (fragment)

Emission (optional)

Texture2D [_EmissionMap] → Sample Texture 2D → Multiply [_EmissionColor] → Emission (fragment)

Wiring GLB Textures: Albedo, Normal, Metallic, and Roughness — illustrated

Adding Vertex Color Support for Tinting and AO

Vertex colors are free data — they're already in the mesh, you just have to read them:

Vertex Color → Multiply (with Base Color output) → Base Color (fragment)

This multiplies the albedo by whatever vertex color is painted on the mesh. A white vertex color leaves the texture unchanged; a tinted vertex color shifts the hue. This is the standard approach for foliage variation, where the same tree mesh uses vertex colors to randomize hue across instances.

For foliage models specifically (grab a free GLB tree from BitSoul's marketplace to test this), you can also route the vertex color Alpha channel to a wind displacement node on the vertex stage:

Vertex Color (Alpha) → Multiply [_WindStrength] → Position offset (vertex)
Vertex ChannelCommon Use in GLB Assets
RGBMesh tinting, ambient occlusion bake
AlphaWind strength mask, blend weight
All whiteNo vertex color data — safe to ignore

GPU Instancing and SRP Batcher Compatibility

Two things kill draw calls in scenes with many instances of the same model:

SRP Batcher requires all material properties to live in a single CBUFFER block. Shader Graph handles this automatically when you expose properties via the Blackboard — each exposed property gets added to the constant buffer. Do not use GetComponent<Renderer>().material.SetTexture() at runtime on batched materials; use MaterialPropertyBlock instead.

GPU Instancing (enabled in Graph Inspector earlier) lets the GPU render thousands of identical meshes in a single draw call with per-instance data. To verify it's working:

// In your C# spawn script
Graphics.DrawMeshInstanced(mesh, 0, material, matrices, count);

Run the Frame Debugger (Window > Analysis > Frame Debugger) and look for Draw Mesh (instanced) entries. If you see individual Draw Mesh calls instead, check that:

Applying This to Free GLB Assets

The entire workflow above is designed around assets in GLB/glTF format because that's what you'll encounter most often in free asset libraries. Every model in BitSoul's marketplace ships as a game-ready GLB, so you can grab a free character, vehicle, or prop, import it into your URP project, assign this GLBLitCustom Shader Graph material, and have correct PBR shading in under 20 minutes — no texture repacking, no channel guessing.

The metallic-roughness channel swap (G = roughness, B = metallic) described above applies to all of them, so once you've built this graph once, it works across the entire library.

Key Steps at a Glance

StepWhat to Do
SetupCreate URP Lit Shader Graph, enable GPU Instancing
AlbedoSample _BaseMap, wire to Base Color
NormalSample _NormalMap in Normal mode
MetallicSample ORM texture B channel → Metallic
RoughnessSample ORM texture G channel, invert → Smoothness
AOSample AO texture R channel → Ambient Occlusion
Vertex ColorRead Vertex Color node, multiply into Base Color
PerformanceSRP Batcher + sharedMaterial references

Build it once, save it as a .shadergraph asset, and reuse it across every GLB import in the project. Head to BitSoul's marketplace and grab a free GLB model to test the shader on — filter by character, vehicle, or environment prop and you'll have a working test case in two clicks.


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

Tags: weapons

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)