Skip to main content

Optical effects library — lens flares, camera optics, atmospheric/diffusion, stylized optics

Project description

optic-fx

Optical effects for video — lens flares, camera optics, atmospheric layers, and stylized optics. 86 named effects. Frame-accurate. Compositable.

PyPI CI


Install

pip install optic-fx

Requires ffmpeg >= 6.0 on PATH.

Extras:

Extra What it adds Approx size
pip install optic-fx base: flares, optics, atmospherics, stylized ~80 MB
pip install optic-fx[advanced] scikit-image — higher quality atmospheric noise ~120 MB
pip install optic-fx[overlay] web-overlay + Playwright Chromium — SVG-rendered flares ~230 MB
pip install optic-fx[all] overlay + advanced ~270 MB

The [overlay] extra installs Playwright Chromium. Most pipelines do not need it — the PIL fallback is used automatically when web-overlay is absent.


5-minute tour

Apply a named effect to a clip:

from optic_fx import apply_optic

apply_optic(
    video="raw.mp4",
    effect="anamorphic_lens_flare_gold",
    output="flared.mp4",
)

Add a dense fog layer with animated drift:

from optic_fx import render_atmosphere

render_atmosphere(
    video="raw.mp4",
    effect="fog_overlay_dense",
    output="foggy.mp4",
    density=0.8,
    movement_speed=0.3,
)

Render a flare as a standalone overlay for compositing in another tool:

from optic_fx import render_flare

render_flare(
    effect="anamorphic_lens_flare_subtle",
    width=1920,
    height=1080,
    position=(0.7, 0.3),   # normalized (x, y) of the flare origin
    duration=2.0,
    output="flare_overlay.webm",
)

The 86 effects

lens_flares_and_glow (25)

Slug Display name
anamorphic_lens_flare_subtle Anamorphic Lens Flare (Subtle)
anamorphic_lens_flare_intense Anamorphic Lens Flare (Intense)
anamorphic_lens_flare_gold Anamorphic Lens Flare (Gold)
sci_fi_aggressive_flare Sci-Fi Aggressive Flare
sun_glint_small Sun Glint (Small)
sun_glint_ribbon Sun Glint (Ribbon)
lens_orb_flare_single Lens Orb Flare (Single)
lens_orb_flare_chain Lens Orb Flare (Chain)
rainbow_prism_flare Rainbow Prism Flare
glow_bloom_soft Glow Bloom (Soft)
glow_bloom_intense Glow Bloom (Intense)
soft_diffusion_pro_mist Soft Diffusion (Pro Mist)
soft_diffusion_white_diffusion Soft Diffusion (White Diffusion)
halation Halation
halation_warm Halation (Warm)
neon_glow_magenta Neon Glow (Magenta)
neon_glow_cyan Neon Glow (Cyan)
neon_glow_warm Neon Glow (Warm)
starburst_filter_4_point Starburst Filter (4 Point)
starburst_filter_8_point Starburst Filter (8 Point)
dirty_lens Dirty Lens
bokeh_bloom_circular Bokeh Bloom (Circular)
bokeh_bloom_hexagonal Bokeh Bloom (Hexagonal)
bokeh_bloom_anamorphic_oval Bokeh Bloom (Anamorphic Oval)
lens_breathing Lens Breathing

camera_optics (18)

Slug Display name
barrel_distortion_gentle Barrel Distortion (Gentle)
barrel_distortion_strong Barrel Distortion (Strong)
pincushion_distortion_gentle Pincushion Distortion (Gentle)
pincushion_distortion_strong Pincushion Distortion (Strong)
vignette_subtle Vignette (Subtle)
vignette_heavy Vignette (Heavy)
vignette_rectangular Vignette (Rectangular)
lens_warp_organic Lens Warp (Organic)
lens_warp_geometric Lens Warp (Geometric)
soft_corners Soft Corners
microscope_lens Microscope Lens
telephoto_compression_moderate Telephoto Compression (Moderate)
telephoto_compression_extreme Telephoto Compression (Extreme)
underwater_lens_ripple Underwater Lens (Ripple)
underwater_lens_deep Underwater Lens (Deep)
prism_refraction_horizontal Prism Refraction (Horizontal)
prism_refraction_radial Prism Refraction (Radial)
prism_refraction_stacked Prism Refraction (Stacked)

atmospheric_and_diffusion (25)

