Code/CCSBoxBlur.cs

A post-processing component that applies a box (or circular) blur to the rendered image. It exposes properties for blur radius, multiplier, aspect correction and circular mode, packs those into shader attributes, loads a shader material and issues a Blit call to run the effect.

Native Interop
using Sandbox;
using System;


using Sandbox;
using Sandbox.Rendering;

/// <summary>
/// Box-Blur filter with various options, looks OK, not very performant.
/// </summary>
[Title( "Simple Blur" )]
[Category( "Post Processing" )]
[Icon( "blur_linear" )]
public sealed class CCSBoxBlur : BasePostProcess<CCSBoxBlur>
{
    /// <summary>
    /// size of the box used to blur the image
    /// </summary>
    [Property, Title("Blur Radius"), Range(0.0f, 50.0f, 1, true)]
    public float bRadius { get; set; } = 0.0f;

    /// <summary>
    /// Use this to make the blur larger, but lower quality
    /// </summary>
    [Property, Title("Blur Size"), Range(0.5f, 50.0f, 0, true)]
    public float bMulti { get; set; } = 2.0f;

    /// <summary>
    /// Will actually make the blur a perfect square instead of it stretching to your screen's aspect ratio.
    /// </summary>
    [Property, Title("Don't Stretch")]
    public bool bAspect { get; set; }

    /// <summary>
    /// The blur will be generated using a circle instead of a box.
    /// </summary>
    [Property, Title("Circularize")]
    public bool bCircle { get; set; }

    private bool bLoop = false;

    public override void Render()
    {
        // Числовые значения через GetWeighted — поддерживает блендинг в PostProcess Volume
        float bRadiusW = GetWeighted(x => x.bRadius);
        float bMultiW = GetWeighted(x => x.bMulti);

        // Bool берем напрямую — GetWeighted с bool вызывает NullReferenceException
        bool bAspectW = bAspect;
        bool bCircleW = bCircle;
        bool bLoopW = bLoop;

        // Передаем значения в шейдер
        Attributes.Set("bRadius", bRadiusW);
        Attributes.Set("bMulti", bMultiW);

        // Bool передаем как int (0/1) для надежной работы с HLSL
        Attributes.Set("bAspect", bAspectW ? 1 : 0);
        Attributes.Set("bCircle", bCircleW ? 1 : 0);
        Attributes.Set("bLoop", bLoopW ? 1 : 0);

        // Загружаем материал с проверкой на null
        var material = Material.FromShader("postprocess/ccs_boxfilter.shader");
        if (material == null)
        {
            Log.Warning("CCSBoxBlur: Material 'materials/postprocess/ccs_boxblur.vmat' not found!");
            return;
        }

        // Применяем эффект через современный Blit API
        // Приоритет 2001 перенесен из оригинального кода
        var blit = BlitMode.WithBackbuffer(material, Stage.AfterPostProcess, 2001, true);
        Blit(blit, "CCSBoxBlur");
    }
}