A post-process effect component that applies depth-based screen-space fog. It sets shader parameters (color, min/max distance, opacity), grabs the current frame and depth textures, and issues a command list to run the shaders after transparent geometry.
using Sandbox;
using Sandbox.Rendering;
namespace BrickJam;
/// <summary>
/// Depth-based screen-space fog. Scene-System port of the legacy <c>ScreenFogEffect : RenderHook</c>.
/// Uses the same unchanged <c>shaders/screenfog_postprocess.shader</c> and its
/// <c>Color</c>/<c>MinDistance</c>/<c>MaxDistance</c>/<c>Opacity</c> attributes plus the grabbed
/// <c>"FrameTexture"</c>/<c>"DepthTexture"</c>. The legacy ran <c>Graphics.Grab*Texture + Graphics.Blit</c>
/// at <c>Stage.AfterTransparent</c>; here we build the same command list and insert it.
/// </summary>
[Title( "Screen Fog" )]
[Category( "Post Processing" )]
[Icon( "foggy" )]
public sealed class ScreenFogEffect : BasePostProcess<ScreenFogEffect>
{
[Property] public Color Color { get; set; } = new Color( 0.5f, 0.5f, 0.5f, 1f );
[Property] public float MinimumDistance { get; set; } = 80f;
[Property] public float MaximumDistance { get; set; } = 7000f;
[Property, Range( 0, 1 )] public float MaxOpacity { get; set; } = 0.6f;
private static readonly Material Shader = Material.FromShader( "shaders/screenfog_postprocess.shader" );
public override void Render()
{
if ( !Shader.IsValid() )
return;
var cl = new CommandList( "ScreenFog" );
// Custom shader parameters go on the material attributes...
Attributes.Set( "Color", GetWeighted( x => x.Color, Color ) );
Attributes.Set( "MinDistance", GetWeighted( x => x.MinimumDistance, MinimumDistance ) );
Attributes.Set( "MaxDistance", GetWeighted( x => x.MaximumDistance, MaximumDistance ) );
Attributes.Set( "Opacity", GetWeighted( x => x.MaxOpacity, MaxOpacity ) );
// ...the grabbed frame/depth textures go on the command list.
cl.Attributes.GrabFrameTexture( "FrameTexture" );
cl.Attributes.GrabDepthTexture( "DepthTexture" );
cl.Blit( Shader, Attributes );
InsertCommandList( cl, Stage.AfterTransparent, 100, "ScreenFog" );
}
}