Slug Display name
cinematic_haze_morning Cinematic Haze (Morning)
cinematic_haze_evening Cinematic Haze (Evening)
fog_overlay_light Fog Overlay (Light)
fog_overlay_dense Fog Overlay (Dense)
fog_overlay_ground_only Fog Overlay (Ground Only)
smoke_diffusion_stage Smoke Diffusion (Stage)
smoke_diffusion_cinematic Smoke Diffusion (Cinematic)
heat_haze_desert Heat Haze (Desert)
heat_haze_urban Heat Haze (Urban)
rain_streak_refraction_light Rain Streak Refraction (Light)
rain_streak_refraction_heavy Rain Streak Refraction (Heavy)
snow_glow Snow Glow
dust_storm_dry Dust Storm (Dry)
dust_storm_apocalyptic Dust Storm (Apocalyptic)
dream_fog Dream Fog
moonlight_mist Moonlight Mist
fire_smoke_warm Fire Smoke (Warm)
fire_smoke_drifting Fire Smoke (Drifting)
volumetric_atmosphere_forest Volumetric Atmosphere (Forest)
volumetric_atmosphere_cathedral Volumetric Atmosphere (Cathedral)
stage_spotlight_haze_concert Stage Spotlight Haze (Concert)
stage_spotlight_haze_theatrical Stage Spotlight Haze (Theatrical)
window_diffusion Window Diffusion
clouded_lens_light Clouded Lens (Light)
clouded_lens_heavy Clouded Lens (Heavy)

stylized_optical (18)

Slug Display name
kaleidoscope_prism_triangular Kaleidoscope Prism (Triangular)
kaleidoscope_prism_hexagonal Kaleidoscope Prism (Hexagonal)
glass_refraction Glass Refraction
crystal_refraction Crystal Refraction
mirror_hall Mirror Hall
oil_smear_lens Oil Smear Lens
dream_prism Dream Prism
heatwave_blur Heatwave Blur
tunnel_vision_subtle Tunnel Vision (Subtle)
tunnel_vision_claustrophobic Tunnel Vision (Claustrophobic)
psychedelic_refraction Psychedelic Refraction
security_monitor_glow Security Monitor Glow
holographic_reflections Holographic Reflections
mirror_split_horizontal Mirror Split (Horizontal)
mirror_split_vertical Mirror Split (Vertical)
shattered_glass Shattered Glass
retro_tv_curvature Retro TV Curvature
acid_bloom Acid Bloom

Engines

Four base engines implement all 86 effects. Each engine handles a family of variants.

Engine Effects What it does
flare_glow 25 Anamorphic streaks, orb artifacts, glow bloom, halation, neon glow, starburst, bokeh
optical_distortion 18 Geometric remapping via OpenCV cv2.remap — barrel, pincushion, vignette, lens warp, prism
atmospheric_layer 25 Procedural noise layers — fog, smoke, haze, dust, rain streaks, volumetric light
stylized_optical 18 Kaleidoscope, mirror, glass/crystal refraction, CRT curvature, psychedelic transforms

The resolver maps each slug to (base_engine, variant, params) from data/effects_catalog.json. Engines are instantiated lazily. Optical distortion remap arrays are computed once and cached. Atmospheric noise is procedural numpy — no extra dependency at base install; [advanced] adds scikit-image for higher quality layering. Three flare effects use SVG templates rendered via [overlay]; without it a PIL approximation runs with a UserWarning.


OpticConfig

OpticConfig is a Pydantic model. All fields except effect have defaults.

from optic_fx import OpticConfig

cfg = OpticConfig(
    effect="anamorphic_lens_flare_gold",
    intensity=0.9,
    position=(0.75, 0.25),
    blend_mode="screen",
)
Field Type Default Notes
effect str required Slug from the catalog
intensity float 0.75 Overall effect strength
opacity float 1.0 Layer opacity before blend
blend_mode str "screen" screen, add, overlay, multiply, soft_light
seed int | None None Fix random seed for reproducible noise
start_time float 0.0 Seconds into the clip to start effect
duration float | None None Duration in seconds; None = full clip
in_animation str "none" fade_in or none
out_animation str "none" fade_out or none
position tuple[float, float] | None None Normalized (x, y) for flare origin
flare_color str | None None CSS color override for flare tint
follow_motion bool False Subtle motion-based flare drift
bloom_radius float 12.0 Bloom kernel radius in pixels
density float 0.5 Atmospheric layer opacity/thickness
movement_speed float 0.5 Animation speed for fog/smoke drift
depth_aware bool False Depth-map-weighted atmospheric composite (advanced)
color_tint str | None None CSS color tint for atmospheric layer
distortion_strength float 0.5 Geometric distortion amount
chromatic_separation float 0.0 Extra RGB fringing on distortion edges
video_codec str "libx264" Output video codec
audio_codec str "copy" Output audio handling

