Home › Blog › URP shader conversion
🔷 Engine guide · 2026

Converting Built-in shaders to URP

The converter handles Unity's own materials. Everything custom is up to you. Here is how to triage a Built-in project, rewrite hand-written shaders for URP and replace effects that no longer exist.

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 findRoute
Materials on Standard, Legacy or Mobile shadersRender Pipeline Converter
Surface shaders with simple lighting tweaksShader 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 buffersRenderer Feature or Full Screen Pass
Shaders using GrabPass (distortion, refraction)Opaque Texture or Scene Color node
Old post-processing stackURP 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 UniversalFragmentPBR takes a SurfaceData structure whose fields line up closely with Built-in's SurfaceOutputStandard, 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:

  1. Replace CGPROGRAM and ENDCG with HLSLPROGRAM and ENDHLSL.
  2. Replace UnityCG.cginc with URP's Core.hlsl include, plus Lighting.hlsl if you light the surface.
  3. Add "RenderPipeline" = "UniversalPipeline" to the SubShader tags. Without it, URP will not use the SubShader.
  4. Set pass tags: UniversalForward for the main pass and a ShadowCaster pass if the object casts shadows. URP does not support Built-in tags such as ForwardAdd.
  5. Wrap material properties in CBUFFER_START(UnityPerMaterial) and CBUFFER_END, identical in every pass, so the shader stays compatible with the SRP Batcher.
  6. Use URP's helpers, for example TransformObjectToHClip or GetVertexPositionInputs for positions, GetMainLight for the main light, and SampleSH instead of ShadeSH9.
  7. Rename _MainTex and _Color to _BaseMap and _BaseColor if 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_PLUS keyword was deprecated in Unity 6.1.
  • Missing depth-normals pass. Custom shaders without one will not contribute to SSAO properly.
  • Variant explosion. Every multi_compile multiplies variants and build time. Check stripping settings and the Frame Debugger after conversion.
  • Scripts setting old property names. URP Lit keeps _Color only 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

FAQ

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.