Fullscreen shaders
A Fullscreen shader is a post-processing effect: its Frag runs once for every pixel of the screen, usually to change the image rendered so far. Grayscale, vignetting, outlines from depth and color grading are typical examples.
using Ahilevich.ShaderScript;
[Shader]
public class Vignette : ShaderScript.Fullscreen
{
[Range(0, 1)] public float Strength { get; } = 0.5f;
public override void Frag(FullscreenInput IN, ref FullscreenOutput OUT)
{
float4 color = SampleBlitSource(IN.uv);
float distance = math.length(IN.uv - new float2(0.5f, 0.5f));
float vignette = 1 - math.smoothstep(0.3f, 0.8f, distance) * Strength;
OUT.color = new float4(color.rgb * vignette, 1);
}
}
Writing the effect
Frag gets the pixel's position on screen, IN.uv from 0 to 1 and IN.positionCS in pixels, and writes the pixel's color to OUT.color.
| Method | What it does |
|---|---|
SampleBlitSource(uv) |
Reads the image rendered so far. On HDRP, the alpha is always 1. |
SampleSceneDepth(uv) |
Reads the camera's raw depth. Convert it with ShaderApi.LinearEyeDepth or ShaderApi.Linear01Depth. |
By default, the output color replaces the image. With a [Blend] attribute, it's blended over the image instead, for example [Blend(BlendPreset.Alpha)] to overlay a semi-transparent effect, or [Blend(BlendPreset.Multiply)] to darken it. Fullscreen shaders support only the Blend, BlendOp and ZTest surface attributes.
Using it on URP
- Create a material with the shader.
- Select your URP Renderer asset, for example
PC_RendererorMobile_Renderer, and add a Full Screen Pass Renderer Feature. - Set its Pass Material to the material.
The feature's defaults are what most effects need: it runs after post-processing, and Fetch Color Buffer is on, so SampleBlitSource reads the rendered image. Change the Injection Point to run the effect earlier, for example before post-processing so that bloom and tone mapping apply to it.
To read depth with SampleSceneDepth, add Depth to the feature's Requirements.
Using it on HDRP
- Create a material with the shader.
- Add a Custom Pass Volume to your scene. Set its Mode to Global to apply the effect everywhere, or keep a local volume to apply it only where the camera is inside the volume.
- In the volume, add a Full Screen Custom Pass and set its FullScreen Material to the material.
- Set the volume's Injection Point to After Post Process to process the finished image.
SampleBlitSource reads the camera's color as it is at the injection point, and SampleSceneDepth reads its depth.
One shader, both pipelines
The same Fullscreen shader works on both render pipelines; only the setup above differs. Multiply blending is available to Fullscreen shaders on HDRP too, unlike Lit and Unlit shaders.