Extra fields are forbidden (extra="forbid") — unknown keys raise immediately.


CLI

Every subcommand accepts --help.

Apply an effect:

optic-fx apply --video raw.mp4 --effect anamorphic_lens_flare_gold --out flared.mp4

Render a standalone flare overlay (no input video):

optic-fx flare --effect anamorphic_lens_flare_subtle \
  --width 1920 --height 1080 --position 0.7,0.3 --duration 2 --out flare.webm

Pre-render an atmospheric layer:

optic-fx atmosphere --effect fog_overlay_dense --width 1920 --height 1080 --duration 10 --out fog.webm

Browse the catalog:

optic-fx list                                       # all 86, one slug per line
optic-fx list --category atmospheric_and_diffusion  # 25
optic-fx categories                                 # four category names
optic-fx info anamorphic_lens_flare_gold            # engine, variant, description

Preview an effect on a generated test frame:

optic-fx preview --effect kaleidoscope_prism_hexagonal --out preview.mp4

Print the OpticConfig JSON schema: optic-fx schema --pretty


Composition with color-fx, video-fx

optic-fx is one of three siblings. Each handles a distinct layer of the finishing pass.

# video-fx → optic-fx → color-fx pipeline
from optic_fx import apply_optic_chain
apply_optic_chain(
    video="dof.mp4",       # output from video-fx
    effects=[
        {"effect": "barrel_distortion_gentle"},
        {"effect": "anamorphic_lens_flare_subtle", "position": (0.7, 0.3)},
        {"effect": "halation_warm", "intensity": 0.5},
        {"effect": "vignette_subtle"},
    ],
    output="optic.mp4",    # feed into color-fx next
)

Pre-render a long atmospheric layer once, reuse across many shots:

from optic_fx import pre_render_atmosphere, composite_atmosphere

atmo = pre_render_atmosphere(
    effect="volumetric_atmosphere_cathedral",
    width=1920, height=1080, duration=10.0,
    output="atmo_cathedral.webm",
)
for shot in shots:
    composite_atmosphere(shot, atmo, output=f"{shot.stem}_atmo.mp4")

The siblings share no runtime state and can run in any order. Each installs independently.


What this is NOT

optic-fx is not a node-based compositor. No GUI, no real-time preview, no timeline. It processes clips, not projects.

The 9 effects overlapping with video-fx — Fisheye Lens, Tilt Shift, Rack Focus, Depth of Field, Chromatic Aberration, Rolling Shutter, Light Leak, God Rays, Underwater Caustics — are deliberately absent. Use the video-fx versions for those.

Atmospheric layers are procedurally generated, not physically simulated. Fog does not respond to scene geometry. The depth_aware field requires an external depth map — optic-fx does not produce depth maps.


Provenance

Built at Trollfabriken AITrix AB for the CineForge pipeline's anamorphic flare and atmospheric work, AIMOS Insight municipal report visual polish, SocKartan civic transparency segments, and the Timelock Film AB festival slate's optical finishing pass.

Source: https://github.com/tomastimelock/optic-fx — License: MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

optic_fx-0.1.0.tar.gz (161.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

optic_fx-0.1.0-py3-none-any.whl (77.2 kB view details)

Uploaded Python 3

File details

Details for the file optic_fx-0.1.0.tar.gz.

File metadata

  • Download URL: optic_fx-0.1.0.tar.gz
  • Upload date:
  • Size: 161.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for optic_fx-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d1d8ec12ac5bc29f9fd05341ac60f98d19319b9c6ddb0becea72387fd7b0a4dd
MD5 0a524f042d67396fc889ceb32c5ee753
BLAKE2b-256 6cf44146e23bccabc87a7d7d9b1bd1b11cd4ee1216fedd92104a2a5c7c5d75c1

See more details on using hashes here.

Provenance

The following attestation bundles were made for optic_fx-0.1.0.tar.gz:

Publisher: release.yml on tomastimelock/optic-fx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file optic_fx-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: optic_fx-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 77.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for optic_fx-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 52d568eef1fbe8ffb04ee858cba6e13ac48c3b904b35f6044176d09ac14f3cba
MD5 961fcca9eb5e8bb4fa7f51ceff6e75fd
BLAKE2b-256 2a63b6fa0ae7e044aa1a606b2d45efe7745936bca54a1fe6e9afbbb94c625b21

See more details on using hashes here.

Provenance

The following attestation bundles were made for optic_fx-0.1.0-py3-none-any.whl:

Publisher: release.yml on tomastimelock/optic-fx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page