Skip to content
HY Devlog
Go back

A Render Pipeline Is an Asset, and Built-In Is What's Left When the Field Is Empty

The last three posts kept circling the URP / Built-In fork. The shader docs split in two, examples run on only one side, the macro names differ. Every time, I waved it off with “different pipeline” — without ever pinning down what a pipeline actually is.

That’s the moment I clipped this. Following the shader docs downward, I got curious about the pipeline itself and climbed a level up. It’s Unity’s Introduction to render pipelines, and unlike the previous ones it’s a page with actual prose rather than a table of links.

One thing changed after reading it. Thinking of Built-In as something you “pick” was wrong.

Table of contents

Table of contents

A graphics pipeline and a render pipeline are different things

The names need sorting out first. I wrote The Graphics Pipeline a while back, and that was about what happens inside the GPU as a vertex becomes a pixel — vertex shader, rasterizer, fragment shader.

The render pipeline in this document is one level up. The glossary defines it as:

A series of operations that take the contents of a Scene, and displays them on a screen. Unity lets you choose from pre-built render pipelines, or write your own.

“Or write your own” is the difference. The graphics pipeline inside the GPU isn’t mine to change; the render pipeline the engine runs each frame is. The relationship:

LayerWhat it doesCan I touch it
Render pipelineWhat to draw each frame, and in what orderYes, in C# (SRP)
└ Graphics pipelineHow one draw call goes from vertices to pixelsOnly via shader code

It’s not strange that the two names get confused. Both are “pipeline,” and both glossary entries open with something like “a series of operations.”

As an aside, this clipping lost its glossary links entirely, so the first sentence was saved as “A takes the objects in a and displays them on-screen.” — a sentence with no subject and no object. That’s a scraping problem rather than a documentation one, and other clippings from the same day kept their glossary text. It’s a good reason to reopen the original before relying on something you clipped.

Three steps — culling, rendering, post-processing

The manual lays out what a render pipeline does in three steps.

StepWhat the manual says
1. CullingDecides which objects from the scene to display
2. RenderingDraws the objects with their correct lighting into pixel buffers
3. Post-processingModifies the pixel buffers to generate the final output frame

And one more line:

A render pipeline repeats these steps each time Unity generates a new frame.

Unpacking each a little:

Culling is removing what isn’t visible. The manual names two kinds — frustum culling for what’s outside the view, and occlusion culling for what’s hidden behind something else. Not drawing what doesn’t need drawing is the cheapest optimization there is, which is why this step is first.

Rendering is where the graphics pipeline above runs. “With their correct lighting” matters here. How lighting is computed — forward or deferred, how many lights an object can receive — differs per pipeline, and that’s why shaders are pipeline-bound. A URP shader can call GetMainLight() because URP decided to hand the data over that way.

Post-processing works on the finished pixel buffers. The manual’s examples are color grading and bloom. Screen effects like glitch usually attach here too.

Built-In isn’t a choice, it’s the default

This is the part that made me write the post.

The manual says Unity “provides three prebuilt render pipelines” — URP, HDRP, Built-In. Which reads like picking one of three. But look up the rule that decides which one actually runs and the picture is different.

For each quality level in the Quality settings window, Unity uses the Render Pipeline Asset assigned to Render Pipeline Asset. If the property is unassigned, Unity uses the Render Pipeline Asset assigned to Default Render Pipeline Asset in the Graphics settings window instead.

If both Render Pipeline Asset and Default Render Pipeline aren’t set, Unity uses the Built-In Render Pipeline.

So the order is:

PriorityWhere Unity looks
1The quality level’s Render Pipeline Asset
2Graphics settings’ Default Render Pipeline Asset
3Both empty → Built-In

Built-In has no asset. URP and HDRP are switched on by assigning a RenderPipelineAsset that exists as a file in your project; Built-In is what remains when that field is empty. Less “one of three” than two assets and one fallback.

The Built-In page’s own wording leans this way too:

Unity’s Built-in Render Pipeline is Unity’s older render pipeline. It’s not based on the Scriptable Render Pipeline, but you can configure it by choosing between different rendering paths, and extend its functionality with command buffers and callbacks.

No “deprecated,” no “legacy.” It’s still Supported in the current docs. But “older” and “not based on the Scriptable Render Pipeline” place it.

This also explains why a URP shader needs the "RenderPipeline" = "UniversalPipeline" tag, from the earlier posts. The pipeline is an assigned thing, so it can be named — and Built-In has no name to point at, so it gets no tag.

What SRP sells isn’t features, it’s C#

So what is SRP? The definition is short.

The Scriptable Render Pipeline is a thin API layer that lets you schedule and configure rendering commands using C# scripts.

It has two parts:

NameWhat the manual says
RenderPipelineAssetAn asset in your Unity Project that stores data about which Render Pipeline Instance to use, and how to configure it
Render Pipeline InstanceAn instance of a class whose script inherits from RenderPipeline and overrides its Render() method

