CCSPerspectiveShift.cs

A post-processing effect component for s&box that applies a simple perspective shift to the rendered image. It exposes upper/lower scale and a smoothing boolean, passes weighted values to a shader, loads the shader material, and issues a Blit call to apply the effect.

Native Interop
using Sandbox;
using System;


using Sandbox;
using Sandbox.Rendering;

/// <summary>
/// Shift the perspective of the image.(very basic)
/// </summary>
[Title( "Perspective Shift" )]
[Category( "Post Processing" )]
[Icon( "grid_4x4" )]
public sealed class CCSPerspectiveShift : BasePostProcess<CCSPerspectiveShift>
{
    /// <summary>
    /// Scale the upper edge of the image to simulate perspective shift
    /// </summary>
    [Property, Title("Upper Scale"), Range(0.0f, 1.0f, 0, true)]
    public float dUpper { get; set; } = 0.0f;

    /// <summary>
    ///  Scales the lower edge, disables upper scale when above 0.
    /// </summary>
    [Property, Title("Lower Scale"), Range(0.0f, 1.0f, 0, true)]
    public float dLower { get; set; } = 0.0f;

    /// <summary>
    /// Smooth the resulting image.
    /// </summary>
    // ИСПРАВЛЕНО: убран Range у bool, оставлен только Property
    [Property, Title("Smooth")]
    public bool Filter { get; set; }

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

        // Bool берем напрямую — GetWeighted с bool вызывает NullReferenceException
        bool filterW = Filter;

        // Передаем значения в шейдер
        Attributes.Set("dUpper", dUpperW);
        Attributes.Set("dLower", dLowerW);

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

        // Загружаем шейдер с проверкой на null
        var shader = Material.FromShader("postprocess/ccs_perspectiveshift.shader");
        if (shader == null)
        {
            Log.Warning("CCSPerspectiveShift: Shader 'postprocess/ccs_perspectiveshift.shader' not found!");
            return;
        }

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