Files
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

142 lines
4.5 KiB
C#

using Sandbox.Rendering;
namespace Sandbox;
/// <summary>
/// Applies a depth of field effect to the camera
/// </summary>
[Title( "Depth Of Field" )]
[Category( "Post Processing" )]
[Icon( "center_focus_strong" )]
public sealed class DepthOfField : BasePostProcess<DepthOfField>
{
/// <summary>
/// Quality scale factors: [Off, Low, Medium, High]
/// </summary>
private static readonly float[] StepScales = { 0f, 3f, 2f, 1f };
// same problem, this isn't granular enough
[ConVar( "r_dof_quality", ConVarFlags.Saved, Min = 0, Max = 3, Help = "Depth of field quality (0: off, 1: low, 2: med, 3: high)" )]
internal static int Quality { get; set; } = 3;
/// <summary>
/// How blurry to make stuff that isn't in focus.
/// </summary>
[Range( 0, 100 )]
[Property, Group( "Focus" ), Icon( "blur_circular" )]
public float BlurSize { get; set; } = 30.0f;
/// <summary>
/// How far away from the camera to focus in world units.
/// </summary>
[Range( 1.0f, 1000 )]
[Property, Group( "Focus" ), Icon( "horizontal_distribute" )]
public float FocalDistance { get; set; } = 200.0f;
/// <summary>
/// This modulates how far is the blur to the image.
/// </summary>
[Property, Range( 0.0f, 1000.0f ), Group( "Focus" ), Icon( "blur_linear" )]
public float FocusRange { get; set; } = 500f;
/// <summary>
/// Should we blur what's ahead the focal point towards us?
/// </summary>
[Property, Group( "Properties" ), Icon( "flip_to_back" ), Hide]
public bool FrontBlur { get; set; } = false;
/// <summary>
/// Should we blur what's behind the focal point?
/// </summary>
[Property, Group( "Properties" ), Icon( "flip_to_front" ), Hide]
public bool BackBlur { get; set; } = true;
CommandList command = new CommandList( "Depth Of Field" );
public override void Render()
{
if ( Quality == 0 || (!BackBlur && !FrontBlur) )
return;
float blurSize = GetWeighted( x => x.BlurSize, 0.0f );
if ( blurSize < 0.5f ) return;
float focalDistance = GetWeighted( x => x.FocalDistance, 200.0f );
float focalLength = GetWeighted( x => x.FocusRange, 500.0f );
float stepScale = StepScales[Quality.Clamp( 0, 3 )];
command.Reset();
var compute = new ComputeShader( "postprocess_standard_dof_cs" );
var downsample = 2;
command.Attributes.SetValue( "Color", RenderValue.ColorTarget );
command.Attributes.SetValue( "Depth", RenderValue.DepthTarget );
command.Attributes.SetValue( "D_MSAA", RenderValue.MsaaCombo );
var Vertical = command.GetRenderTarget( "Vertical", downsample, ImageFormat.RGBA16161616F, ImageFormat.None );
var Diagonal = command.GetRenderTarget( "Diagonal", downsample, ImageFormat.RGBA16161616F, ImageFormat.None );
var Final = command.GetRenderTarget( "Final", downsample, ImageFormat.RGBA16161616F, ImageFormat.None );
command.Attributes.Set( "InvDimensions", Vertical.Size, true );
command.Attributes.Set( "Radius", (int)(blurSize / stepScale) );
command.Attributes.Set( "StepScale", stepScale );
command.Attributes.Set( "VerticalSRV", Vertical.ColorTexture );
command.Attributes.Set( "DiagonalSRV", Diagonal.ColorTexture );
command.Attributes.Set( "FinalSRV", Final.ColorTexture );
command.Attributes.Set( "Vertical", Vertical.ColorTexture );
command.Attributes.Set( "Diagonal", Diagonal.ColorTexture );
command.Attributes.Set( "Final", Final.ColorTexture );
command.Attributes.Set( "FocusGap", 0 );
foreach ( DoFTypes type in Enum.GetValues( typeof( DoFTypes ) ) )
{
if ( !BackBlur && type == DoFTypes.BackBlur )
continue;
if ( !FrontBlur && type == DoFTypes.FrontBlur )
continue;
command.Attributes.Set( "FocusPlane", focalDistance.Clamp( 0, 5000 ) );
command.Attributes.Set( "FocalLength", focalLength );
command.Attributes.SetCombo( "D_DOF_TYPE", type );
command.Attributes.SetCombo( "D_PASS", BlurPasses.CircleOfConfusion );
command.DispatchCompute( compute, Vertical.Size );
command.Attributes.SetCombo( "D_PASS", BlurPasses.Blur );
command.DispatchCompute( compute, Vertical.Size );
command.Attributes.SetCombo( "D_PASS", BlurPasses.RhomboidBlur );
command.DispatchCompute( compute, Vertical.Size );
command.Attributes.SetCombo( "D_DOF_TYPE", type );
command.Attributes.SetCombo( "D_PASS", 0 );
var composite = Material.FromShader( "postprocess_standard_dof.shader" );
command.Blit( composite );
}
InsertCommandList( command, Stage.AfterTransparent, 100, "Dof" );
}
private enum BlurPasses
{
CircleOfConfusion,
Blur,
RhomboidBlur,
};
private enum DoFTypes
{
BackBlur,
FrontBlur,
};
}