User:The E: Difference between revisions

The E (talk | contribs)
New page: Hi there. This is The E, the most common letter in the english alphabet. What makes me special among all the E's out there is my unique capacity to troubleshoot FS2Open installs. No other ...
 
The E (talk | contribs)
No edit summary
Line 1: Line 1:
Hi there. This is The E, the most common letter in the english alphabet. What makes me special among all the E's out there is my unique capacity to troubleshoot FS2Open installs. No other letter of the english alphabet has ever done this. It is my sincere hope that other letters and numbers will follow my example and contribute to the community.
Hi there. This is The E, the most common letter in the english alphabet. What makes me special among all the E's out there is my unique capacity to troubleshoot FS2Open installs. No other letter of the english alphabet has ever done this. It is my sincere hope that other letters and numbers will follow my example and contribute to the community.
{{SCP_table}}
{{Tables}}
<!-- Editor's note: everything on this page is new in FS2 Open 26.1. Template:Table261
    did not exist when this was written (the newest was Template:Table250); once it
    is created, the intro line below can be replaced with the usual version box. -->
The '''lens_flares.tbl''' defines physically-based lens systems used to render camera lens flares for suns. Added in '''FS2 Open, 26.1'''.
Unlike the sprite-based '''$Flare:''' effect defined in [[Stars.tbl]], a lens system is described the way a real lens is: as a stack of glass surfaces. The engine traces that stack at table load and derives everything the flare needs from it, so the ghosts, their colours and the starburst all follow from the optics rather than from hand-placed sprites. A sun opts in with '''$Lens:''' in [[Stars.tbl]]; suns without it are unaffected, and a sun that has one no longer draws its sprite '''$Flare:'''.
FreeSpace Open ships a default lens_flares.tbl built into the engine, so the lens systems listed under [[#Default lens systems]] are always available even when no table file is present.
This table is one of the [[Modular Tables]] and can be extended with xxx-lens.tbm
==General Format==
*The table consists of a single section
*Begins with <nowiki>#</nowiki>'''Lens Systems'''
*Contains any number of lens systems, each beginning with '''$Name:'''
*Must be closed with <nowiki>#</nowiki>'''End'''
*A lens system in a .tbm that reuses the '''$Name:''' of an existing one replaces it completely, rather than adding a second lens of the same name
*'''Entries must appear in the order listed on this page.''' Options are read in sequence, so an option placed out of order is skipped, and one placed after the surface list will abort the parsing of the whole table
*Every option except '''$Name:''' is optional and falls back to the default given below
==Lens system options==
*'''$Name:'''
**The name used to refer to this lens system from '''$Lens:''' in [[Stars.tbl]] and from the lens [[#SEXPs|SEXPs]]
**Begins a new lens system
**Syntax: '''String'''
*'''$Entrance Pupil Radius:'''
**Radius of the front element, in millimetres. For a real design this is the focal length divided by twice the f-number
**Controls how large the ghosts are and how much light the lens gathers
**Syntax: '''Float''', default is '''10.0'''
*'''$Aperture Radius:'''
**Half-opening of the iris, in millimetres
**This is the setting that decides whether a ghost is lit at all: each ghost slides across the iris as the sun moves off-axis, by an amount that grows with the field angle and shrinks with this value, and a ghost that slides off the iris goes black. Too small a value confines the whole flare to a sun near the centre of the frame; too large a one shrinks the ghosts within the iris until the blades stop shaping them
**The physical value is the paraxial marginal-ray height where it crosses the '''$Stop:'''. The shipped lenses use 1.25x that
**Syntax: '''Float''', default is '''5.0'''
*'''$Sensor Width:'''
**Width of the film gate, in millimetres. 36.0 is a full 35mm frame
**Together with the focal length the engine derives from the surfaces, this sets how far the ghosts travel as the sun moves off-axis
**Syntax: '''Float''', default is '''36.0'''
*'''$Coating Wavelength:'''
**Wavelength in nanometres that the anti-reflection coating is tuned to, as a quarter-wave layer
**500-570 (green-centred, like real broadband coatings) gives the classic magenta and cyan ghost tints. '''0''' disables coatings entirely for an uncoated vintage look: much brighter, neutral grey ghosts
**Can be overridden per surface with '''+Coating Wavelength:'''
**Syntax: '''Float''', default is '''540.0'''
===Aperture===
A lens has exactly one aperture, and it drives both the ghosts and the starburst: every ghost is an image of the iris, and the starburst is that same image's diffraction pattern. Changing a blade count therefore restyles both at once.
*'''$Aperture Blades:'''
**Number of iris blades. Fewer than 3 gives a perfectly round iris
**Syntax: '''Integer''', default is '''6'''
*'''+Blade Rotation:'''
**Rotation of the iris, in degrees
**Syntax: '''Float''', default is '''0.0'''
*'''+Blade Curvature:'''
**How the blades bow. '''0''' leaves them straight, '''1''' bows their midpoints out to the corner radius for a circular iris, and negative values bow them inward into a star
**Syntax: '''Float''', -1.0 to 1.0, default is '''0.0'''
*'''+Edge Softness:'''
**Feathering of the iris edge, as a fraction of the iris radius
**The default is also the floor the engine clamps to (about a two pixel ramp, so the mask never aliases), so asking for less has no effect. Softening the edge visibly weakens the starburst spikes, because those come from the sharpness of that edge
**Syntax: '''Float''', default is '''0.0039'''
===Aperture imperfections===
Three optional layers darken the iris on top of the blade shape, for a dirty or damaged lens. All are off by default, and each takes its strength on the '''$'''-line followed by optional '''+''' sub-options.
Note that the starburst is normalized against its own brightest value, so these layers dim the core spikes as they add speckle around them, rather than only adding to what was already there.
*'''$Aperture Grating:'''
**A diffraction grating around the rim of the iris: radial ridges that throw extra spikes into the starburst
**Syntax: '''Float''', 0.0 to 1.0, strength; default is '''0.0''' (off)
**'''+Density:'''
***Fraction of the 360 possible ridges
***Syntax: '''Float''', 0.0 to 1.0, default is '''0.5'''
**'''+Length:'''
***How far in from the rim the ridges reach, as a fraction of the iris radius
***Syntax: '''Float''', 0.0 to 1.0, default is '''0.5'''
**'''+Width:'''
***Ridge width, as a duty cycle of the spacing between neighbouring ridges. Because it is relative, raising '''+Density:''' thins the ridges rather than merging them into a solid ring
***Syntax: '''Float''', 0.0 to 1.0, default is '''0.25'''
**'''+Softness:'''
***Syntax: '''Float''', default is '''0.0'''
*'''$Aperture Scratches:'''
**Scratches on the glass: randomly placed slivers
**Syntax: '''Float''', 0.0 to 1.0, strength; default is '''0.0''' (off)
**'''+Density:'''
***Fraction of the 1000 possible scratches
***Syntax: '''Float''', 0.0 to 1.0, default is '''0.5'''
**'''+Length:'''
***Syntax: '''Float''', 0.0 to 1.0, default is '''0.5'''
**'''+Width:'''
***Syntax: '''Float''', 0.0 to 1.0, default is '''0.25'''
**'''+Rotation:'''
***Direction the scratches run, in degrees
***Syntax: '''Float''', default is '''0.0'''
**'''+Rotation Variation:'''
***'''0''' leaves every scratch parallel, '''1''' scatters them completely
***Syntax: '''Float''', 0.0 to 1.0, default is '''0.0'''
**'''+Softness:'''
***Syntax: '''Float''', default is '''0.0'''
*'''$Aperture Dust:'''
**Dust on the glass: randomly placed specks
**Syntax: '''Float''', 0.0 to 1.0, strength; default is '''0.0''' (off)
**'''+Density:'''
***Fraction of the 1000 possible specks
***Syntax: '''Float''', 0.0 to 1.0, default is '''0.5'''
**'''+Radius:'''
***Syntax: '''Float''', 0.0 to 1.0, default is '''0.5'''
**'''+Softness:'''
***Syntax: '''Float''', default is '''0.0'''
===Starburst and brightness===
*'''$Starburst:'''
**Whether this lens draws the diffraction starburst around the sun itself. When it does, the sun's bitmap glow is skipped so the two do not stack
**Syntax: '''Boolean''', default is '''YES'''
*'''+Starburst Scale:'''
**Size of the starburst relative to the frame
**Syntax: '''Float''', default is '''1.0'''
*'''$Intensity:'''
**Overall brightness of this lens's flare
**This is the artistic control, and it is best set by comparing against the shipped lenses in the lab. An uncoated lens ('''$Coating Wavelength: 0''') reflects far more light and needs a much smaller value to stay in the same range
**Syntax: '''Float''', default is '''0.2'''
*'''$Max Ghosts:'''
**How many of the brightest ghosts to draw. A lens with many elements can produce several hundred, so this caps the cost
**Values above 63 are clamped to 63
**Syntax: '''Integer''', default is '''40'''
==Optical prescription==
The rest of the entry is the lens itself: an ordered list of the surfaces light passes through, front element first. Every ordered pair of surfaces produces one ghost, so the number and arrangement of surfaces is what gives a lens its character.
These numbers are "lens prescriptions" as published in lens patents and optical design references, and can be transcribed directly, one element per '''$Surface:''' row. Scaling all radii and thicknesses by the same factor changes the focal length. The engine derives the focal length, the sensor distance, the ghost list and each ghost's brightness and tint from this stack at table load.
*'''$Surface:'''
**One spherical glass surface
**Syntax: '''( Float, Float, Float )''' — curvature radius in millimetres, distance to the next surface in millimetres, and refractive index of the glass '''behind''' the surface ('''1.0''' being air)
**A positive radius means the surface bulges toward the front of the lens, with its centre of curvature behind it; a negative radius bulges toward the sensor; '''0''' is a flat surface
**The distance on the ''last'' surface is ignored: the engine places the sensor at the focus it computes
**'''+Abbe:'''
***Abbe V-number of the glass behind the surface, which sets how much it disperses. Crown glasses are around 55-60, dense flints around 30-40. This only drives the chromatic fringing of the ghosts, so approximate values are fine
***Syntax: '''Float''', default is '''0.0''' (no dispersion)
**'''+Coating Wavelength:'''
***Overrides '''$Coating Wavelength:''' for this surface alone
***Syntax: '''Float''', defaults to the lens's own value
*'''$Stop:'''
**Marks the iris plane. It does not refract or reflect; it is where the aperture sits in the stack
**Syntax: '''( Float )''', distance to the next surface in millimetres
**A lens without a '''$Stop:''' uses its middle surface as the aperture plane
A lens system needs at least two surfaces, and its prescription must actually form an image. One that does not (for instance an afocal stack) is dropped with a warning at table load and cannot be referenced.
==Using a lens==
*Assign a lens to a sun with '''$Lens:''' in [[Stars.tbl]], naming a lens system from this table
*Missions can override it and edit the iris at runtime with the lens [[#SEXPs|SEXPs]]
*The F3 lab (''Render options'' -> ''Lens flare options'') can swap the lens on each sun and adjust every aperture setting live, which is the practical way to dial in '''$Intensity:''' and the imperfection layers
*Only the first visible lens-equipped sun in a mission renders a flare
*The flare is suppressed in full-nebula missions, in subspace, in VR, when post-processing is disabled, and when the Planets/Backgrounds detail setting is off
===SEXPs===
*'''set-sun-lens''' — override which lens system a sun uses, or turn its flare off
*'''set-lens-aperture''' — blade count, rotation, curvature and edge softness
*'''set-lens-grating''', '''set-lens-scratches''', '''set-lens-dust''' — the imperfection layers
The aperture operators edit the lens system itself, so they affect every sun using that lens; the edits are undone when the mission ends. These operators are not sent over the network, so in multiplayer they only affect the host.
==Default lens systems==
The built-in table ships eight lens systems, transcribed from published patents. All of them leave the imperfection layers off.
*'''angenieux_100mm''' — double-Gauss cine prime, f/2.2. The reference prescription from the research this renderer is based on, and the lens the others are calibrated against
*'''tessar_50mm''' — classic Tessar, f/3.5. Few elements, so a sparse and subtle ghost set
*'''canon_70_200mm''' — modern multicoated telephoto zoom, f/2.8. The busiest shipped lens: a dense, strongly tinted ghost train
*'''kodak_100mm''' — symmetric double Gauss, f/3.8, single-coated. A sparse, orderly ghost set that stays stable as the sun moves off-axis
*'''leica_35mm''' — fast aspherical wide-angle prime, f/1.4. The shortest focal length shipped, so its ghosts sweep the furthest
*'''nikon_50_135mm''' — multicoated telephoto zoom, f/3.5
*'''color_heliar_105mm''' — uncoated vintage prime, f/3.5. The uncoated reference: few, large, colourless, obvious ghosts
*'''zeiss_master_prime_50mm''' — modern multicoated cine prime, T1.3. Many large, bright, strongly tinted ghosts; the closest to a contemporary cinema look
==Sample==
<pre>
#Lens Systems
; Classic Tessar, f/3.5, f=50mm, with a little dust on the front element.
$Name: tessar_50mm
$Entrance Pupil Radius: 7.0
$Aperture Radius: 5.0
$Sensor Width: 36.0
$Coating Wavelength: 520
$Aperture Blades: 8
+Blade Rotation: 0.0
+Blade Curvature: 0.3
$Aperture Dust: 0.4
+Density: 0.3
+Radius: 0.25
$Starburst: YES
+Starburst Scale: 0.8
$Intensity: 0.2
$Max Ghosts: 24
$Surface: ( 16.25, 2.90, 1.6116 )
+Abbe: 56.9
$Surface: ( -285.90, 0.29, 1.0 )
$Surface: ( -30.05, 1.20, 1.6053 )
+Abbe: 43.6
$Surface: ( 17.47, 1.38, 1.0 )
$Stop: ( 1.15 )
$Surface: ( 31.55, 1.20, 1.5123 )
+Abbe: 51.0
$Surface: ( 21.30, 3.50, 1.6116 )
+Abbe: 56.9
$Surface: ( -23.70, 40.0, 1.0 )
#End
</pre>
To use it, name it from a sun in [[Stars.tbl]]:
<pre>
#Stars
$Sun: SunWhite
$Sunglow: Sunglow01
$SunRGBI: 1.0 1.0 1.0 1.0
$Lens: tessar_50mm
#end
</pre>
[[Category:Tables]]

Revision as of 07:15, 26 July 2026

Hi there. This is The E, the most common letter in the english alphabet. What makes me special among all the E's out there is my unique capacity to troubleshoot FS2Open installs. No other letter of the english alphabet has ever done this. It is my sincere hope that other letters and numbers will follow my example and contribute to the community.


This feature requires FreeSpace Open
List of Tables and related code files
* Notes Modular Tables
** Notes tables which only use modular tables
Ai.tbl* /ai/aicode.cpp
Ai_profiles.tbl* /ai/ai_profiles.cpp
Animation.tbl** /model/modelanimation.cpp
Armor.tbl* /ship/ship.cpp
Asteroid.tbl* /asteroid/asteroid.cpp
Autopilot.tbl* /autopilot/autopilot.cpp
Cheats.tbl* /cheats_table/cheats_table.cpp
Colors.tbl* /globalincs/alphacolors.cpp
Curves.tbl* /math/curves.cpp
Controlconfigdefaults.tbl /controlconfig/controlsconfigcommon.cpp
Credits.tbl* /menuui/credits.cpp
Cutscenes.tbl* /cutscene/cutscenes.cpp
Decals.tbl** /decals/decals.cpp
Fireball.tbl* /fireball/fireballs.cpp
Fonts.tbl* /graphics/font.cpp
Game_settings.tbl* /mod_table/mod_table.cpp
Glowpoints.tbl* /model/modelread.cpp
Help.tbl* /gamehelp/contexthelp.cpp
Hud_gauges.tbl* /hud/hudparse.cpp
Icons.tbl* /mission/missionbriefcommon.cpp
Iff_defs.tbl* /iff_defs/iff_defs.cpp
Keywords.tbl* Not In Codebase
Lighting_Profiles.tbl* /lighting/lighting_profiles.cpp
Lightning.tbl* /nebula/neblightning.cpp
Mainhall.tbl* /menuui/mainhallmenu.cpp
Medals.tbl* /stats/medals.cpp
Messages.tbl* /mission/missionmessage.cpp
Mflash.tbl* /weapon/muzzleflash.cpp
Music.tbl* /gamesnd/eventmusic.cpp
Nebula.tbl* /nebula/neb.cpp
Objecttypes.tbl* /ship/ship.cpp
Options.tbl* Not In Codebase
Particle effects(-part.tbm)** /particle/effects...
Post_processing.tbl /graphics/gropenglpostprocessing.cpp
Props.tbl* /props/props.cpp
Rank.tbl* /stats/scoring.cpp
Scpui.tbl* Not In Codebase
Scripting.tbl* /parse/scripting.cpp
Ships.tbl* /ship/ship.cpp
Sexps.tbl** /parse/sexp/sexp_lookup.cpp
Sounds.tbl* /gamesnd/gamesnd.cpp
Species_defs.tbl* /species_defs/species_defs.cpp
Species.tbl* /menuui/techmenu.cpp
Ssm.tbl* /hud/hudartillery.cpp
Stars.tbl* /starfield/starfield.cpp
Strings.tbl* /localization/localize.cpp
Tips.tbl* /menuui/playermenu.cpp
Traitor.tbl* /stats/scoring.cpp
Tstrings.tbl* /localization/localize.cpp
Virtual_pofs.tbl* /model/modelreplace.cpp
Weapon_expl.tbl* /weapon/weapons.cpp
Weapons.tbl* /weapon/weapons.cpp

The lens_flares.tbl defines physically-based lens systems used to render camera lens flares for suns. Added in FS2 Open, 26.1.

Unlike the sprite-based $Flare: effect defined in Stars.tbl, a lens system is described the way a real lens is: as a stack of glass surfaces. The engine traces that stack at table load and derives everything the flare needs from it, so the ghosts, their colours and the starburst all follow from the optics rather than from hand-placed sprites. A sun opts in with $Lens: in Stars.tbl; suns without it are unaffected, and a sun that has one no longer draws its sprite $Flare:.

FreeSpace Open ships a default lens_flares.tbl built into the engine, so the lens systems listed under #Default lens systems are always available even when no table file is present.

This table is one of the Modular Tables and can be extended with xxx-lens.tbm

General Format

  • The table consists of a single section
  • Begins with #Lens Systems
  • Contains any number of lens systems, each beginning with $Name:
  • Must be closed with #End
  • A lens system in a .tbm that reuses the $Name: of an existing one replaces it completely, rather than adding a second lens of the same name
  • Entries must appear in the order listed on this page. Options are read in sequence, so an option placed out of order is skipped, and one placed after the surface list will abort the parsing of the whole table
  • Every option except $Name: is optional and falls back to the default given below

Lens system options

  • $Name:
    • The name used to refer to this lens system from $Lens: in Stars.tbl and from the lens SEXPs
    • Begins a new lens system
    • Syntax: String
  • $Entrance Pupil Radius:
    • Radius of the front element, in millimetres. For a real design this is the focal length divided by twice the f-number
    • Controls how large the ghosts are and how much light the lens gathers
    • Syntax: Float, default is 10.0
  • $Aperture Radius:
    • Half-opening of the iris, in millimetres
    • This is the setting that decides whether a ghost is lit at all: each ghost slides across the iris as the sun moves off-axis, by an amount that grows with the field angle and shrinks with this value, and a ghost that slides off the iris goes black. Too small a value confines the whole flare to a sun near the centre of the frame; too large a one shrinks the ghosts within the iris until the blades stop shaping them
    • The physical value is the paraxial marginal-ray height where it crosses the $Stop:. The shipped lenses use 1.25x that
    • Syntax: Float, default is 5.0
  • $Sensor Width:
    • Width of the film gate, in millimetres. 36.0 is a full 35mm frame
    • Together with the focal length the engine derives from the surfaces, this sets how far the ghosts travel as the sun moves off-axis
    • Syntax: Float, default is 36.0
  • $Coating Wavelength:
    • Wavelength in nanometres that the anti-reflection coating is tuned to, as a quarter-wave layer
    • 500-570 (green-centred, like real broadband coatings) gives the classic magenta and cyan ghost tints. 0 disables coatings entirely for an uncoated vintage look: much brighter, neutral grey ghosts
    • Can be overridden per surface with +Coating Wavelength:
    • Syntax: Float, default is 540.0

Aperture

A lens has exactly one aperture, and it drives both the ghosts and the starburst: every ghost is an image of the iris, and the starburst is that same image's diffraction pattern. Changing a blade count therefore restyles both at once.

  • $Aperture Blades:
    • Number of iris blades. Fewer than 3 gives a perfectly round iris
    • Syntax: Integer, default is 6
  • +Blade Rotation:
    • Rotation of the iris, in degrees
    • Syntax: Float, default is 0.0
  • +Blade Curvature:
    • How the blades bow. 0 leaves them straight, 1 bows their midpoints out to the corner radius for a circular iris, and negative values bow them inward into a star
    • Syntax: Float, -1.0 to 1.0, default is 0.0
  • +Edge Softness:
    • Feathering of the iris edge, as a fraction of the iris radius
    • The default is also the floor the engine clamps to (about a two pixel ramp, so the mask never aliases), so asking for less has no effect. Softening the edge visibly weakens the starburst spikes, because those come from the sharpness of that edge
    • Syntax: Float, default is 0.0039

Aperture imperfections

Three optional layers darken the iris on top of the blade shape, for a dirty or damaged lens. All are off by default, and each takes its strength on the $-line followed by optional + sub-options.

Note that the starburst is normalized against its own brightest value, so these layers dim the core spikes as they add speckle around them, rather than only adding to what was already there.

  • $Aperture Grating:
    • A diffraction grating around the rim of the iris: radial ridges that throw extra spikes into the starburst
    • Syntax: Float, 0.0 to 1.0, strength; default is 0.0 (off)
    • +Density:
      • Fraction of the 360 possible ridges
      • Syntax: Float, 0.0 to 1.0, default is 0.5
    • +Length:
      • How far in from the rim the ridges reach, as a fraction of the iris radius
      • Syntax: Float, 0.0 to 1.0, default is 0.5
    • +Width:
      • Ridge width, as a duty cycle of the spacing between neighbouring ridges. Because it is relative, raising +Density: thins the ridges rather than merging them into a solid ring
      • Syntax: Float, 0.0 to 1.0, default is 0.25
    • +Softness:
      • Syntax: Float, default is 0.0
  • $Aperture Scratches:
    • Scratches on the glass: randomly placed slivers
    • Syntax: Float, 0.0 to 1.0, strength; default is 0.0 (off)
    • +Density:
      • Fraction of the 1000 possible scratches
      • Syntax: Float, 0.0 to 1.0, default is 0.5
    • +Length:
      • Syntax: Float, 0.0 to 1.0, default is 0.5
    • +Width:
      • Syntax: Float, 0.0 to 1.0, default is 0.25
    • +Rotation:
      • Direction the scratches run, in degrees
      • Syntax: Float, default is 0.0
    • +Rotation Variation:
      • 0 leaves every scratch parallel, 1 scatters them completely
      • Syntax: Float, 0.0 to 1.0, default is 0.0
    • +Softness:
      • Syntax: Float, default is 0.0
  • $Aperture Dust:
    • Dust on the glass: randomly placed specks
    • Syntax: Float, 0.0 to 1.0, strength; default is 0.0 (off)
    • +Density:
      • Fraction of the 1000 possible specks
      • Syntax: Float, 0.0 to 1.0, default is 0.5
    • +Radius:
      • Syntax: Float, 0.0 to 1.0, default is 0.5
    • +Softness:
      • Syntax: Float, default is 0.0

Starburst and brightness

  • $Starburst:
    • Whether this lens draws the diffraction starburst around the sun itself. When it does, the sun's bitmap glow is skipped so the two do not stack
    • Syntax: Boolean, default is YES
  • +Starburst Scale:
    • Size of the starburst relative to the frame
    • Syntax: Float, default is 1.0
  • $Intensity:
    • Overall brightness of this lens's flare
    • This is the artistic control, and it is best set by comparing against the shipped lenses in the lab. An uncoated lens ($Coating Wavelength: 0) reflects far more light and needs a much smaller value to stay in the same range
    • Syntax: Float, default is 0.2
  • $Max Ghosts:
    • How many of the brightest ghosts to draw. A lens with many elements can produce several hundred, so this caps the cost
    • Values above 63 are clamped to 63
    • Syntax: Integer, default is 40

Optical prescription

The rest of the entry is the lens itself: an ordered list of the surfaces light passes through, front element first. Every ordered pair of surfaces produces one ghost, so the number and arrangement of surfaces is what gives a lens its character.

These numbers are "lens prescriptions" as published in lens patents and optical design references, and can be transcribed directly, one element per $Surface: row. Scaling all radii and thicknesses by the same factor changes the focal length. The engine derives the focal length, the sensor distance, the ghost list and each ghost's brightness and tint from this stack at table load.

  • $Surface:
    • One spherical glass surface
    • Syntax: ( Float, Float, Float ) — curvature radius in millimetres, distance to the next surface in millimetres, and refractive index of the glass behind the surface (1.0 being air)
    • A positive radius means the surface bulges toward the front of the lens, with its centre of curvature behind it; a negative radius bulges toward the sensor; 0 is a flat surface
    • The distance on the last surface is ignored: the engine places the sensor at the focus it computes
    • +Abbe:
      • Abbe V-number of the glass behind the surface, which sets how much it disperses. Crown glasses are around 55-60, dense flints around 30-40. This only drives the chromatic fringing of the ghosts, so approximate values are fine
      • Syntax: Float, default is 0.0 (no dispersion)
    • +Coating Wavelength:
      • Overrides $Coating Wavelength: for this surface alone
      • Syntax: Float, defaults to the lens's own value
  • $Stop:
    • Marks the iris plane. It does not refract or reflect; it is where the aperture sits in the stack
    • Syntax: ( Float ), distance to the next surface in millimetres
    • A lens without a $Stop: uses its middle surface as the aperture plane

A lens system needs at least two surfaces, and its prescription must actually form an image. One that does not (for instance an afocal stack) is dropped with a warning at table load and cannot be referenced.

Using a lens

  • Assign a lens to a sun with $Lens: in Stars.tbl, naming a lens system from this table
  • Missions can override it and edit the iris at runtime with the lens SEXPs
  • The F3 lab (Render options -> Lens flare options) can swap the lens on each sun and adjust every aperture setting live, which is the practical way to dial in $Intensity: and the imperfection layers
  • Only the first visible lens-equipped sun in a mission renders a flare
  • The flare is suppressed in full-nebula missions, in subspace, in VR, when post-processing is disabled, and when the Planets/Backgrounds detail setting is off

SEXPs

  • set-sun-lens — override which lens system a sun uses, or turn its flare off
  • set-lens-aperture — blade count, rotation, curvature and edge softness
  • set-lens-grating, set-lens-scratches, set-lens-dust — the imperfection layers

The aperture operators edit the lens system itself, so they affect every sun using that lens; the edits are undone when the mission ends. These operators are not sent over the network, so in multiplayer they only affect the host.

Default lens systems

The built-in table ships eight lens systems, transcribed from published patents. All of them leave the imperfection layers off.

  • angenieux_100mm — double-Gauss cine prime, f/2.2. The reference prescription from the research this renderer is based on, and the lens the others are calibrated against
  • tessar_50mm — classic Tessar, f/3.5. Few elements, so a sparse and subtle ghost set
  • canon_70_200mm — modern multicoated telephoto zoom, f/2.8. The busiest shipped lens: a dense, strongly tinted ghost train
  • kodak_100mm — symmetric double Gauss, f/3.8, single-coated. A sparse, orderly ghost set that stays stable as the sun moves off-axis
  • leica_35mm — fast aspherical wide-angle prime, f/1.4. The shortest focal length shipped, so its ghosts sweep the furthest
  • nikon_50_135mm — multicoated telephoto zoom, f/3.5
  • color_heliar_105mm — uncoated vintage prime, f/3.5. The uncoated reference: few, large, colourless, obvious ghosts
  • zeiss_master_prime_50mm — modern multicoated cine prime, T1.3. Many large, bright, strongly tinted ghosts; the closest to a contemporary cinema look

Sample

#Lens Systems

; Classic Tessar, f/3.5, f=50mm, with a little dust on the front element.
$Name: tessar_50mm
$Entrance Pupil Radius: 7.0
$Aperture Radius: 5.0
$Sensor Width: 36.0
$Coating Wavelength: 520
$Aperture Blades: 8
+Blade Rotation: 0.0
+Blade Curvature: 0.3
$Aperture Dust: 0.4
+Density: 0.3
+Radius: 0.25
$Starburst: YES
+Starburst Scale: 0.8
$Intensity: 0.2
$Max Ghosts: 24
$Surface: ( 16.25, 2.90, 1.6116 )
+Abbe: 56.9
$Surface: ( -285.90, 0.29, 1.0 )
$Surface: ( -30.05, 1.20, 1.6053 )
+Abbe: 43.6
$Surface: ( 17.47, 1.38, 1.0 )
$Stop: ( 1.15 )
$Surface: ( 31.55, 1.20, 1.5123 )
+Abbe: 51.0
$Surface: ( 21.30, 3.50, 1.6116 )
+Abbe: 56.9
$Surface: ( -23.70, 40.0, 1.0 )

#End

To use it, name it from a sun in Stars.tbl:

#Stars

$Sun: SunWhite
$Sunglow: Sunglow01
$SunRGBI: 1.0 1.0 1.0 1.0
$Lens: tessar_50mm

#end