s&box
RustCounter-Strike 2s&boxDeadlock
Wiki
Get s&box on Steam
Browse
OverviewGetting StartedCreating GamesEngine & ToolsDocumentationCommunity GamesResources
s&boxDocumentationRenderingPost ProcessingCreating Postprocesses
SOURCE 2 · C#
Build and play games with s&box.

Facepunch's game engine and creation platform — make games in C#, or jump straight into community games.

Get s&box on Steam

s&box Wiki

  • Overview
  • Getting Started
  • Creating Games
  • Engine & Tools
  • Documentation
  • Community Games
  • Resources

Tools & Community

  • Getting Started
  • Creating Games
  • Engine & Tools
  • Resources

Platforms

  • RustBattle
  • CSBattle
  • Rust Game Wiki
  • CS2 Skins Wiki
  • Deadlock Wiki

About

  • Official Site
  • Developer Wiki
  • GitHub
  • Get on Steam
NOT AFFILIATED WITH FACEPUNCH STUDIOS · © 2026 s&box Wiki (community)
Docs/Rendering
Rendering

Creating PostProcesses

To make a post process shader you should derive from BasePostProcess<T>. This makes it easier to make a component that will be able to blend from multiple others.

public sealed class MyBrightnessEffect : BasePostProcess<MyBrightnessEffect>
{
	[Property, Range( -1, 1 )]
	public float Brightness{ get; set; } = 0.0f;

	public override void Render()
	{
		float brightness = GetWeighted( x => x.Brightness );
		if ( brightness.AlmostEqual( 0.0f ) ) return;

		Attributes.Set( "brightness", 1 + brightness );

		var shader = Material.FromShader( "shaders/postprocess/brightness.shader" );
		var blit = BlitMode.WithBackbuffer( shader, Stage.AfterPostProcess, 200, false );
		Blit( blit, "Brightness" );
	}
}

There are a few things here that might need more detail.

GetWeighted

This method gets a weighted value from all of the volumes we might be in. So instead of using Intensity from the component itself, we get it from this method.. which will look at all the active volumes and give us a blended, weighted value according to where the Camera is.

Blit

This method will create a CommandList, which will later be executed when rendering. You can specify the render stage and the order.

You can also specify whether your effect needs the backbuffer or not. If you do, it'll be passed to your shader using the name ColorBuffer.

Shader

Here's a very basic shader that will let the component change the brightness.

MODES 
{
    Forward();
}

COMMON
{
    #include "postprocess/shared.hlsl"
}

struct VertexInput
{
    float3 vPositionOs  : POSITION < Semantic( PosXyz ); >;
    float2 vTexCoord    : TEXCOORD0 < Semantic( LowPrecisionUv ); >;
};

struct PixelInput
{
    float2 vTexCoord : TEXCOORD0;

	// VS only
	#if ( PROGRAM == VFX_PROGRAM_VS )
		float4 vPositionPs		: SV_Position;
	#endif

	// PS only
	#if ( ( PROGRAM == VFX_PROGRAM_PS ) )
		float4 vPositionSs		: SV_Position;
	#endif
};

VS
{
    PixelInput MainVs( VertexInput i )
    {
        PixelInput o;
        
        o.vPositionPs = float4( i.vPositionOs.xy, 0.0f, 1.0f );
        o.vTexCoord = i.vTexCoord;
        
        return o;
    }
}

PS
{
    #include "postprocess/common.hlsl"
    #include "postprocess/functions.hlsl"
    #include "procedural.hlsl"

    Texture2D colorBuffer < Attribute( "ColorBuffer" ); SrgbRead( true ); >;

    float g_flBrightness < Attribute ( "brightness" ); >;

    float4 MainPs( PixelInput i ) : SV_Target0
    {
        float4 color = colorBuffer.SampleLevel( g_sBilinearMirror, i.vTexCoord.xy, 0 );

        color.rgb *= g_flBrightness;

        return color;
    }
}

Source: Facepunch/sbox-docs (CC-BY-4.0) · updated 2026-08-02. Read it rendered on the official docs.

More in Rendering

AmbientLight
Animated Effects
Attributes and Variables
BeamEffect
Beams
Bindless API
C# Shader Nodes
Classes
← All documentation

Community wiki — not affiliated with Facepunch Studios. For the latest and most authoritative information, see the official developer wiki.