CCSLensDistortion.cs

A post-processing effect component that applies lens distortion to the camera image. It exposes properties for barrel and pincushion distortion, crop, smoothing, circularization and a Panini mode, passes weighted values to a shader, and performs a blit using a named shader.

Native Interop
using Sandbox;
using System;
using Sandbox.Rendering;


/// <summary>
/// Realistic Camera Lens Distortion.
/// </summary>
[Title( "Lens Distortion" )]
[Category( "Post Processing" )]
[Icon( "panorama_photosphere_select" )]
public sealed class CCSLensDistortion : BasePostProcess<CCSLensDistortion>
{
	
    // future todo: create other shader which takes texture input of a dudv map (flowmap) or something else so you can 
    // input real life lens distortion profiles(?) and other shapes for cool screen effects.

    /// <summary>
    /// Amount of Barrel (outward bending) Lens Distortion 
    /// </summary>
    [Property, Title("Barrel Distortion"), Range(0, 0.5f, 0, true)]
    public float dBarrel { get; set; } = 0.0f;

    /// <summary>
    ///  Amount of Pincushion (inward bending) Lens Distortion 
    /// </summary>
    [Property, Title("Pincushion Distortion"), Range(0, 0.5f, 0, true)]
    public float dPin { get; set; } = 0.0f;

    /// <summary>
    /// Zoom in on the image to hide repeating effect. Non-circular max barrel distortion requires only 200% (2X crop) while Circular max requires 420% to fully hide the edges.
    /// </summary>
    [Property, Title("Crop"), Range(100.0f, 420.0f, 0, true)]
    public float CropIn { get; set; } = 1.0f;

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

    /// <summary>
    /// Forces the distortion to be perfectly circular. This more closely simulates non anamorphic lenses but requires more crop.
    /// </summary>
    // ИСПРАВЛЕНО: убран Range у bool
    [Property, Title("Circularize")]
    public bool dCircle { get; set; }

    /// <summary>
    /// Uses the built-in sbox panini perspective mode, which maintains vertical lines in wide images. In this mode barrel and pin sliders become the strength of the effect. Not a lens-effect but interesting. 
    /// </summary>
    // ИСПРАВЛЕНО: убран Range у bool
    [Property, Title("Panini")]
    public bool dPanini { get; set; }

    public override void Render()
    {
        // Числовые значения через GetWeighted — поддерживает блендинг в PostProcess Volume
        float dBarrelW = GetWeighted(x => x.dBarrel);
        float dPinW = GetWeighted(x => x.dPin);
        float CropInW = GetWeighted(x => x.CropIn);

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

        // Передаем значения в шейдер
        Attributes.Set("dBarrel", dBarrelW);
        Attributes.Set("dPin", dPinW);
        Attributes.Set("CropIn", CropInW);

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

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

        // Применяем эффект через современный Blit API
        var blit = BlitMode.WithBackbuffer(shader, Stage.AfterPostProcess, 1001, true);
        Blit(blit, "CCSLensDistortion");
    }
}