The short answer
Run Unity's Render Pipeline Converter for materials that use Unity's own Standard, Legacy and Mobile shaders, then sort every custom shader into one of three routes: rebuild it in Shader Graph, port it to hand-written URP HLSL, or replace it with a URP feature that already does the job. Surface shaders, GrabPass and OnRenderImage do not exist in URP, so plan for those first. Built-in is deprecated but supported through the Unity 6.7 LTS cycle, at least until the end of 2028, so do this carefully rather than in a panic. Our Unity 6 upgrade guide covers the planning side; this post covers the shader work.
Step 1: back up and triage
The converter overwrites files and Unity's documentation warns they cannot be restored, so work on a branch. Then list every shader in the project. From Unity 6.4, Project Auditor is built into the editor (Window > Analysis > Project Auditor) and its Shaders view shows variants, passes and keywords per shader. Sort them:
| What you find | Route |
|---|---|
| Materials on Standard, Legacy or Mobile shaders | Render Pipeline Converter |
| Surface shaders with simple lighting tweaks | Shader Graph (Lit target), or a URP custom lighting template |
| Hand-written vertex/fragment shaders (unlit, VFX, UI) | Port to URP HLSL |
| Screen effects using OnRenderImage or camera command buffers | Renderer Feature or Full Screen Pass |
| Shaders using GrabPass (distortion, refraction) | Opaque Texture or Scene Color node |
| Old post-processing stack | URP Volume overrides (the converter has a Post-Processing Stack v2 step) |
Step 2: run the converter
Open Window > Rendering > Render Pipeline Converter. From Unity 6.4 you choose Built-in as the source and URP as the target, select the material and settings converters, click Scan, review the list, then Convert Assets; Unity 6.0 to 6.3 use an Initialize Converters step instead. Standard maps to URP Lit and Legacy and Mobile shaders map to Simple Lit. Unity notes that Simple Lit is not a performance match for old mobile shaders, because it considers all lights in the URP Asset, so profile on devices afterwards. Unity 6.5 also added a command-line converter for batch runs on large projects.
The converter does not touch custom shaders. Any material still showing magenta afterwards is on your list for the next steps.
Step 3: decide what to do with surface shaders
Surface shaders are Built-in only. Unity had planned "Block Shaders" as a replacement for scriptable pipelines, but its shader team said in January 2026 that development is on hold. That leaves two options:
- Shader Graph. Usually the fastest route for lit materials with custom colour, masks, dissolve or vertex animation. A Custom Function node lets you keep small pieces of existing HLSL. Unity 6.3 added custom lighting templates, including toon and simplified lighting.
- Hand-written HLSL using URP's lighting functions. URP's
UniversalFragmentPBRtakes aSurfaceDatastructure whose fields line up closely with Built-in'sSurfaceOutputStandard, which makes it the closest equivalent for porting a surface shader by hand.
Step 4: port hand-written shaders
For vertex and fragment shaders, the changes are mechanical but must all be made:
- Replace
CGPROGRAMandENDCGwithHLSLPROGRAMandENDHLSL. - Replace
UnityCG.cgincwith URP'sCore.hlslinclude, plusLighting.hlslif you light the surface. - Add
"RenderPipeline" = "UniversalPipeline"to the SubShader tags. Without it, URP will not use the SubShader. - Set pass tags:
UniversalForwardfor the main pass and aShadowCasterpass if the object casts shadows. URP does not support Built-in tags such asForwardAdd. - Wrap material properties in
CBUFFER_START(UnityPerMaterial)andCBUFFER_END, identical in every pass, so the shader stays compatible with the SRP Batcher. - Use URP's helpers, for example
TransformObjectToHCliporGetVertexPositionInputsfor positions,GetMainLightfor the main light, andSampleSHinstead ofShadeSH9. - Rename
_MainTexand_Colorto_BaseMapand_BaseColorif scripts or other systems expect URP naming, and update any scripts that set the old names.
Step 5: replace GrabPass and OnRenderImage
GrabPass is not supported in URP. Turn on Opaque Texture in the URP Asset, which Unity describes as working like GrabPass, and sample it with SampleSceneColor in HLSL or the Scene Color node in Shader Graph. It only contains opaque objects, so refraction shaders must render as transparent.
OnRenderImage is not supported in scriptable pipelines, and Camera.AddCommandBuffer only works in Built-in. For simple full-screen effects, create a Fullscreen Shader Graph and add a Full Screen Pass Renderer Feature to the renderer. For complex effects, write a Renderer Feature using the render graph API; from Unity 6.4 the old Compatibility Mode for custom passes is removed, so new passes must use render graph.
The traps that waste days
- No shadows, no error. If a ported shader leaves out URP's main-light shadow keywords, it compiles cleanly and simply receives no shadows.
- Forward+ and extra lights. In the Forward+ path the old additional-light count returns zero; use the cluster light loop macros instead. The older
_FORWARD_PLUSkeyword was deprecated in Unity 6.1. - Missing depth-normals pass. Custom shaders without one will not contribute to SSAO properly.
- Variant explosion. Every
multi_compilemultiplies variants and build time. Check stripping settings and the Frame Debugger after conversion. - Scripts setting old property names. URP Lit keeps
_Coloronly as a hidden legacy property, so code that sets it stops changing the visible colour.
Test it properly
Compare screenshots of every scene before and after, profile on your weakest target device, check the SRP Batcher is batching in the Frame Debugger, and run a full QA pass before any release. Conversions look finished long before they are.
Need help converting?
We convert Unity projects to URP for studios that want their own team on new content: audit first, then a fixed price for the shader and pipeline work. See co-development and project rescue or Unity game development.
Sources: Unity Manual: Render Pipeline Converter · Unity: render pipelines strategy for 2026 · Unity Manual: surface shaders · Unity Manual: GrabPass · Unity Scripting API: OnRenderImage · Unity: Block Shaders on hold. Checked October 14, 2026.
Related: Co-development and rescue · Unity game development · Unity 6 upgrade guide
Quick answers ❓
Does the Render Pipeline Converter convert custom shaders?
No. Unity's documentation says the material converters handle only prebuilt Built-in shaders, such as Standard, Legacy and Mobile. Custom shaders must be rebuilt in Shader Graph, ported to URP HLSL or replaced.
Are surface shaders supported in URP?
No. Surface shaders work only in the Built-in Render Pipeline. Unity put its planned Block Shaders replacement on hold in January 2026, so use Shader Graph or hand-written HLSL with URP's lighting functions.
What replaces GrabPass in URP?
The Opaque Texture. Enable it in the URP Asset and sample it with SampleSceneColor in HLSL or the Scene Color node in Shader Graph. It contains only opaque objects, so the shader must render as transparent.
What replaces OnRenderImage in URP?
Renderer Features. For simple effects, use a Fullscreen Shader Graph with the Full Screen Pass Renderer Feature. For complex effects, write a custom Renderer Feature using the render graph API.
When will Unity remove the Built-in Render Pipeline?
Unity has not set a removal date. Built-in was deprecated in Unity 6.5 and remains supported through the Unity 6.7 LTS cycle, at least until the end of 2028 according to Unity.
Related guides
Unity 6 upgrade guide: Built-in is deprecated → Unity pricing in 2026 →Moving your project to URP? 🧪
Send us the project details. You'll get a shader audit plan and a fixed price for the conversion within 48 hours.