So the asset holds “which one to use” and the instance holds “how to draw.” That structure is also why unchecking boxes on a URP Asset shrinks your build — the shader variant stripping from the earlier post. The settings live in an asset, so the build process can read them.

And here’s the line on this page I found most striking:

This level of customization is also possible in the Built-In Render Pipeline when you purchase access to the Unity engine’s source code in C++.

Which means Built-In’s “limited options for customization” is not a technical limit but an access one. To change culling, rendering, or post-processing in Built-In you buy the C++ source; in SRP you just read the C# that ships in the package.

Viewing SRP as adding readability rather than new graphics features explains why URP exists separately from Built-In despite targeting nearly the same platforms.

So which one do you pick

The Choose a render pipeline page states the target use cases:

PipelineThe stated target
URPProjects needing rendering scalability across all platforms, especially TBDR platforms and untethered VR
HDRPProjects needing photorealism and high-fidelity rendering on high-end platforms
Built-InProjects needing rendering scalability across all platforms

URP and Built-In read almost identically — both are “rendering scalability across all platforms.” So the target isn’t the difference; the difference is the extensibility from the previous section. The manual also calls URP “easier to extend than the Built-In Render Pipeline.”

Two constraints are unambiguous:

You can’t use the Universal Render Pipeline and the High Definition Render Pipeline (HDRP) at the same time.

HDRP is also platform-narrow. In the feature comparison, Nintendo Switch, iOS, and Android are all “No.” Ray tracing and DLSS, conversely, are HDRP-only.

One entry surprised me. Multiple directional light shadows show “Yes” for Built-In and “No” for both URP and HDRP. The newer pipeline isn’t always a superset. Before migrating, check which cell the features you use fall into.

And the most important warning:

It can be very time-consuming to switch a project from one render pipeline to another, especially if the project is far along in development.

Given that the previous three posts were about porting a single shader, that tracks. Shaders, materials, post-processing volumes, and lighting settings are all bound to the pipeline.

Where and why you’d use this

You don’t write code from this document as such. But needing to check which pipeline is active from code does come up — when different pipelines need different shaders or assets, or when a teammate opens a scene with the wrong asset assigned.

Checking which pipeline is active

using UnityEngine;
using UnityEngine.Rendering;

/// <summary>
/// Checks the active render pipeline and warns when it isn't the expected one.
/// </summary>
public class RenderPipelineGuard : MonoBehaviour
{
    private const string EXPECTED_ASSET_NAME = "UniversalRP-HighQuality";

    [Header("Expectation")]
    [SerializeField, Tooltip("Leave empty to expect the Built-In Render Pipeline")]
    private RenderPipelineAsset _expectedAsset;

    private void Awake()
    {
        // Already resolved: quality settings first, then graphics settings. Null if both are empty.
        RenderPipelineAsset active = GraphicsSettings.currentRenderPipeline;

        if (active == null)
        {
            Debug.LogWarning(
                $"[{nameof(RenderPipelineGuard)}] The active pipeline is Built-In. " +
                $"No {EXPECTED_ASSET_NAME} asset is assigned.", this);
            return;
        }

        if (_expectedAsset != null && active != _expectedAsset)
        {
            Debug.LogWarning(
                $"[{nameof(RenderPipelineGuard)}] Expected: {_expectedAsset.name}, " +
                $"actual: {active.name}", this);
        }
    }
}

A few notes:

Switching at runtime

You can swap the asset from code. There are two places to write to:

// The global default
GraphicsSettings.defaultRenderPipeline = _targetAsset;

// The current quality level (this one wins)
QualitySettings.renderPipeline = _targetAsset;

Because of the precedence, a leftover value in the quality settings means changing the graphics settings does nothing. That’s the spot where you’ll lose time wondering why nothing happened.

The manual’s warning, carried over:

When you change the active render pipeline, you must ensure that the assets and code in your project are compatible with the new render pipeline; otherwise, you might experience errors or unintended visual effects.

Swapping quality presets (URP high ↔ low) is reasonable; swapping URP ↔ Built-In at runtime effectively isn’t. The shaders don’t follow.

What to check before choosing

Things the docs can answer at the moment you’re deciding:

Where not to apply this

Summary

The “different pipeline” I waved at across three posts now has an answer behind it. A pipeline is an asset assigned to the project, and that asset holds, in C#, what gets drawn each frame and in what order. Shaders being pipeline-bound and migration being expensive both fall out of that.


References

The clipping dates from December 2025. Its source link is pinned to 6000.1, so the quotations follow that version. The shader clippings from the same day pointed at 6000.2.


Share this post:

Previous Post
Thirteen Built-In Shader Examples: The Further Down the List, the Less Ports to URP
Next Post
There Are Two Clamps: Swap the Arguments and Only One Throws