Files
sbox-public/engine/Sandbox.Engine/Systems/UI/Render/UIRenderer.cs
Matt Stevens 0ca4a90e28 UI panels that use backdrops can be batched (#4735)
* Panels with backdrop filters are batched now and reuse the same frame grab, break batch on Z groups

Before: https://files.facepunch.com/matt/1b0311b1/sbox_HB6vN6Reo6.png
After: https://files.facepunch.com/matt/1b0311b1/sbox_gFO4enjxiv.png

* Save backdropGrabActive, panel children can't share a backdrop (if they use one) since they won't contain the fresh quad, but siblings can use the same backdrop still

Fixes overlapping blurred panels using the original frame grab e.g Sandbox:

Before: https://files.facepunch.com/matt/1b0311b1/sbox_M8xXVyxcsF.png
After: https://files.facepunch.com/matt/1b0311b1/sbox_RePJDF3HWW.png

(Even though Sandbox shouldn't be layering 3 blurred panels on top of each other)
2026-05-04 09:05:14 +01:00

57 lines
1.7 KiB
C#

using Sandbox.Rendering;
using System.Runtime.InteropServices;
namespace Sandbox.UI;
/// <summary>
/// Renders descriptors that can't go through the instanced batch path.
/// Backdrops need framebuffer grabs.
/// </summary>
internal static class UIRenderer
{
internal static void Draw( Span<BackdropDrawDescriptor> descriptors, CommandList commandList, bool reuseGrab = false )
{
for ( int i = 0; i < descriptors.Length; i++ )
{
ref var desc = ref descriptors[i];
var attributes = commandList.Attributes;
attributes.Set( "HasInverseScissor", 0 );
attributes.SetCombo( "D_LAYERED", desc.IsLayered ? 1 : 0 );
attributes.Set( "BoxPosition", desc.PanelRect.Position );
attributes.Set( "BoxSize", desc.PanelRect.Size );
attributes.Set( "BorderRadius", desc.BorderRadius );
attributes.Set( "Brightness", desc.Brightness );
attributes.Set( "Contrast", desc.Contrast );
attributes.Set( "Saturate", desc.Saturate );
attributes.Set( "Sepia", desc.Sepia );
attributes.Set( "Invert", desc.Invert );
attributes.Set( "HueRotate", desc.HueRotate );
attributes.Set( "BlurScale", desc.BlurScale );
attributes.SetCombo( "D_BLENDMODE", desc.OverrideBlendMode );
if ( !reuseGrab )
{
attributes.GrabFrameTexture( "FrameBufferCopyTexture", Graphics.DownsampleMethod.GaussianBlur );
PanelRenderer.Stats.FrameGrabs++;
}
commandList.DrawQuad( desc.PanelRect, Material.UI.BackdropFilter, Color.White.WithAlpha( desc.Opacity ) );
}
var reset = commandList.Attributes;
reset.Set( "Brightness", 1.0f );
reset.Set( "Contrast", 1.0f );
reset.Set( "Saturate", 1.0f );
reset.Set( "Sepia", 0.0f );
reset.Set( "Invert", 0.0f );
reset.Set( "HueRotate", 0.0f );
reset.Set( "BlurScale", 0.0f );
}
}