Camera/RetroCameraVignette.cs
using Sandbox;
using Sandbox.Rendering;

public sealed class RetroCameraVignette : BasePostProcess
{
	/// <summary>
	/// The color of the vignette or the "border"
	/// </summary>
	[Property] public Color Color { get; set; } = Color.Black;

	/// <summary>
	/// How strong the vignette is. This is a value between 0 -> 1
	/// </summary>
	[Property, Range( 0, 1 )] public float Intensity { get; set; } = 1.0f;

	/// <summary>
	/// How much fall off or how blurry the vignette is
	/// </summary>
	[Property, Range( 0, 1 )] public float Smoothness { get; set; } = 1.0f;

	/// <summary>
	/// How circular or round the vignette is
	/// </summary>
	[Property, Range( 0, 1 )] public float Roundness { get; set; } = 1.0f;

	/// <summary>
	/// The center of the vignette in relation to UV space. This means
	/// a value of {0.5, 0.5} is the center of the screen
	/// </summary>
	[Property] public Vector2 Center { get; set; } = new Vector2( 0.5f, 0.5f );

	static Material effectMaterial = Material.Load( "materials/postprocessing/vignette.vmat" );

	public override void Render()
	{
		if ( Intensity.AlmostEqual( 0.0f ) )
			return;

		Attributes.Set( "standard.vignette.color", Color );
		Attributes.Set( "standard.vignette.intensity", Intensity );
		Attributes.Set( "standard.vignette.smoothness", Smoothness );
		Attributes.Set( "standard.vignette.roundness", Roundness );
		Attributes.Set( "standard.vignette.center", Center );

		var cl = new CommandList( "Vignette" );
		cl.Attributes.GrabFrameTexture( "ColorBuffer" );
		cl.Attributes.GrabDepthTexture( "DepthBuffer" );
		cl.Blit( effectMaterial, Attributes );

		InsertCommandList( cl, Stage.BeforePostProcess, 100, "Vignette" );
	}
}