test/FisheyeEffect.cs
/// <summary>
/// GoPro-style fisheye lens distortion effect. Simulates the barrel distortion,
/// chromatic aberration, and heavy vignetting of a wide-angle action camera lens.
/// Attach to a camera or use inside a PostProcessVolume.
/// </summary>
[Title( "Fisheye Lens" )]
[Category( "Post Processing" )]
[Icon( "camera" )]
public sealed class FisheyeEffect : BasePostProcess<FisheyeEffect>
{
[Property, Range( 0, 1 ), Group( "General" )]
public float Intensity { get; set; } = 1.0f;
/// <summary>
/// Barrel distortion strength. Higher values push more pixels outward
/// from center, creating the characteristic fisheye bulge.
/// </summary>
[Property, Range( 0, 2 ), Group( "Distortion" )]
public float BulgeAmount { get; set; } = 0.6f;
/// <summary>
/// Zoom factor to crop into the distorted image and hide the black
/// borders at the edges. 1.0 = no zoom, higher = more cropped.
/// </summary>
[Property, Range( 0.5f, 2 ), Group( "Distortion" )]
public float Zoom { get; set; } = 1.0f;
/// <summary>
/// Per-channel radial aberration. Separates R/G/B at different distortion
/// strengths so colors fringe toward the edges, like a real wide-angle lens.
/// </summary>
[Property, Range( 0, 1 ), Group( "Aberration" )]
public float ChromaticAberration { get; set; } = 0.3f;
/// <summary>
/// Lateral (transverse) chromatic dispersion. Shifts red and blue channels
/// horizontally in opposite directions for additional color fringing.
/// </summary>
[Property, Range( 0, 1 ), Group( "Aberration" )]
public float Dispersion { get; set; } = 0.1f;
/// <summary>
/// Edge darkening intensity. Wide-angle lenses lose significant light
/// toward the frame edges due to the steep angle of incidence.
/// </summary>
[Property, Range( 0, 1 ), Group( "Vignette" )]
public float VignetteIntensity { get; set; } = 0.5f;
/// <summary>
/// How circular the vignette is. 1.0 = perfectly round, 0.0 = follows
/// the rectangular aspect ratio of the frame.
/// </summary>
[Property, Range( 0, 1 ), Group( "Vignette" )]
public float VignetteRoundness { get; set; } = 0.8f;
public override void Render()
{
float intensity = GetWeighted( x => x.Intensity );
if ( intensity.AlmostEqual( 0.0f ) )
{
return;
}
Attributes.Set( "intensity", intensity );
Attributes.Set( "bulgeAmount", GetWeighted( x => x.BulgeAmount ) );
Attributes.Set( "zoom", GetWeighted( x => x.Zoom ) );
Attributes.Set( "chromaticAberration", GetWeighted( x => x.ChromaticAberration ) );
Attributes.Set( "dispersion", GetWeighted( x => x.Dispersion ) );
Attributes.Set( "vignetteIntensity", GetWeighted( x => x.VignetteIntensity ) );
Attributes.Set( "vignetteRoundness", GetWeighted( x => x.VignetteRoundness ) );
// Render after built-in post-processing effects, same stage as VHS/NTSC
var shader = Material.FromShader( "test/shaders/postprocess/pp_fisheye.shader" );
var blit = BlitMode.WithBackbuffer( shader, Sandbox.Rendering.Stage.AfterPostProcess, 300, false );
Blit( blit, "Fisheye Lens" );
}
}