Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ntsc-rs/ntsc-rs/llms.txt

Use this file to discover all available pages before exploring further.

ntsc-rs exposes every aspect of its analog video simulation through a single, unified settings structure. Whether you interact with the effect through the desktop GUI, a host-plugin (After Effects, OpenFX), or the command-line tool, every knob and switch maps directly to a field of the NtscEffect Rust struct. Understanding this structure lets you craft precise JSON presets, automate parameter sweeps, and understand exactly what each control is doing under the hood.

The NtscEffect struct

Every parameter is a public field on NtscEffect. The struct is defined in ntscrs::settings::standard and implements Default, so omitted fields always fall back to sensible starting values.
pub struct NtscEffect {
    pub random_seed: i32,
    pub use_field: UseField,
    pub filter_type: FilterType,
    pub input_luma_filter: LumaLowpass,
    pub chroma_lowpass_in: ChromaLowpass,
    pub chroma_demodulation: ChromaDemodulationFilter,
    pub luma_smear: f32,
    pub composite_sharpening: f32,
    pub video_scanline_phase_shift: PhaseShift,
    pub video_scanline_phase_shift_offset: i32,
    pub head_switching: SettingsBlock<HeadSwitchingSettings>,
    pub tracking_noise: SettingsBlock<TrackingNoiseSettings>,
    pub composite_noise: SettingsBlock<FbmNoiseSettings>,
    pub ringing: SettingsBlock<RingingSettings>,
    pub luma_noise: SettingsBlock<FbmNoiseSettings>,
    pub chroma_noise: SettingsBlock<FbmNoiseSettings>,
    pub snow_intensity: f32,
    pub snow_anisotropy: f32,
    pub chroma_phase_noise_intensity: f32,
    pub chroma_phase_error: f32,
    pub chroma_delay_horizontal: f32,
    pub chroma_delay_vertical: i32,
    pub vhs_settings: SettingsBlock<VHSSettings>,
    pub chroma_vert_blend: bool,
    pub chroma_lowpass_out: ChromaLowpass,
    pub scale: SettingsBlock<ScaleSettings>,
}

SettingsBlock<T>

Several parameters are wrapped in SettingsBlock<T>. This type acts like a typed Option<T>: it pairs an enabled: bool flag with a settings: T value. When enabled is false the entire sub-section is skipped at render time, but the inner settings are preserved so that toggling it back on restores your previous values.
pub struct SettingsBlock<T> {
    pub enabled: bool,
    pub settings: T,
}
In JSON presets the enabled flag is written as the group’s own key (a boolean), and each child setting is a sibling key at the top level of the object.

JSON preset format

Presets are flat JSON objects. Every setting — including those nested inside SettingsBlock groups — is serialized as a top-level key. Enum variants are stored as their integer discriminant. The object must contain "version": 1.
{
  "version": 1,
  "random_seed": 0,
  "use_field": 4,
  "filter_type": 1,
  "vhs_settings": true,
  "vhs_tape_speed": 2,
  "composite_noise": true,
  "composite_noise_intensity": 0.05,
  "composite_noise_frequency": 0.5,
  "composite_noise_detail": 1
}
Keys use the internal serialization name (shown in the setting_id! macros), which may differ slightly from the Rust field name. For example, composite_sharpening serializes as "composite_preemphasis" and scale.settings.horizontal_scale serializes as "bandwidth_scale". The correct key names are documented on each sub-page.

Enum integer mappings

All enum parameters are stored as unsigned integers in JSON. The tables below list the discriminant for each variant.
EnumVariantInteger
UseFieldAlternating0
UseFieldUpper1
UseFieldLower2
UseFieldBoth3
UseFieldInterleavedUpper4
UseFieldInterleavedLower5
FilterTypeConstantK0
FilterTypeButterworth1
LumaLowpassNone0
LumaLowpassBox1
LumaLowpassNotch2
ChromaLowpassNone0
ChromaLowpassLight1
ChromaLowpassFull2
ChromaDemodulationFilterBox0
ChromaDemodulationFilterNotch1
ChromaDemodulationFilterOneLineComb2
ChromaDemodulationFilterTwoLineComb3
PhaseShiftDegrees00
PhaseShiftDegrees901
PhaseShiftDegrees1802
PhaseShiftDegrees2703
VHSTapeSpeedNONE0
VHSTapeSpeedSP1
VHSTapeSpeedLP2
VHSTapeSpeedEP3

GUI modes: Easy vs. Standard

The ntsc-rs GUI offers two configuration modes that trade completeness for simplicity. Easy Mode presents a condensed set of sliders that map to an EasyMode struct. Under the hood, each easy-mode value is converted to a full NtscEffect via a fixed mapping — for example, a single “VHS Head Switching” slider drives height, offset, and horiz_shift simultaneously. Easy Mode is ideal for quick experimentation. Its JSON keys are prefixed with ez_. Standard Mode (the default for presets) exposes every field of NtscEffect directly. This is what the sub-pages below document.
JSON presets saved from Easy Mode are not compatible with Standard Mode and vice versa. Use the matching import button in the GUI.

Parameter reference pages

Luma & Chroma

Input filters, demodulation, smearing, sharpening, phase shift, and color delay.

VHS

Tape speed quality, chroma loss, edge wave distortion, and high-frequency sharpening.

Noise

Composite, luma, and chroma FBM noise; snow intensity and anisotropy; chroma phase noise.

Artifacts

Head-switching glitches, ringing, tracking noise bands, and the global random seed.

Build docs developers (and LLMs) love