Built-in Render Pipeline to URP in Unity 6: The Migration Checklist
Unity 6.5 deprecated the Built-in Render Pipeline. When to move to URP, what the converter misses, and how to port custom shaders and post-processing.
This checklist follows the order the work actually happens in: decide, back up, convert what Unity can convert for you, then fix the three things it cannot, which are custom shaders, post-processing, and scripts that hook into rendering. Each step names the exact window or menu, and links to the Unity 6 upgrade pages where an API changed.
Should you migrate now?
When to move to URP
| Your situation | Recommendation | Note |
|---|---|---|
| Starting a new project | Start on URP | Unity calls Built-in not recommended for new titles, and URP is the default template in Unity 6. |
| Shipped game, live updates on Built-in | Plan it, no rush | Built-in is supported through the 6.7 LTS lifecycle. Migrate alongside a larger content update rather than in a patch. |
| Selling assets or teaching | Move to URP | Unity is asking Asset Store and education content to be URP-compatible by default. |
| Many custom shaders or OnRenderImage effects | Budget the time | The converter skips these. Count them first: they are most of the work. |
1. Back up first
Unity's documentation is direct about this: the Render Pipeline Converter makes irreversible changes to the project. Commit everything to version control, or copy the project folder, before you open it. Do the migration on a branch so you can compare the old and new look side by side.
Before converting, make a list of every custom shader (search the Project window with t:Shader and ignore Unity's own) and every script that implements OnRenderImage, OnPreRender or OnPostRender. That list is your real estimate.
2. Install URP
- Open Window > Package Manager and install Universal RP (com.unity.render-pipelines.universal) for your Unity version.
- Do not create the pipeline asset by hand yet: the converter's Rendering Settings step creates the URP asset and Universal Renderer, and converts your Built-in quality settings into them.
3. Run the Render Pipeline Converter
- Open Window > Rendering > Render Pipeline Converter.
- Choose Built-In Render Pipeline to URP. For a 2D project, choose Built-In Render Pipeline 2D to URP 2D instead.
- Tick Rendering Settings (creates the URP asset and renderer from your quality settings), Material Upgrade (converts materials that use Unity's built-in shaders) and Read-only Material Converter (converts built-in read-only materials such as Default-Diffuse).
- Initialize the converters, review the list of assets each one will change, then convert.
- Check that the new URP asset is assigned in Project Settings > Graphics and on every level in Project Settings > Quality.
What the Material Upgrade converts
| Built-in shader | URP shader | Note |
|---|---|---|
| Standard, Standard (Specular setup) | Universal Render Pipeline/Lit | URP's physically based shader, metallic or specular workflow. |
| Standard Terrain | Universal Render Pipeline/Terrain/Lit | |
Particles/Standard Surface | Universal Render Pipeline/Particles/Lit | |
Particles/Standard Unlit | Universal Render Pipeline/Particles/Unlit | |
Mobile/* and Legacy Shaders/* (Diffuse, Specular, Bumped, Self-Illumin, Transparent, Cutout) | Universal Render Pipeline/Simple Lit | A cheaper non-PBR shader, close to the legacy look. |
4. Convert custom shaders
The Render Pipeline Converter does not touch custom shaders. You have two routes. For most surface-style shaders, rebuilding them in Shader Graph is fastest and keeps them working through future URP changes. For hand-written vertex and fragment shaders, port the code. Built-in surface shaders (#pragma surface) do not work in URP at all, so those need one route or the other.
Porting a vertex and fragment shader comes down to the same handful of changes every time:
- Add
"RenderPipeline" = "UniversalPipeline"to the SubShader tags. - Replace
CGPROGRAMandENDCGwithHLSLPROGRAMandENDHLSL. - Replace
#include "UnityCG.cginc"with#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl". - Replace
UnityObjectToClipPos(v.vertex)withTransformObjectToHClip(v.positionOS.xyz). - Declare textures with
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);and sample withSAMPLE_TEXTURE2Dinstead ofsampler2Dandtex2D. - Put material properties inside
CBUFFER_START(UnityPerMaterial)andCBUFFER_ENDso the shader works with the SRP Batcher. - Lit passes use the
"LightMode" = "UniversalForward"tag; Built-in's ForwardBase and ForwardAdd passes have no URP equivalent.
Shader "Custom/UnlitTexture"
{
Properties
{
_BaseMap ("Texture", 2D) = "white" {}
_BaseColor ("Color", Color) = (1, 1, 1, 1)
}
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes { float4 positionOS : POSITION; float2 uv : TEXCOORD0; };
struct Varyings { float4 positionHCS : SV_POSITION; float2 uv : TEXCOORD0; };
TEXTURE2D(_BaseMap);
SAMPLER(sampler_BaseMap);
CBUFFER_START(UnityPerMaterial)
float4 _BaseMap_ST;
half4 _BaseColor;
CBUFFER_END
Varyings vert(Attributes input)
{
Varyings output;
output.positionHCS = TransformObjectToHClip(input.positionOS.xyz);
output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
return output;
}
half4 frag(Varyings input) : SV_Target
{
return SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv) * _BaseColor;
}
ENDHLSL
}
}
}GrabPass is not supported in URP. To read what is already on screen, enable Opaque Texture on the URP asset and sample _CameraOpaqueTexture, or use the Scene Color node in Shader Graph.
5. Replace post-processing
URP is not compatible with the Post Processing Stack v2 package. Its post-processing is built in and driven by the Volume framework instead.
- Note the effects and values in each Post-process Volume profile.
- Add a Global Volume (GameObject > Volume > Global Volume), create a Volume Profile, and add the equivalent overrides, such as Bloom, Tonemapping, Color Adjustments and Vignette.
- Enable Post Processing on each camera that should show it.
- Remove the Post Processing Stack v2 package once nothing references it.
6. Fix scripts that hook into rendering
This is the part that compiles fine and silently stops working. URP does not call OnRenderImage, OnPreRender or OnPostRender on cameras, and command buffers added with Camera.AddCommandBuffer do not run.
Built-in hook and its URP replacement
| Built-in | URP | Note |
|---|---|---|
OnRenderImage with Graphics.Blit | Full Screen Pass Renderer Feature | Assign a full-screen material to the renderer feature; no script needed for simple effects. |
OnPreRender / OnPostRender | RenderPipelineManager.beginCameraRendering / endCameraRendering | Subscribe to the static events; they pass the camera being rendered. |
Camera.AddCommandBuffer | A Scriptable Renderer Feature and render pass | In Unity 6 the pass implements RecordRenderGraph. See why Execute stops running. |
| Projector component | URP Decal Projector | Add the Decal renderer feature to the Universal Renderer first. |
| Several cameras sorted by depth | Camera Stacking | One Base camera with Overlay cameras in its stack. |
using UnityEngine;
using UnityEngine.Rendering;
public class CameraHook : MonoBehaviour
{
void OnEnable() => RenderPipelineManager.beginCameraRendering += OnBeginCamera;
void OnDisable() => RenderPipelineManager.beginCameraRendering -= OnBeginCamera;
void OnBeginCamera(ScriptableRenderContext context, Camera camera)
{
// Runs where OnPreRender used to, for every camera URP renders
}
}7. Check lighting and look
- URP's Forward path limits how many lights affect each object. If lights pop or disappear on busy scenes, switch the Universal Renderer to the Forward+ rendering path.
- Rebake lightmaps and reflection probes, then compare screenshots from the Built-in branch: ambient, fog and shadow defaults differ.
- Check each Quality level in Project Settings > Quality uses the URP asset you expect, and tune its shadow distance and cascades.
- Search the project for remaining magenta materials before calling it done.
The checklist
- Project committed and on a branch.
- Custom shaders and rendering scripts listed.
- Universal RP installed; converter run with Rendering Settings, Material Upgrade and Read-only Material Converter.
- URP asset assigned in Graphics and every Quality level.
- No magenta materials; custom shaders rebuilt in Shader Graph or ported to HLSL.
- Post Processing Stack v2 replaced with Volumes, then removed.
- OnRenderImage, OnPreRender, OnPostRender and AddCommandBuffer replaced.
- Lighting rebaked and compared against the Built-in build.
- Scripts checked for other Unity 6 changes with the Unity 6 script checker.
Sources
- Unity: Render pipelines strategy for 2026
- Unity Manual: Migrate from the Built-In Render Pipeline to URP (6.5)
- Unity Manual: Render Pipeline Converter
- Unity Manual: Convert shaders to URP with the Render Pipeline Converter
- Unity Manual: Upgrade custom shaders for URP compatibility
- Unity Manual: URP integration with post-processing
Written by Mete, the Unity developer who makes Scripts For Unity and shares it free with the community. Articles cite the Unity documentation they rely on, state the Unity version they were written for, and show an updated date only when the text or code changed. How articles are written and checked