Table of Contents

One shader, two render pipelines

A Shader Script shader works on URP and on HDRP. This page explains how, and what differs between the two.

How it works

Every shader class is translated into shader code for both render pipelines. When Unity imports the shader, it keeps the code for the render pipelines installed in the project, so a URP project doesn't pay for HDRP code and vice versa. With both pipelines installed, the shader works with whichever is active.

The Create menu's URP and HDRP templates only differ in the pipeline-specific attributes they list as comments. The resulting shaders work on both pipelines.

Pipeline-specific attributes

Most attributes apply to both render pipelines. The ones that exist only on one pipeline are in their own namespace:

  • Ahilevich.ShaderScript.Urp: WorkflowMode, ReceiveShadows, SpecularHighlights, EnvironmentReflections, DetailMap, DetailScale.
  • Ahilevich.ShaderScript.Hdrp: Material, ClearCoat, Refraction, DepthOffset, Tessellation, Distortion, and the DiffusionProfile property type.

A pipeline-specific attribute has no effect on the other pipeline, so a shader can use attributes of both.

Pipeline-specific code

Branch on IsUrp or IsHdrp, compile-time constants, when the code must differ. The branch for the other pipeline is removed from the compiled shader, but it must still compile on both pipelines.

OUT.emission = IsHdrp ? EmissionColor.rgb * 1000 : EmissionColor.rgb;

What differs

Topic URP HDRP
World-space positions Absolute. Relative to the camera. Use ShaderApi.GetAbsolutePositionWS for positions that must stay fixed in the world, and the ShaderApi view-direction functions instead of subtracting from WorldSpaceCameraPos.
Light units Arbitrary units: an emission of 1 is visibly bright. Physical units with camera exposure: the same emission looks dark. Scale emission up on HDRP, or use ShaderLib.ApplyExposureWeight.
LitFragmentOutput HDRP fields Ignored. Used by the material type and features.
Built-in variables All available. The matrices and ScaledScreenParams listed as URP-only don't exist; use the ShaderApi transforms.
Ambient and fog functions Return the scene's values. Return 0.
Multiply blending Supported. Fullscreen shaders only.
FragmentInput.uv4 to uv7 Available. Unity 6000.3 or later.
Passes URP's set. HDRP's set, with more passes, including ray tracing.

The Material Inspector

The Material Inspector follows the active render pipeline: on URP it looks like URP's Lit or Unlit Inspector, on HDRP like HDRP's. The settings it shows use each pipeline's own names, and so do the material properties behind them. For example, the surface type is stored in _Surface on URP and in _SurfaceType on HDRP.

Keep that in mind when you set a shader's surface settings from a script. From a Material Inspector plugin, the GuiPluginContext methods such as IsTransparent read them the same way on both pipelines. See Material Inspector.