mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-08-01 08:18:20 -04:00
* Camera motion vectors for static geometry A full screen pass that creates a motion vector texture from depth + previous frame view projection. This is only good for objects that have moved due to camera motion, per object motion is not captured here - so this is good for static geometry that does not move, which is the majority of draw calls. Also this layer only executes if "WantsMotionVectors" is true in the pipeline's render attributes. * Add upscaling infrastructure and a simple bilinear stretch upscaler For stretch upscaler, the scene renders into a low-resolution RT, then is upscaled to display resolution before post-processing. * Add FSR upscaler (non temporal) * Add FSR3 upscaler (temporal) Temporal upscaler using FSR3 with explicitly no frame generation Maps to the standard resolution scale factors: * Native - 1x * Quality - 1.5x * Balanced - 1.7x * Performance - 2x * Ultra Performance - 3x * Add all the upscaler cvars to the settings menu https://files.facepunch.com/matt/1b1311b1/sbox_jIRwaBdWwJ.png * Add FidelityFX SDK to third-party legal notices * Add FSR3 reactive mask for viewmodel and overlay objects * Compiled shaders
114 lines
3.2 KiB
C#
114 lines
3.2 KiB
C#
using NativeEngine;
|
|
|
|
namespace Sandbox.Rendering;
|
|
|
|
/// <summary>
|
|
/// Renders objects matching the given flags in depth-only mode to a separate depth target.
|
|
/// Pixels where reactive geometry exists will have depth > 0 (reverse-Z clear = 0).
|
|
/// Multiple instances can share the same depth RT to accumulate different object types.
|
|
/// </summary>
|
|
internal class ReactiveDepthLayer : RenderLayer
|
|
{
|
|
public ReactiveDepthLayer( string name, SceneObjectFlags requiredFlags, bool clearDepth = true )
|
|
{
|
|
Name = name;
|
|
LayerType = SceneLayerType.DepthPrepass;
|
|
ShaderMode = "Depth";
|
|
|
|
Flags |= LayerFlags.NeverRemove | LayerFlags.IsDepthRenderingPass;
|
|
|
|
ObjectFlagsRequired = requiredFlags;
|
|
ObjectFlagsExcluded = SceneObjectFlags.IsLight;
|
|
|
|
if ( clearDepth )
|
|
ClearFlags = ClearFlags.Depth;
|
|
}
|
|
|
|
public void Setup( SceneViewRenderTargetHandle depthHandle )
|
|
{
|
|
DepthAttachment = depthHandle;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts the reactive depth target into an R16F reactive mask for FSR3.
|
|
/// Any pixel with depth > 0 (written by a reactive object) outputs 1.0.
|
|
/// </summary>
|
|
internal class ReactiveMaskLayer : ProceduralRenderLayer
|
|
{
|
|
static Material MaskMaterial = Material.FromShader( "shaders/reactive_mask_generate.shader" );
|
|
|
|
RenderTarget ReactiveMaskRT;
|
|
RenderTarget ReactiveDepthRT;
|
|
|
|
/// <summary>
|
|
/// The reactive mask color RT handle, for additional layers to render into.
|
|
/// </summary>
|
|
public SceneViewRenderTargetHandle ReactiveMaskHandle { get; private set; }
|
|
|
|
public ReactiveMaskLayer()
|
|
{
|
|
Name = "Reactive Mask";
|
|
Flags |= LayerFlags.NeverRemove
|
|
| LayerFlags.DoesntModifyDepthStencilBuffer;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Allocates the shared depth RT and the output mask RT.
|
|
/// Returns the depth handle that ReactiveDepthLayer instances should render into.
|
|
/// </summary>
|
|
public SceneViewRenderTargetHandle Setup( RenderViewport viewport, ISceneView view )
|
|
{
|
|
ReactiveDepthRT = RenderTarget.GetTemporary(
|
|
(int)viewport.Rect.Width,
|
|
(int)viewport.Rect.Height,
|
|
colorFormat: ImageFormat.None,
|
|
depthFormat: ImageFormat.D32,
|
|
targetName: "ReactiveDepth" );
|
|
|
|
ReactiveMaskRT = RenderTarget.GetTemporary(
|
|
(int)viewport.Rect.Width,
|
|
(int)viewport.Rect.Height,
|
|
colorFormat: ImageFormat.R16F,
|
|
depthFormat: ImageFormat.None,
|
|
targetName: "ReactiveMask" );
|
|
|
|
var reactiveDepthHandle = ReactiveDepthRT.ToDepthHandle( view );
|
|
|
|
ColorAttachment = ReactiveMaskRT.ToColorHandle( view );
|
|
ReactiveMaskHandle = ColorAttachment;
|
|
ClearFlags = ClearFlags.Color;
|
|
|
|
RenderTargetAttributes["ReactiveDepth"] = reactiveDepthHandle;
|
|
|
|
view.GetRenderAttributesPtr().SetTextureValue( "ReactiveMask", ReactiveMaskRT.ColorTarget.native, -1 );
|
|
|
|
return reactiveDepthHandle;
|
|
}
|
|
|
|
internal override void OnRender()
|
|
{
|
|
Graphics.Blit( MaskMaterial );
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Debug visualization: blits the reactive mask over the scene as a red overlay.
|
|
/// </summary>
|
|
internal class ReactiveMaskDebugLayer : ProceduralRenderLayer
|
|
{
|
|
static Material DebugMaterial = Material.FromShader( "shaders/reactive_mask_debug.shader" );
|
|
|
|
public ReactiveMaskDebugLayer()
|
|
{
|
|
Name = "Reactive Mask Debug";
|
|
Flags |= LayerFlags.NeverRemove
|
|
| LayerFlags.DoesntModifyDepthStencilBuffer;
|
|
}
|
|
|
|
internal override void OnRender()
|
|
{
|
|
Graphics.Blit( DebugMaterial );
|
|
}
|
|
}
|