photography_and_imaging

Computational photography and workflow:
  exposure bracketing  multiple exposures merged for extended range
  burst averaging      noise reduced by combining aligned frames; the basis of
                       small-sensor low-light performance
  alignment            required before combining; motion is the difficulty
  focus stacking       extended depth of field beyond the diffraction limit
  panorama stitching   extended field of view; projection choice matters
  depth estimation     from stereo, phase detection, or a learned model
  synthetic aperture   background blur computed rather than optical
  the boundary artifact  hair, glass, and fine structure at depth
                       discontinuities
  semantic processing  region-aware adjustment; skies, skin, foliage treated
                       differently
  the aesthetic question  computational processing has a house style, and
                       recognizing it is part of evaluating an image
  raw plus processed   keep the raw; the rendering can be redone, the capture
                       cannot
  metadata             capture settings, location, and keywords; the only
                       organization that scales
  the rating pass      done immediately; deferred culling never happens
  backup rule          multiple copies, multiple media, one off-site
  verification         a backup that has never been restored from is a hypothesis
                       rather than a backup, and the archive failure that matters
                       is always the one discovered too late


physical_computing_installation

Light, Projection, and Installation Fabrication

## Light Sources and Control

Light is the primary medium of most installation work, and the properties determining how it
behaves are frequently different from the ones specified in a catalogue. Luminous flux measured in
lumens is the total light emitted, which describes the source. Illuminance in lux is the light
falling on a surface, which depends on distance and falls with its square. Luminance in candelas
per square metre is the brightness of a surface as seen, which is what the viewer perceives. A
source specified only in lumens says nothing about how bright anything will appear without knowing
the geometry.


physical_computing_installation

Colour rendering describes how faithfully a source reveals surface colours, and it matters
whenever the light is illuminating something rather than being the subject. The colour rendering
index compares against a reference across a set of sample colours, and its known weakness is that
a source can score well while rendering saturated reds poorly, which is why the newer metrics
report fidelity and gamut separately. Sources with spiky spectra — some LEDs and most discharge
lamps — render some colours badly regardless of their index.


physical_computing_installation

Colour temperature describes the appearance of white light on a scale from warm to cool, and it
is not a measure of quality. Two sources at the same colour temperature can have entirely
different spectra and render colours differently, which is why matching colour temperature between
fixtures does not guarantee they will look the same on a surface.


physical_computing_installation

Light properties and control:
  luminous flux        lumens; total emitted, a property of the source
  illuminance          lux; falling on a surface, falls with distance squared
  luminance            candelas per square metre; perceived brightness of a surface
  inverse square law   doubling the distance quarters the illuminance
  beam angle           where the intensity falls to half; determines the spread
  colour temperature   warm to cool appearance; not a quality measure
  colour rendering     fidelity to a reference; spiky spectra render poorly
                       regardless of the index
  metamerism           two sources appearing identical rendering surfaces
                       differently
  dimming curve        perception is roughly logarithmic, so linear dimming looks
                       wrong; apply a gamma curve
  PWM dimming          switching rapidly; the frequency must exceed what cameras
                       and peripheral vision detect, which is far above the flicker
                       threshold for direct viewing
  flicker              visible or not depending on frequency and depth; a health
                       concern and a problem for video capture
  DMX                  the standard lighting control protocol; 512 channels per
                       universe, no acknowledgement, and no security
  Art-Net and sACN     DMX over Ethernet; many universes over one cable


physical_computing_installation

Q: An installation lit by PWM-dimmed LEDs looks fine to the eye and shows severe banding when
filmed. The cause is:
A. The camera is faulty
B. The PWM frequency interacts with the camera's rolling shutter, so different rows of the sensor
   are exposed during different parts of the PWM cycle
C. The LEDs are the wrong colour temperature
D. The exposure is wrong
Reasoning: A rolling shutter exposes sensor rows sequentially rather than simultaneously, so a
light switching on and off during the frame produces bright and dark bands corresponding to the
PWM state when each row was exposed. The eye integrates over time and does not see it. Raising the
PWM frequency well above the row rate, or using analogue dimming, eliminates it. Answer: B.


physical_computing_installation

## LED Systems

Addressable LED strips have become the default medium for light-based installation work because
they permit per-pixel control at low cost. The two families differ in ways that determine which
suits an application. Single-wire protocols embed the clock in the data timing, which requires only
one signal wire and makes the timing critical — an interrupt during transmission corrupts the
frame. Two-wire protocols with a separate clock are timing-insensitive, work over longer distances,
and support far higher refresh rates.


physical_computing_installation

Power is the constraint that most installations underestimate. A common strip specification is
sixty LEDs per metre at sixty milliamps each at full white, which is 3.6 amps per metre — so a
ten-metre run at full brightness draws thirty-six amps, which is a substantial supply and a
conductor sizing problem. Voltage drop along the strip is the associated failure: at five volts, a
run of more than a couple of metres shows visible dimming and colour shift toward red at the far
end, because the red channel's forward voltage is lowest and it survives the drop best.


physical_computing_installation

Power injection addresses this by feeding supply at intervals along the strip rather than only at
one end, and the spacing follows from the acceptable drop. Twelve-volt and twenty-four-volt strips
tolerate longer runs because the same absolute drop is a smaller fraction of the supply, which is
why higher voltages are preferred for large installations despite the lower per-pixel density.


physical_computing_installation

LED systems:
  addressable strip    per-pixel control; the default medium
  single-wire protocol  clock embedded in timing; one wire, timing-critical
  two-wire protocol    separate clock; robust, longer runs, higher refresh
  current per LED      ~60 mA at full white for a common type
  power calculation    LEDs times current times voltage; a ten-metre run at full
                       white is a serious supply
  voltage drop         visible dimming and colour shift along a run
  colour shift         toward red, since red has the lowest forward voltage
  power injection      feed supply at intervals; the spacing follows from the drop
  higher voltage       12 V and 24 V tolerate longer runs; lower pixel density
  common ground        data and power grounds must be connected, and a missing
                       common ground is the most frequent cause of erratic
                       behaviour
  level shifting       5 V data from a 3.3 V controller; marginal without it
  first pixel sacrifice  using the first LED as a level shifter; a common
                       workaround
  refresh rate         limited by the protocol and the pixel count; single-wire
                       protocols become slow at high counts
  thermal              LEDs at full brightness in an enclosed channel overheat and
                       degrade; derate or provide a heat path
  diffusion            direct view of individual LEDs is usually unwanted; a
                       diffuser at an appropriate distance is what makes a strip
                       read as a line of light


physical_computing_installation

The missing common ground deserves specific emphasis because it produces symptoms that appear to
be data corruption and is fixed by a wire. If the controller and the LED strip are powered from
separate supplies with no ground connection between them, the data signal has no defined reference
at the receiving end, and the behaviour ranges from erratic flickering to apparently random colours
to intermittent failure that appears when someone touches the installation. Connecting the grounds
resolves it, and checking for it first saves hours of investigating the data.


physical_computing_installation

## Projection

Projection places light on surfaces, and the fundamental constraint is that a projector adds light
and cannot remove it — so black in a projected image is whatever the ambient light makes the
surface, and contrast depends entirely on controlling that ambient. An installation in a bright
space will have washed-out projection regardless of the projector's specification, and darkening
the space is more effective than any increase in brightness.


physical_computing_installation

Throw ratio relates the projection distance to the image width and determines whether a projector
fits a space. A standard lens might have a ratio around 1.5, so a three-metre-wide image requires
4.5 metres of throw. Short-throw and ultra-short-throw lenses reduce this substantially, which
matters when the space is small or when people would otherwise walk through the beam and cast
shadows.


physical_computing_installation

Keystone correction compensates for projecting at an angle, and it should be understood as a
compromise rather than a solution. Correcting geometrically in software means discarding pixels —
the projected rectangle becomes a trapezoid within the available resolution — so the image loses
brightness and resolution. Physical alignment, lens shift, and mounting the projector on the
optical axis are preferable where possible.


physical_computing_installation

Projection mapping projects onto non-flat surfaces so that the imagery aligns with the geometry,
and the technique is what permits projection onto buildings, sculptures, and irregular objects.
The alignment is achieved by warping the source image to match the surface, either by manually
adjusting a mesh or by structured-light scanning that determines the correspondence
automatically.


physical_computing_installation

Projection:
  additive only        a projector cannot make black; contrast depends on ambient
                       light
  control the ambient  more effective than any brightness increase
  lumens               brightness; ANSI lumens is the comparable measure and
                       marketing figures frequently are not
  throw ratio          distance over image width; determines whether it fits
  short throw          large image at short distance; avoids shadows from people
  lens shift           offset the image optically without distortion; preferable
                       to keystone correction
  keystone correction  compensates for angle in software; costs pixels and
                       brightness
  edge blending        overlap several projectors with a gradient in the overlap;
                       requires matched brightness and colour
  projection mapping   warp to match a non-flat surface
  structured light     project patterns to determine the surface correspondence
                       automatically
  surface material     matte and light-coloured for a screen; specular surfaces
                       produce hotspots
  rear projection      no shadows from viewers; requires depth behind the surface
  projector heat and noise  a real constraint in a quiet installation; consider
                       an enclosure with acoustic treatment and ducted airflow
  lamp life            and its cost; laser sources have largely displaced lamps
                       for installation use


physical_computing_installation

Edge blending deserves note because it is how large projected surfaces are built and because its
difficulty is in matching rather than in blending. Overlapping two projectors and applying a
gradient in the overlap region so their contributions sum to the correct level is geometrically
straightforward. Making the seam invisible requires the two projectors to match in brightness,
colour, and black level — and projectors of the same model differ, drift over time, and age
differently, so the matching requires measurement and periodic adjustment rather than being a
one-time setup.


physical_computing_installation

[user] My projection installation looks great in the studio and washed out in the gallery, and the
gallery says they can't turn the lights down.
[assistant] tool_call projection.contrast_analysis({"projector_lumens": 4000,
"image_width_m": 4, "image_height_m": 2.25, "surface_gain": 1.0,
"ambient_lux_studio": 20, "ambient_lux_gallery": 300, "content": "dark_with_bright_elements"})
[tool] {"image_area_m2": 9, "projected_illuminance_lux": 444,
"studio_contrast_ratio": 23, "gallery_contrast_ratio": 2.5,
"verdict": "ambient_dominates", "options": ["reduce_ambient_locally",
"high_gain_or_ambient_rejecting_surface", "increase_brightness", "redesign_content"]}
[assistant] The arithmetic is stark: your ambient went from 20 lux to 300, and your projector puts
about 444 lux on the surface. In the studio the contrast ratio was 23 to 1, which reads as
properly black. In the gallery it is 2.5 to 1, which reads as grey with slightly brighter grey on
it.


physical_computing_installation

You cannot fix this with brightness alone. Matching the studio contrast at 300 lux ambient would
require about 6,700 lux on the surface, which is fifteen times your current projector — a
sixty-thousand-lumen machine, which is a different order of installation.


physical_computing_installation

Four approaches, and the first two are the realistic ones.


physical_computing_installation

Reduce the ambient locally rather than globally. The gallery cannot darken the whole space and can
frequently accommodate a local intervention: a partial enclosure, a light-blocking baffle above and
around the projection surface, redirecting or shading the specific fixtures illuminating that wall,
or a fabric surround. Reducing the ambient on the surface from 300 to 60 lux restores most of the
contrast and is a fraction of the cost of a larger projector.


physical_computing_installation

Change the surface. An ambient-light-rejecting screen material accepts light from the projector's
direction and rejects light from other angles, which improves the contrast ratio by a factor of
several in exactly your situation. It is directional, so the viewing positions must be considered,
and it is substantially cheaper than the projector upgrade.


physical_computing_installation

Increase brightness, which helps proportionally and does not solve it alone. Going to 10,000
lumens takes your contrast from 2.5 to about 4.7, which is better and still not what the studio
looked like.


physical_computing_installation

Redesign the content. Imagery designed for a low-contrast environment — bright content on a
mid-tone base rather than bright elements on black — reads well where black is unattainable. This
is a legitimate response rather than a compromise, and content designed for the actual condition
will look better than content designed for a dark room and shown in a bright one.


physical_computing_installation

The general principle to carry forward: measure the ambient illuminance at the installation site
before finalizing the design. It is a two-minute measurement with a meter or a phone app, and it
determines what is achievable in a way that no projector specification does.


physical_computing_installation

## Kinetic Elements and Fabrication

Kinetic work adds mechanical motion, and the engineering requirements are unforgiving because the
piece runs continuously and is accessible to the public. The duty cycle question dominates: a
mechanism running eight hours a day for three months completes an enormous number of cycles, and
components adequate for a demonstration wear out or overheat within days.


physical_computing_installation

Actuator selection follows from the motion required and from the duty cycle. Hobby servos hold
position by drawing current continuously and overheat when loaded; they suit intermittent motion
and not sustained holding. Steppers hold position with current and also run hot, and they lose
steps silently under overload. Geared DC motors with position feedback suit continuous rotation.
Solenoids must be duty-limited or they burn out. And for slow silent motion, shape memory alloys
and pneumatics have their niches.


physical_computing_installation

Noise is a design parameter in a gallery and is frequently discovered late. A stepper motor's
characteristic whine, a servo's chatter as it hunts around a position, a fan, a relay click, and a
mechanism's vibration transmitted into a plinth are all audible in a quiet space and all read as
technical noise rather than as part of the work. Compliant mounting, quieter actuators,
microstepping, and mechanical damping address them, and considering them at the design stage
avoids a rebuild.


physical_computing_installation

Kinetic and fabrication:
  duty cycle           the dominant question; a demonstration is not a run
  servo                intermittent motion; overheats holding a load
  stepper              holds with current, runs hot, loses steps under overload
  geared DC            continuous rotation; needs feedback for position
  solenoid             discrete actuation; duty limited or it burns out
  noise                a design parameter in a gallery; discovered late by default
  compliant mounting   isolates vibration from the structure
  bearings and wear    the failure point in continuous motion; specify for the
                       cycle count
  end stops            mechanical limits independent of the software; a software
                       limit fails when the software does
  fail safe            what happens on power loss; define it
  laser cutting        fast, precise, flat sheet; kerf compensation and material
                       limits
  CNC routing          larger and thicker; three-dimensional forms
  3D printing          complex geometry, small parts, prototypes; anisotropic
                       strength along the layer direction
  tolerances           digital fabrication is precise and not exact; design in
                       clearance rather than assuming a press fit
  material behaviour   wood moves with humidity, acrylic crazes under solvent and
                       stress, MDF absorbs water; each fails in a characteristic
                       way
  finishing            the difference between a prototype and a work; and it takes
                       longer than expected


physical_computing_installation

The anisotropy of 3D printed parts deserves emphasis because it produces failures that seem
inexplicable. A part printed by fused deposition is strong within each layer and weak between
layers, so the strength depends entirely on the print orientation relative to the load. A bracket
that would carry the load if printed one way snaps at a layer boundary if printed another, and the
part looks identical. Designing with the load path in mind and orienting the print accordingly is
what makes printed parts structural rather than decorative.


physical_computing_installation

## Power, Safety, and Production

Electrical safety in installation work is a legal and ethical requirement rather than a matter of
diligence, because the public will touch the work and the installer is not present. Anything
connected to mains voltage requires appropriate isolation, enclosure, earthing, and protection, and
in most jurisdictions requires appropriately qualified work and testing.


physical_computing_installation

Power calculation should be done for the simultaneous worst case rather than for typical
operation. An LED installation at full white draws several times its average, a motor's inrush
current is many times its running current, and a projector's startup draw exceeds its steady
consumption. Sizing for the average produces a supply that trips or sags at the moment everything
runs together, which is typically the opening.


physical_computing_installation

Cable management is both a safety requirement and a visual one. Cables on the floor are a trip
hazard and are also visible, and both are addressed by the same interventions — routing within
structure, under covers, or overhead. Strain relief at every connection prevents the most common
physical failure, which is a cable pulled until the conductor breaks inside the insulation where
it cannot be seen.


physical_computing_installation

Power, safety, and production:
  mains voltage        qualified work, enclosure, earthing, protection, and
                       testing; a legal requirement in most jurisdictions
  extra-low voltage    under 50 V AC or 120 V DC; substantially fewer
                       requirements, and it is why most installation electronics
                       runs at 12 or 24 V
  RCD protection       residual current device; required and cheap
  worst case power     simultaneous peak, not average; inrush and full-brightness
                       cases
  inrush current       motors and supplies draw many times their running current
                       at startup; sequence them or use soft start
  cable management     safety and appearance; the same interventions serve both
  strain relief        at every connection; the most common physical failure
  fire rating          materials and their treatment; galleries and public venues
                       have requirements
  structural loading   anything suspended requires calculation and appropriate
                       hardware; the consequences of failure are severe
  insurance and permits  the practical constraints that determine what is
                       installable
  documentation        a start and stop procedure, a wiring diagram, and a fault
                       guide for the venue
  spares               on site with instructions a non-specialist can follow
  build time           consistently underestimated; the fabrication and
                       installation take longer than the software


physical_computing_installation

The rigging point deserves the closing emphasis because it is the one where a mistake is
catastrophic rather than merely inconvenient. Anything suspended above people is a structural
element requiring calculation, appropriate rated hardware, secondary retention in case the primary
fails, and in most venues sign-off by someone qualified. The consequences of a failure are entirely
different in kind from a piece that stops working, and the temptation to improvise under time
pressure at install is exactly when the risk is greatest. Determining the rigging approach and the
hardware early, and treating it as a fixed constraint rather than as something to resolve on site,
is the practice that prevents the situation arising.


procedural_generation

## Grammars and Rewriting Systems

Procedural generation creates content algorithmically rather than by hand, and the oldest
family of techniques is rewriting: start from a symbol and repeatedly replace symbols
according to rules until a terminal string remains, then interpret that string as structure.


procedural_generation

L-systems, developed to model plant growth, rewrite all symbols in parallel at each step,
which is what distinguishes them from ordinary formal grammars and what makes them model
biological growth well — every cell divides simultaneously rather than one at a time. The
resulting string is interpreted by a turtle: symbols command forward movement, rotation,
and the pushing and popping of state that produces branching. A handful of rules and a few
iterations produce convincing trees, ferns, and space-filling curves.


procedural_generation

The extensions are what make L-systems practical rather than merely elegant. Stochastic
rules select among alternatives by probability, so repeated generation gives variety rather
than identical copies. Context-sensitive rules let a symbol's rewriting depend on its
neighbours, which models signal propagation through a growing structure. Parametric systems
attach numeric parameters to symbols — length, width, age — so that rules can express
continuous change and conditional behaviour, which is how realistic tapering and
age-dependent branching are obtained.


procedural_generation

Shape grammars apply the same idea to geometry directly rather than through a string,
rewriting shapes into arrangements of shapes. Split grammars, their architectural
specialization, repeatedly subdivide a mass into floors, then into bays, then into window
and wall elements, which is how procedural building generation works and why it produces
plausible facades: real buildings genuinely are organized by hierarchical subdivision.


procedural_generation

Rewriting system components:
  alphabet             the symbols
  axiom                the starting string
  production rules     symbol to string replacements
  parallel rewriting   all symbols rewritten simultaneously; the L-system defining
                       property
  turtle interpretation F forward, +/- rotate, [ ] push/pop state
  stochastic rules     multiple productions with probabilities; variety
  context sensitive    rewriting depends on neighbours
  parametric           symbols carry numeric parameters
  shape grammar        rewriting on geometry rather than symbols
  split grammar        hierarchical subdivision; facades and interiors
  wave function collapse  constraint propagation over local adjacency rules


procedural_generation

The characteristic failure of grammar-based generation is that local rules do not guarantee
global properties. An L-system tree can grow branches that intersect, because no rule
considers what other branches are doing. A split grammar can produce a building whose
windows do not align between floors. The remedies are post-processing to detect and repair
violations, adding environmental sensitivity so that rules query the surrounding geometry
before firing, or moving to a formulation where global constraints are expressed directly —
which is what constraint-based methods do.


procedural_generation

Q: An L-system produces identical output on every run. The most direct way to get variety
while preserving the same structural character is:
A. Increase the iteration count
B. Add stochastic productions with weighted alternatives
C. Change the axiom each run
D. Add more symbols to the alphabet
Reasoning: Stochastic productions replace a symbol with one of several alternatives chosen
by probability, so the structural grammar is preserved while the specific realization varies.
More iterations produce a larger structure of the same character; changing the axiom changes
the starting point rather than the variation; more symbols changes the grammar itself.
Answer: B.


procedural_generation

## Constraint-Based Generation

Constraint-based methods invert the grammar approach: rather than specifying how content is
built, specify what must be true of it and let a solver find something satisfying the
requirements. This is attractive because designers naturally think in constraints — every
room must be reachable, the key must be findable before the door, no two adjacent tiles may
be incompatible — and because it guarantees the constraints rather than hoping the generative
process happens to satisfy them.


procedural_generation

Wave function collapse is the technique that popularized this framing in generative art. It
takes an example input, extracts the set of local patterns and their adjacency
compatibilities, then fills an output grid by repeatedly choosing the cell with fewest
remaining possibilities, collapsing it to one option, and propagating the consequences to
neighbours. The result resembles the input locally everywhere while being globally novel.
Its appeal is that the designer specifies the style by drawing an example rather than by
writing rules.


procedural_generation

The technique's characteristic problem is contradiction: propagation can reach a state where
some cell has no valid options, and the generation fails. The standard responses are
backtracking, which is expensive; restarting, which is simple and wasteful; and constraint
relaxation, which permits an imperfect result rather than none. In practice, careful design
of the tile set to avoid over-constraining, plus restart-on-failure, is what most
implementations do.


procedural_generation

Answer set programming and SAT-based approaches generalize this. Content requirements are
expressed as logical constraints and a general-purpose solver finds satisfying assignments,
with the ability to enumerate distinct solutions for variety. This handles global constraints
that local propagation cannot — that a level must be completable, that a puzzle must have
exactly one solution, that a quest chain must be acyclic — at the cost of much heavier
computation and the difficulty of expressing aesthetic preferences as logic.


procedural_generation

Constraint approaches:
  wave function collapse  local adjacency from an example; fast, style-driven
  model synthesis         the predecessor; similar idea with different propagation
  answer set programming  full logical constraints; global guarantees, slower
  SAT / SMT               constraint satisfaction with rich theories
  constraint propagation  arc consistency; prune impossible options early
  backtracking            recover from contradictions at some cost
  soft constraints        preferences with weights rather than hard requirements
  generate and test       simple, effective when the acceptance rate is decent,
                          hopeless when constraints are tight
  repair-based            generate freely, then fix violations; often the most
                          practical hybrid


procedural_generation

The choice between generate-and-test and constraint solving comes down to the acceptance
rate. If a naive generator produces a valid artifact most of the time, testing and rejecting
is far simpler than building a solver. If valid artifacts are rare — a level that must be
completable, a puzzle with a unique solution — rejection sampling never terminates and a
constructive or constraint-based method is required. Estimating that acceptance rate early is
worth doing before committing to an architecture.


procedural_generation

## Terrain, Worlds, and Continuous Content

Terrain generation is the most visible application and rests on noise. A heightmap generated
from fractal Brownian motion — layered noise octaves at increasing frequency and decreasing
amplitude — produces plausible rolling landscape immediately. The refinements are what turn
that into something with character.


procedural_generation

Ridged noise, taking one minus the absolute value of noise and squaring, produces sharp
ridgelines resembling mountain ranges rather than rounded hills. Domain warping, evaluating
noise at coordinates displaced by another noise field, produces the flowing, folded
structure of real geology rather than isotropic bumps. Erosion simulation — either
hydraulic, moving material downhill with simulated water flow, or thermal, relaxing slopes
beyond an angle of repose — produces the drainage networks, valleys, and talus slopes that
make terrain read as having a history rather than as noise.


procedural_generation

Erosion deserves emphasis because it is the single highest-impact addition. Pure fractal
noise produces terrain that is statistically self-similar and geologically impossible: no
drainage, no valleys converging, no sediment deposition in basins. Even a crude hydraulic
erosion pass — drop particles, let them pick up and deposit material according to slope and
capacity, repeat — transforms the result, because real terrain is shaped overwhelmingly by
water and the eye recognizes drainage structure even without knowing why.


procedural_generation

Terrain and world generation:
  fractal noise         layered octaves; the base heightmap
  ridged noise          sharp crests; mountain ranges
  domain warping        folded, flowing structure; the highest-value cheap addition
  hydraulic erosion     drainage networks, valleys, sediment; transformative
  thermal erosion       talus slopes at the angle of repose
  Voronoi regions       tectonic plates, biomes, political territories
  Whittaker biomes      assign biome from temperature and precipitation fields
  rivers                trace downhill from high points; carve and widen
  masks and gradients   island shapes, continental outlines, playable-area limits
  chunked generation    generate on demand from position-seeded noise; enables
                        effectively infinite worlds with no storage
  level of detail       resolution scaled by distance; essential at world scale


procedural_generation

Infinite world generation requires that content be a pure function of position and seed,
computable independently of any other chunk. This is why noise functions rather than
simulation are the base layer: noise is evaluable at any coordinate in isolation, while
erosion is inherently global. The standard compromise is a noise base that is
position-independent, plus locally-simulated detail within a chunk, plus careful handling of
chunk boundaries so that features crossing them remain continuous — which usually means
generating with overlap and blending, or restricting cross-boundary features to the base
layer.


procedural_generation

[user] My generated terrain looks like noise, not landscape. What's the highest-impact
change?
[assistant] tool_call procgen.terrain_audit({"base": "perlin_fbm", "octaves": 6,
"erosion": false, "domain_warp": false, "river_network": false, "biome_assignment":
"height_only", "ridged": false})
[tool] {"realism_score": 0.28, "missing": ["erosion", "domain_warp",
"drainage_structure"], "highest_impact": "hydraulic_erosion",
"cheapest_impact": "domain_warp", "note": "height_only_biomes_produce_banding"}
[assistant] Two changes, and I would do the cheap one first to see immediate improvement.


procedural_generation

Domain warping costs almost nothing and changes the character immediately. Instead of
sampling noise at position p, sample it at p plus a vector derived from another noise field.
That converts isotropic bumpiness into folded, flowing structure with directionality, which
is what real geology has and pure fractal noise does not. Two lines of code and a warp
strength parameter to tune.


procedural_generation

Hydraulic erosion is the bigger win and costs more. Your terrain has no drainage — no
valleys converging into larger valleys, no ridgelines separating watersheds, no sediment
deposited in flat basins. The eye recognizes drainage structure even without knowing what it
is looking at, and its absence is the main reason fractal terrain reads as noise. A
particle-based erosion pass is straightforward: drop a droplet at a random point, let it flow
downhill accumulating sediment proportional to speed and slope, deposit when it slows or
pools, and run a few hundred thousand droplets. Even a crude implementation transforms the
result.


procedural_generation

Two smaller things while you are in there. Add ridged noise to at least the high-frequency
octaves — one minus the absolute value of noise, squared — which gives sharp crests instead
of rounded lumps. And your biomes are assigned from height alone, which produces the
characteristic horizontal banding that immediately reads as generated. Generate separate
temperature and moisture fields (temperature falling with height and latitude, moisture
from a noise field modified by prevailing wind and rain shadow) and assign biomes from that
two-dimensional space. Rain shadow especially — drier on the lee side of a range — is a
strong realism cue that is nearly free once you have a wind direction.


procedural_generation

Order: domain warp, then ridged octaves, then biome fields, then erosion. Each is visible on
its own so you learn what each contributes.


procedural_generation

## Graphs, Dungeons, and Discrete Structure

Discrete content — level layouts, dungeon maps, quest structures, skill trees — is naturally
represented as a graph, and generating it well means generating the graph first and the
geometry afterward. The mistake that produces incoherent levels is generating rooms and
corridors geometrically and hoping the connectivity turns out interesting.


procedural_generation

The graph-first approach generates the intended structure — a critical path with branches,
optional loops, gated sections — as an abstract graph, verifies its properties, and only then
embeds it in space. This guarantees that the level is completable, that keys precede their
doors, that optional content is genuinely optional, and that the difficulty progression is
what was intended, because all of those are graph properties checked before any geometry
exists.


procedural_generation

Space partitioning generates layouts by recursive subdivision. Binary space partitioning
splits a rectangle repeatedly, placing a room in each leaf and connecting siblings, which
produces the characteristic rectangular dungeon efficiently and with guaranteed
connectivity. Cellular automata smoothing produces organic cave systems from random noise by
repeatedly applying a rule that turns a cell into whatever most of its neighbours are, and
requires a connectivity check afterward since it readily produces isolated pockets.


procedural_generation

Discrete generation techniques:
  BSP subdivision       rectangular rooms with guaranteed connectivity
  cellular automata     organic caves; needs a flood fill to verify connectivity
  random walk / drunkard  simple tunnelling; produces winding organic paths
  Delaunay + MST        connect rooms by minimum spanning tree, then add a few
                        extra edges for loops; produces good connectivity structure
  graph grammar         rewrite an abstract mission graph, then embed
  lock and key          gating structure; verify solvability on the graph
  Poisson disc          room or object placement with minimum spacing
  flood fill            connectivity verification; run it always
  A-star / pathfinding  verify traversability and measure path length as a
                        difficulty proxy


procedural_generation

The minimum spanning tree plus extra edges pattern is worth knowing because it produces
good level connectivity with two lines of reasoning. A minimum spanning tree over room
centres guarantees every room is reachable with no redundant connections, which is a
tree — and a pure tree level is frustrating, because every dead end must be backtracked. Adding
back a small fraction of the discarded edges, chosen from the shortest, introduces loops that
make navigation pleasant without making the space incomprehensible. The fraction of extra
edges is a single tunable parameter controlling how maze-like versus how open the level
feels.


procedural_generation

## Controllability and Evaluation

The central tension in procedural generation is between variety and control. A system with
no constraints produces varied and mostly bad output; a heavily constrained system produces
reliably acceptable and boringly similar output. The design work is finding the parameterization
where the achievable outputs are all acceptable and meaningfully different.


procedural_generation

Controllability techniques give a designer authority over the result without abandoning
generation. Seeded determinism allows a specific output to be recovered and refined.
Exposed parameters with meaningful names let a designer steer at a high level. Authored
constraints let specific content be pinned while the rest generates around it — a hand-built
boss room embedded in a generated dungeon. Mixed-initiative tools let a designer edit a
generated result and regenerate the remainder consistently with the edit, which is the
interaction model that has proven most usable in practice.


procedural_generation

Evaluation is where procedural generation is weakest, because the quality criteria are
usually aesthetic and the output space is too large to inspect. Automated metrics can
capture some properties objectively: connectivity, path length, symmetry, density,
compressibility as a proxy for structure, and expressive range — the region of a metric space
the generator actually covers, which reveals whether the variety is real or nominal.


procedural_generation

Evaluation approaches:
  hard constraints       completability, connectivity, reachability; verify always
  expressive range       plot outputs in a two-dimensional metric space; a
                         generator clustering tightly has less variety than it
                         appears to
  diversity metrics      pairwise distance between outputs under some
                         representation
  playtesting            for interactive content, the ground truth
  contact sheet          judge a hundred outputs at small size, never one at full
  worst-case review      inspect the least good outputs; a system is only as good
                         as its floor if outputs cannot be curated
  A-star difficulty      path length and branching as a difficulty proxy
  designer review        a domain expert rating a sample; expensive and honest


procedural_generation

Expressive range analysis is the most useful evaluation tool and the least used. Generate a
few hundred artifacts, compute two or three meaningful metrics on each, and plot them.
Generators that feel varied frequently occupy a small tight cluster, which explains why their
output starts to feel repetitive after a while even though no two artifacts are identical.
Seeing the covered region also shows which parameter changes move the generator into new
territory and which merely jiggle it within the same cluster, which is far more actionable
than a general impression that the output needs more variety.


procedural_generation

The final practical principle is to design for the worst case rather than the best. A
generator producing an occasional spectacular result alongside frequent failures is only
usable if a human curates the output, and that curation does not scale and does not work at
all for content generated at runtime. A generator whose worst output is acceptable can run
unattended, and the accumulated experience of the field is that constraining the system until
its floor is acceptable — even at the cost of lowering its ceiling — produces more usable work
than the reverse.


shaders_and_gpu_graphics

## The Graphics Pipeline

The GPU is a throughput machine, not a latency machine. It runs thousands of threads
in lockstep groups — warps of 32 on NVIDIA, wavefronts of 64 on AMD, SIMD groups of 32
on Apple — where every thread in a group executes the same instruction on different
data. This single architectural fact explains nearly every shader performance rule.
Branching is expensive not because the branch itself is slow but because divergence
within a group forces both sides to execute with the inactive lanes masked off, so a
conditional where half the pixels take each path costs the sum of both paths. Memory
access is fast when neighbouring threads read neighbouring addresses and slow when
they scatter, because the hardware coalesces contiguous accesses into single
transactions.


shaders_and_gpu_graphics

The rasterization pipeline transforms geometry into pixels through fixed stages. The
vertex shader runs once per vertex, transforming positions from model space through
world, view, and clip space, and passing per-vertex attributes onward. Primitive
assembly groups vertices into triangles. Clipping discards geometry outside the view
frustum and splits triangles that straddle it. The rasterizer determines which pixels
a triangle covers and interpolates the vertex attributes across them, perspective-
correctly. The fragment shader runs once per covered pixel and computes a colour.
Finally per-fragment operations apply the depth test, stencil test, and blending
before writing to the framebuffer.


shaders_and_gpu_graphics

The coordinate transformations are the part most often gotten wrong, and the order
matters because matrix multiplication does not commute. Model space is the mesh's own
frame; the model matrix places it in world space; the view matrix, the inverse of the
camera's transform, moves the world into the camera's frame; the projection matrix maps
the view frustum into clip space, a cube in homogeneous coordinates. The perspective
divide by w then yields normalized device coordinates, and the viewport transform maps
those to pixels. The composite is often precomputed as a single MVP matrix, applied as
`gl_Position = projection * view * model * vec4(position, 1.0)` — read right to left.


shaders_and_gpu_graphics

Pipeline stages and where work belongs:
  vertex shader      per-vertex; cheap because vertices are far fewer than pixels;
                     do as much as possible here and interpolate the result
  tessellation       optional; subdivides patches on the GPU for adaptive detail
  geometry shader    optional; can emit new primitives; notoriously slow, avoid
  rasterizer         fixed function; interpolates with perspective correction
  fragment shader    per-pixel; the expensive stage, run millions of times
  blending           fixed function; order-dependent for transparency
  compute shader     outside the pipeline; general-purpose, arbitrary read/write


shaders_and_gpu_graphics

Normals require special handling in the transformation chain and this catches
everyone once. A normal is perpendicular to a surface, and under non-uniform scaling
the naive transform destroys that perpendicularity — scale a sphere into an ellipsoid
and normals transformed by the model matrix no longer point outward. The correct
transform is the inverse transpose of the upper-left 3x3 of the model matrix, which
reduces to the matrix itself for pure rotation, so the bug is invisible until someone
scales an object unevenly and the lighting goes wrong in a way that is hard to
attribute.


shaders_and_gpu_graphics

Q: A fragment shader contains a conditional where roughly half the pixels in each
region take each branch. Compared with a version taking one branch uniformly, the cost
is approximately:
A. The same
B. Half
C. The sum of both branches
D. The maximum of the two branches
Reasoning: Threads execute in lockstep groups. When threads within a group diverge, the
hardware executes both paths serially with inactive lanes masked, so the group pays for
both. Divergence that is coherent across whole groups — a branch on a uniform, or on
large screen regions — costs only the taken path. Answer: C.


shaders_and_gpu_graphics

## GLSL and Shader Language Fundamentals

GLSL is a C-like language with first-class vector and matrix types and pervasive
component-wise operations. Vectors up to four components support swizzling, so
`v.xyz`, `v.rgb`, `v.bgra`, and `v.xxyy` are all valid reads, and swizzles can appear
on the left of an assignment as long as no component repeats. Arithmetic operators
apply component-wise, and multiplying a matrix by a vector performs the linear
transform. This expressiveness is why shader code reads so densely compared with CPU
code doing the same work.


shaders_and_gpu_graphics

The built-in functions are hardware-accelerated and should be preferred over
hand-written equivalents essentially always. `mix(a, b, t)` is linear interpolation and
is a single instruction. `clamp(x, lo, hi)` and `saturate`-style `clamp(x, 0.0, 1.0)`
are free on most hardware as an output modifier. `step(edge, x)` returns 0 or 1 and
replaces a branch with arithmetic. `smoothstep(e0, e1, x)` gives a Hermite ramp with
zero derivative at both ends, and it is the single most useful function in creative
shader work because it produces antialiased edges, soft masks, and eased transitions
in one call.


shaders_and_gpu_graphics

Precision qualifiers matter on mobile and in WebGL. `highp` is typically 32-bit float,
`mediump` around 16-bit, `lowp` lower still. Fragment shaders on mobile GPUs default
to `mediump` unless specified, and a mediump float has roughly three decimal digits of
precision with a limited exponent range — enough for colour, insufficient for world-
space positions or for time values that grow without bound. A shader that works on
desktop and shows banding, jitter, or complete breakdown on mobile after a few minutes
of runtime is nearly always a precision problem, and the classic instance is passing
elapsed seconds as a mediump uniform, which loses the ability to represent fractional
seconds once the value grows past a few thousand.


shaders_and_gpu_graphics

GLSL essentials by category:
  types           float, vec2/3/4, mat2/3/4, int, ivec, bool, sampler2D
  swizzling       v.xyzw, v.rgba, v.stpq; repeatable on read, unique on write
  interpolation   mix(a,b,t), smoothstep(e0,e1,x), step(edge,x)
  geometry        length, distance, dot, cross, normalize, reflect, refract
  math            abs, sign, floor, ceil, fract, mod, min, max, clamp, pow,
                  exp, log, sqrt, inversesqrt
  trig            sin, cos, tan, asin, acos, atan(y,x)
  derivatives     dFdx, dFdy, fwidth — screen-space gradients, for antialiasing
  texture         texture(sampler, uv), textureLod, texelFetch
  qualifiers      uniform (constant per draw), in/out (stage interface),
                  flat (no interpolation), const


shaders_and_gpu_graphics

`fract` and `mod` are the workhorses of procedural pattern generation because they
create repetition. `fract(uv * 10.0)` tiles the unit square ten times in each axis,
giving each tile local coordinates in [0,1] — the foundation of nearly every grid-based
effect. The subtlety is that `mod` in GLSL is defined as `x - y * floor(x/y)`, which
gives a positive result for negative inputs, unlike C's `fmod` which truncates toward
zero. Code ported from CPU to shader that relies on the sign of a modulus will behave
differently, and patterns that look correct in the positive quadrant break across the
origin.


shaders_and_gpu_graphics

Antialiasing procedural patterns uses the screen-space derivative functions. A hard
`step` produces jagged edges because it changes discretely between adjacent pixels;
replacing it with `smoothstep(-w, w, x)` where `w = fwidth(x)` produces a transition
exactly one pixel wide regardless of zoom level, because `fwidth` reports how fast the
value changes per pixel. This one technique separates amateur from professional
procedural rendering, and it costs almost nothing.


shaders_and_gpu_graphics

## Signed Distance Fields and Raymarching

A signed distance function returns, for any point in space, the distance to the nearest
surface, negative inside and positive outside. Raymarching renders these by stepping
along a ray from the camera, at each step advancing by exactly the distance returned —
which is guaranteed safe, since nothing is closer than that — until the distance falls
below a threshold (a hit) or the ray exceeds a maximum distance or step count (a miss).
This sphere tracing procedure converges quickly in open space and slows near grazing
surfaces where the distance stays small.


shaders_and_gpu_graphics

The appeal for generative art is that SDFs compose algebraically. Union is the minimum
of two distances, intersection is the maximum, and subtraction is the maximum of one
and the negation of the other. Smooth versions of these operators blend surfaces
organically with a single parameter, which produces the characteristic melted,
continuous forms of the medium. Infinite repetition costs one line — take the modulus
of the position before evaluating — so an entire infinite lattice of objects renders at
the same cost as one. Domain distortion, twisting or bending the input coordinate before
evaluating, warps geometry without touching the primitives.


shaders_and_gpu_graphics

Primitive SDFs and operations:
  sphere, radius r        length(p) - r
  box, half-extents b     length(max(abs(p) - b, 0.0)) + min(max(...), 0.0)
  plane, normal n         dot(p, n) + h
  torus, radii t          length(vec2(length(p.xz) - t.x, p.y)) - t.y
  capsule a to b, r       length(p - closest_point_on_segment) - r
  union                   min(d1, d2)
  intersection            max(d1, d2)
  subtraction             max(d1, -d2)
  smooth union, k         h = clamp(0.5 + 0.5*(d2-d1)/k, 0, 1);
                          mix(d2, d1, h) - k*h*(1-h)
  repetition, period c    p = mod(p + 0.5*c, c) - 0.5*c
  round by r              d - r
  onion shell, t          abs(d) - t


shaders_and_gpu_graphics

Normals come free from the gradient of the distance field, approximated by central
differences: sample the SDF at small offsets along each axis and normalize the
resulting vector. This is four to six extra field evaluations per pixel, which is the
main reason raymarched scenes are expensive, and the tetrahedral four-sample variant is
the standard optimization over the six-sample central difference.


shaders_and_gpu_graphics

Two correctness pitfalls recur. First, non-uniform scaling breaks the distance
property: scaling the input coordinate by a non-uniform factor yields a function that is
no longer a true distance, so raymarching overshoots and produces artifacts. The remedy
is to scale uniformly and multiply the result by the scale factor, or to divide the
result by the largest scale component as a conservative bound. Second, most
"distance functions" for complex shapes are actually lower bounds rather than exact
distances, and if the bound is loose the march takes many small steps or, if it ever
overestimates, punches through surfaces. Multiplying every step by a factor slightly
below one is the standard defensive measure.


shaders_and_gpu_graphics

[user] My raymarched scene renders correctly but drops to 12 fps at 1440p and the
profiler says the fragment shader is the bottleneck.
[assistant] tool_call gpu.shader_profile({"resolution": [2560, 1440], "fps": 12,
"stage": "fragment", "max_steps": 256, "epsilon": 0.0001, "normal_samples": 6,
"sdf_primitives": 34})
[tool] {"pixels": 3686400, "avg_steps_per_ray": 97, "sdf_evals_per_frame": 3.9e8,
"normal_eval_share": 0.31, "shadow_ray_share": 0.28, "hot_spots":
["no_early_exit_on_max_dist", "six_sample_normals", "full_res_shadows"]}
[assistant] You are evaluating the SDF about 390 million times per frame. Every fix
below reduces that count rather than making each evaluation faster.


shaders_and_gpu_graphics

Biggest win first: your normals use six samples and account for 31% of all SDF
evaluations. Switch to the tetrahedral four-sample gradient — it is a drop-in
replacement with visually identical results and cuts that third by a third.


shaders_and_gpu_graphics

Second: shadow rays are another 28%. Raymarched soft shadows are notoriously
expensive because each one is a full march. Halve their step budget, since shadow rays
tolerate far more error than primary rays, and raise their epsilon by an order of
magnitude. Better still, render shadows at half resolution into a buffer and upsample —
shadow terms are low-frequency and the difference is rarely visible.


shaders_and_gpu_graphics

Third: 97 average steps against a 256 cap suggests rays are marching a long way before
giving up. Add an early exit on total distance, and make epsilon distance-dependent —
scale it with the distance travelled, since a surface 100 units away does not need
0.0001 precision to look correct. This alone typically cuts average steps by 30-40%.


shaders_and_gpu_graphics

Two structural options if that is not enough. Render at 70% resolution and upscale;
raymarched imagery is soft and this is usually imperceptible while cutting pixel count
in half. And add a cheap bounding-volume test before the full march — if 34 primitives
are all evaluated for every ray, a spatial early-out for rays that cannot possibly hit
most of them is a large saving.


shaders_and_gpu_graphics

Expect 12 fps to reach 45-60 with the normal, shadow, and epsilon changes alone.


shaders_and_gpu_graphics

## Noise and Procedural Generation

Noise functions are the raw material of procedural art. The requirement is a function
that looks random but is deterministic, continuous, and reproducible from a coordinate
alone — no memory, no state, evaluable in parallel for every pixel independently.


shaders_and_gpu_graphics

Value noise assigns random values to lattice points and interpolates between them,
which is simple and produces visible axis-aligned blockiness unless carefully filtered.
Gradient noise, of which Perlin noise is the original, assigns random *gradients* to
lattice points and interpolates the resulting dot products, giving a smoother result
with no obvious grid alignment and a value of zero at every lattice point. Simplex
noise replaces the hypercube lattice with a simplex tiling, reducing the number of
corners to interpolate from 2^n to n+1, which makes it substantially faster in three
dimensions and above and removes directional artifacts. Worley or cellular noise
scatters feature points and returns the distance to the nearest, producing the
characteristic organic cell structures used for water caustics, cracked earth, and
scales.


shaders_and_gpu_graphics

Fractal Brownian motion layers noise at successive octaves, each at double the
frequency and roughly half the amplitude of the last. The amplitude ratio, the
persistence, controls the roughness: 0.5 gives a natural-looking result, lower values
give smoother forms, higher values approach white noise. Four to six octaves is usually
sufficient, since further octaves contribute detail below the pixel scale and cost the
same as the first.


shaders_and_gpu_graphics

Noise recipes:
  hash (no texture)   fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453)
                      cheap, ubiquitous, precision-dependent — breaks on some
                      mobile GPUs; integer bit-mix hashes are more robust
  fBm                 sum over octaves of amp * noise(p * freq),
                      freq *= 2.0, amp *= persistence
  turbulence          same but using abs(noise); creates creases and ridges
  ridged              1.0 - abs(noise), squared; produces mountain ridgelines
  domain warp         noise(p + noise(p)); the single highest-impact technique for
                      organic form — warping the input coordinate by another noise
                      field produces flowing, marbled structure
  curl noise          divergence-free vector field from noise derivatives; gives
                      incompressible-looking fluid motion for particles


shaders_and_gpu_graphics

Domain warping deserves emphasis because it is the technique that most reliably turns
generic noise into something that looks designed. Evaluating noise at a position that
has itself been displaced by another noise field produces swirls, filaments, and
marbling that no amount of octave stacking achieves. Applying it twice — warping the
warp — produces the intricate, flowing structures characteristic of the best
procedural work, at the cost of tripling the noise evaluations.


shaders_and_gpu_graphics

Randomness in generative art is a design material rather than a source of chaos. The
practical discipline is to seed deterministically so a pleasing output can be
reproduced and refined, to constrain the random ranges tightly enough that every
sample is acceptable rather than filtering the failures by hand, and to distinguish
parameters that should vary per piece from those that define the series. A generative
system whose outputs all look alike has too little variance; one whose outputs are
individually unpredictable in quality has too much, and the work of the artist is
largely in tuning that boundary.


shaders_and_gpu_graphics

## Colour, Lighting, and Output

Colour handling is where technically correct shaders most often look wrong. The core
issue is that sRGB, the standard colour space for displays and image files, is not
linear: it applies a gamma curve of approximately 2.2 so that the limited bit depth is
distributed according to human perceptual sensitivity, which is far finer in the darks.
Light, however, adds linearly. Averaging two sRGB values does not average the light
they represent, so blending, blurring, lighting, and antialiasing performed directly on
sRGB values produce results that are systematically too dark in the midtones.


shaders_and_gpu_graphics

The correct pipeline converts sRGB inputs to linear on read, performs all arithmetic in
linear space, and converts back to sRGB on write. Modern APIs do this in hardware with
sRGB texture formats and sRGB framebuffers, which is both faster and more accurate than
doing it manually with a pow. The visible symptom of getting it wrong is familiar: a
gradient between red and green that goes muddy brown in the middle rather than passing
through a bright yellow-olive, and a Gaussian blur that darkens the image overall.


shaders_and_gpu_graphics

Perceptual colour spaces solve a different problem. Interpolating between two colours
in RGB, even linear RGB, traverses a path that is not perceptually uniform — equal
steps do not look equally different, and hue shifts appear along the way. HSL and HSV
are trivially computed and only marginally better, since their lightness axis does not
correspond to perceived brightness. CIELAB and its successors are designed for
perceptual uniformity, and the recent OKLab and OKLCH are the practical modern choice:
interpolation in OKLCH produces smooth, predictable gradients with stable hue and
uniform lightness steps, which is why it has been adopted into CSS.


shaders_and_gpu_graphics

Colour and lighting reference:
  sRGB to linear      c <= 0.04045 ? c/12.92 : pow((c+0.055)/1.055, 2.4)
  linear to sRGB      c <= 0.0031308 ? 12.92*c : 1.055*pow(c, 1/2.4) - 0.055
  luminance (Rec709)  dot(linear_rgb, vec3(0.2126, 0.7152, 0.0722))
  Lambert diffuse     max(dot(N, L), 0.0) * albedo * light_color
  Blinn-Phong spec    pow(max(dot(N, normalize(L + V)), 0.0), shininess)
  Fresnel (Schlick)   F0 + (1 - F0) * pow(1 - dot(N, V), 5.0)
  ambient occlusion   darkens creases; approximated in SDFs by sampling the field
                      along the normal
  tone mapping        maps unbounded HDR radiance into [0,1]; ACES and the
                      Khronos neutral curve are the common choices
  dithering           add ~1/255 of noise before quantizing; removes banding in
                      smooth gradients at 8-bit output


shaders_and_gpu_graphics

Fresnel is the effect that most improves the perceived realism of a shaded surface for
the least code. Every material becomes more reflective at grazing angles — the reason a
road looks mirror-like into the distance and matte underfoot — and Schlick's
approximation captures it in one line. Adding a Fresnel term to an otherwise flat
shaded object immediately gives it a sense of material and volume.


shaders_and_gpu_graphics

Banding in smooth gradients is a quantization artifact of 8-bit output, not a shader
bug, and it is unavoidable when a gradient spans fewer than 256 distinct values across
many pixels. Adding a small amount of noise before quantization — on the order of one
least-significant bit, ideally a blue-noise or ordered dither pattern rather than white
noise — converts the visible contour lines into imperceptible grain. This is the last
step of nearly every polished shader and is routinely omitted, which is why so much
otherwise careful work shows contour rings in dark gradients.


typography_and_layout

## Letterform Anatomy and Classification

Typography is the arrangement of type to make written language legible, readable, and
expressive, and the vocabulary for discussing it begins with the letterform's parts. The
distinctions matter because they are what makes typefaces different from each other and what
determines how a face performs at a given size and medium.


typography_and_layout

The x-height — the height of a lowercase letter without ascenders — is the most consequential
measurement and is not implied by the point size. Two faces set at the same point size can have
substantially different apparent sizes because their x-heights differ, so matching point sizes
across faces produces mismatched visual weight. A large x-height improves legibility at small
sizes by making the letterform's distinguishing features larger, and it reduces the distinction
between ascenders and descenders that helps word-shape recognition at reading sizes.


typography_and_layout

Counters — the enclosed and partially enclosed spaces within letters — determine how a face
performs under adverse conditions. Open counters remain distinguishable at small size, at low
resolution, and at distance; closed or tight counters fill in and letters become
indistinguishable. This is why faces designed for signage, for small text, and for low-resolution
screens have notably open apertures.


typography_and_layout

Letterform anatomy:
  baseline             the line the letters sit on
  x-height             lowercase height without ascenders; determines apparent size
                       more than point size does
  cap height           uppercase height
  ascender, descender  the parts above the x-height and below the baseline
  counter              the enclosed space within a letter
  aperture             the opening of a partially closed counter; open apertures
                       survive small size and low resolution
  stroke contrast      the variation between thick and thin; high contrast is
                       elegant at display size and fragile at text size
  stress               the axis of the thinnest parts; vertical or angled
  terminal             how a stroke ends
  serif                the small terminal stroke
  ligature             joined characters; standard ones fix collisions, and
                       discretionary ones are decorative
  optical size         a face designed for a specific size range; text cuts have
                       larger x-height, lower contrast, and looser spacing than
                       display cuts of the same family


typography_and_layout

Classification groups typefaces by historical and structural characteristics, and the value is
that the groups behave differently rather than merely looking different. Old style faces have
angled stress, moderate contrast, and bracketed serifs, and they set comfortably at length.
Transitional and modern faces increase contrast and verticalize the stress, becoming more elegant
and less robust at small size. Slab serifs have heavy rectangular serifs and read as sturdy. Sans
serifs remove the serifs entirely and divide into grotesque, neo-grotesque, humanist, and
geometric subgroups whose differences in letterform construction produce genuinely different
reading experiences.


typography_and_layout

Q: Two typefaces are set at the same point size and one appears substantially larger. The most
likely explanation is:
A. One is bold
B. They have different x-heights, which determines apparent size far more than the point size
   does
C. The tracking differs
D. One is a display face
Reasoning: Point size describes the em, which is a design space rather than a measured letter
dimension, and the proportion of it occupied by the lowercase letters varies substantially between
faces. Matching point size across faces therefore does not match apparent size, and setting them
to matching x-heights is what produces visual consistency. Answer: B.


typography_and_layout

## Spacing, Rhythm, and Scale

Spacing operates at three levels and each has a distinct name and purpose. Kerning adjusts the
space between specific character pairs whose default spacing collides or gaps — the pairs
involving diagonal and round letters against straight ones are the usual cases. Tracking adjusts
the spacing uniformly across a run, which is used to adjust colour and to fit copy. Word spacing
separates words, and its relationship to letter spacing determines whether words read as units.


typography_and_layout

The relationship between these is what produces even texture. Word spacing should be
noticeably larger than letter spacing so that words separate visually, and noticeably smaller than
line spacing so that lines read as horizontal units rather than the eye jumping between them.
Violating either produces text that is technically legible and effortful to read: too-tight word
spacing merges words, and too-loose word spacing at large tracking produces rivers of white space
running vertically through a paragraph.


typography_and_layout

The measure — the line length — has a well-established comfortable range of roughly 45 to 75
characters, and the reasons are mechanical. A much longer line makes the return sweep to the
beginning of the next line error-prone, so readers lose their place and re-read. A much shorter
line breaks the reading rhythm with too-frequent returns and produces excessive hyphenation or
ragged edges. Line height should increase with measure, because a longer line requires more
vertical separation for the return sweep to land reliably.


typography_and_layout

Spacing and scale:
  kerning              pair-specific adjustment; matters most at display size
  tracking             uniform adjustment across a run; tighten at display size,
                       loosen for small caps and for light text on dark
  word spacing         larger than letter spacing, smaller than line spacing
  rivers               vertical channels of white space in justified text; a
                       symptom of too-wide word spacing without hyphenation
  measure              45-75 characters for body text
  leading              line height; 1.4-1.6 for body, more for longer measures,
                       tighter for headings
  vertical rhythm      consistent baseline spacing down the page; aligns columns
                       and produces coherence
  type scale           a ratio between sizes; 1.125 to 1.333 are the common range
  modular scale        sizes derived from a ratio rather than chosen individually
  hierarchy            three or four distinct levels; more produces confusion
                       rather than more information
  weight over size     for small distinctions, weight differentiates more
                       economically than size
  optical alignment    align by appearance rather than by bounding box; a round
                       letter or a quotation mark must overhang slightly to appear
                       aligned


typography_and_layout

Optical alignment deserves emphasis because mechanical alignment looks wrong. A round letter at
the start of a line, aligned so its bounding box matches the flat letters above and below, appears
inset because less of its area is at the margin. A quotation mark aligned mechanically appears to
push the text inward. Correcting these — hanging punctuation outside the measure and slightly
overhanging round forms — makes the margin appear straight, and the correction is invisible when
present and conspicuous when absent.


typography_and_layout

## Grids and Layout Systems

A grid is a structure of columns, rows, and margins organizing a layout, and its purpose is
consistency and speed rather than restriction. A grid makes alignment decisions once rather than
per element, which means every element relates to every other through a shared structure, and it
converts layout from a series of individual judgments into a set of choices within a system.


typography_and_layout

The column count determines flexibility. A twelve-column grid divides evenly into halves, thirds,
quarters, and sixths, which is why it became the standard for web layout. Fewer columns are
simpler and less flexible; more are flexible and produce columns too narrow to be individually
meaningful. The gutter between columns must be wide enough that adjacent content reads as
separate, and its width relative to the column determines the layout's density.


typography_and_layout

Modular grids add horizontal divisions, producing a field of modules that content can occupy in
various spans. This suits content with varied element sizes — a catalogue, a dashboard, an
editorial page with images and text at several scales — and it enforces vertical alignment that a
column grid alone does not.


typography_and_layout

Grids and layout:
  column grid          vertical divisions; twelve divides conveniently
  gutter               the space between columns; wide enough to separate
  margin               the space at the edges; generous margins read as considered
  modular grid         columns plus rows; a field of modules
  baseline grid        text baselines align across columns; produces vertical
                       coherence and is demanding to maintain
  the grid is a tool   breaking it deliberately at one point creates emphasis;
                       breaking it accidentally reads as error
  white space          an active element; reducing it to fit more content reduces
                       how much is read
  proximity            spacing communicates grouping more strongly than any label
  alignment            elements sharing an edge read as related; misalignment
                       reads as carelessness even when unnoticed consciously
  visual hierarchy     size, weight, colour, position, and isolation
  scanning patterns    readers scan rather than read; the F and Z patterns
                       describe typical paths and vary with content type
  responsive layout    the grid adapts; content order and priority must be decided
                       for each breakpoint rather than emerging


typography_and_layout

The relationship between white space and how much is read deserves stating because the
intuition runs the other way. Reducing margins and spacing to fit more content on a page increases
what is present and decreases what is absorbed, because the structure that made the content
scannable — the grouping, the hierarchy, the visual rest — is what allowed a reader to find and
engage with any part of it. A dense page is read less thoroughly than a sparse one containing less,
and the instruction to fill empty space is almost always a request to reduce the design's
effectiveness.


typography_and_layout

## Editorial and Screen Typography

Typography for extended reading has requirements that display typography does not. The
paramount consideration is that the reader should not notice the typography at all — anything
drawing attention to the letterforms interrupts reading, so a text face is judged by its
invisibility. This is why the faces used for books are conservative and why an expressive display
face becomes exhausting at length.


typography_and_layout

Justified and ragged-right setting differ in their failure modes. Justified text has even
margins on both sides and requires the word spacing to vary line by line, which without
hyphenation produces conspicuous gaps and rivers. Ragged right keeps the word spacing even and
produces an uneven right margin, which should itself be shaped — a rag with a deep indentation
followed by a full line, or a sequence of lines of similar length, both draw attention. Justified
setting requires hyphenation to work, and hyphenation quality varies enormously by language and by
implementation.


typography_and_layout

Screen typography adds constraints that print does not. The resolution was historically far
lower, which drove hinting and the preference for faces with open apertures and simple forms, and
the constraint has substantially relaxed on high-density displays. The reading distance and angle
vary. The size is adjustable by the reader and must be respected. And the rendering differs by
platform in ways that are not controllable, so a design must be robust to the variation rather
than tuned to one rendering.


typography_and_layout

Editorial and screen:
  text face invisibility  a text face is judged by not being noticed
  justified            even margins; requires hyphenation to avoid rivers
  ragged right         even word spacing; the rag itself should be shaped
  hyphenation          essential for justified setting; language dependent
  widows and orphans   a single line separated from its paragraph; avoid
  paragraph indication  first-line indent or space between; not both
  emphasis             italic for gentle emphasis, bold for strong; underline is a
                       hyperlink convention on screen and should not be used for
                       emphasis there
  all caps             slows reading substantially by removing word shape; use for
                       short labels only
  contrast requirement  4.5:1 for body text; light grey on white is the most
                       common screen readability failure
  respect user settings  text must scale with the reader's preference; fixed pixel
                       sizing defeats it
  web font loading     causes layout shift; match fallback metrics with
                       size-adjust and the override descriptors, or use a display
                       strategy that avoids the swap
  system font stack    fast, familiar, zero loading cost; a legitimate choice
                       rather than a compromise
  variable fonts       one file spanning a design space; smaller than several
                       static weights and permits fine adjustment


typography_and_layout

Variable fonts deserve emphasis because they change what is practical. A traditional family
requires a separate file per weight and width, so a design using four weights loads four files,
and intermediate values are unavailable. A variable font encodes a continuous design space in one
file, typically smaller than three static weights, and permits any value along each axis. The
practical consequences are that fine optical adjustments become available — a slightly heavier
weight for light-on-dark text, an optical size axis adjusting the design for the rendered size —
and that responsive typography can vary the weight and width continuously with the viewport rather
than switching between discrete files.


typography_and_layout

## Generative and Computational Typography

Typography in generative work spans from using type as a design element within a generated
composition to generating the letterforms themselves, and the two require different techniques.


typography_and_layout

Type as an element within generative composition benefits from the same discipline as any other
constrained system: a defined type scale, a limited set of weights, and consistent spacing
relationships produce output that reads as designed rather than as arbitrary. The failure mode is
sampling sizes and positions freely, which produces compositions that are individually plausible
and collectively incoherent, and the remedy is the same constraint that makes any generative
system cohere.


typography_and_layout

Type on a path, along a curve, or distributed within a shape requires solving the spacing
correctly. Placing glyphs at uniform parameter intervals along a Bezier curve produces uneven
spacing, because the parameter is not arc length — the same problem that affects any object placed
along a curve. Computing the arc length and placing each glyph at the correct cumulative distance,
accounting for its own advance width, is what produces even setting.


typography_and_layout

Generating letterforms computationally is a different discipline. Parametric type design defines
letters by a skeleton and a set of parameters — weight, width, contrast, terminal shape — from
which the outlines are constructed, so a whole family or a continuous design space is generated
from one definition. This is what variable font technology exposes at the file format level, and
tools for parametric design predate it substantially.


typography_and_layout

Generative typography:
  constrain the scale  a defined set of sizes and weights; free sampling produces
                       incoherence
  type on a path       place by arc length, not by parameter; account for each
                       glyph's advance width
  glyph outlines       quadratic or cubic Bezier contours with a fill rule; the
                       raw material for manipulation
  outline manipulation  offsetting, distorting, interpolating, and reconstructing
                       from the contours
  interpolation        between two compatible outlines; requires matching point
                       counts and orders, which is why compatible masters are
                       designed together
  parametric design    skeleton plus parameters; generates a family or a
                       continuous space
  variable font axes   weight, width, optical size, slant, and custom axes;
                       registered and arbitrary
  font metrics         advance width, side bearings, kerning pairs; needed for
                       correct setting and frequently ignored in generative work
  text rendering       shaping applies substitutions and positioning per script;
                       naive glyph-by-glyph placement fails for many writing
                       systems entirely
  complex scripts      Arabic contextual forms, Indic reordering and conjuncts;
                       correct rendering requires a shaping engine rather than
                       character-to-glyph mapping
  legibility floor     generated type should remain readable unless
                       unreadability is the point, and that decision should be
                       deliberate


typography_and_layout

Text shaping deserves the closing emphasis because it is where naive computational typography
fails completely for much of the world's writing. Rendering Latin text by mapping each character
to a glyph and advancing by its width is approximately correct. Arabic requires each letter to
take one of four contextual forms depending on its neighbours and requires ligature substitution.
Indic scripts require reordering, where a vowel written after a consonant in the encoding is
displayed before it, and require conjunct formation combining consonant clusters into single
glyphs. A rendering pipeline that maps characters to glyphs directly produces text that is
unreadable rather than merely imperfect, and using a proper shaping engine is not an
internationalization refinement but a correctness requirement.


typography_in_practice

## Letterforms and Type Anatomy

A typeface is a designed system of letterforms, and its consistency comes from shared proportions
and shared construction rather than from letters resembling each other. The relevant measurements
are the x-height, the height of lowercase letters without ascenders; the cap height; the ascender and
descender extents; and the relationship among them, which determines how large a typeface appears at
a given nominal size far more than the nominal size does.


typography_in_practice

This is why two typefaces set at the same point size can look very different in scale. Point size
measures the em, an abstract box, not any visible feature, so a typeface with a large x-height
relative to its em appears larger and generally reads better at small sizes. Comparing typefaces
requires setting them to matching x-heights rather than to matching point sizes, which is a
practical adjustment that most software does not make automatically.


typography_in_practice

Stroke construction distinguishes the broad categories. Serif faces have terminating strokes whose
form and contrast reflect their historical origins in written and engraved letterforms. Sans serif
faces omit them and vary in whether their skeleton is geometric, humanist, or neutral. Contrast —
the difference between thick and thin strokes — is the single most consequential characteristic for
legibility at small sizes and for behaviour at large ones, since high contrast is elegant in display
and disappears in body text at low resolution.


typography_in_practice

Type anatomy:
  x-height             lowercase height without ascenders; the perceived size
                       driver
  cap height           uppercase height
  ascender and descender  the extents above and below
  the em               an abstract box; what point size measures
  the comparison consequence  matching point sizes does not match apparent size
  the practical adjustment  set to matching x-heights when comparing
  serif                terminating strokes; historical origins in writing and
                       engraving
  sans serif           without them; geometric, humanist, or neutral skeletons
  stroke contrast      thick to thin difference
  the contrast tradeoff  elegant in display, fragile at small sizes
  counters             the enclosed spaces; open counters read better small
  aperture             how open the terminals are; strongly affects legibility
  weight and width     the two primary axes of a family
  optical sizes        separate designs for small and large use; the historical
                       norm, lost in early digital type, and returning with
                       variable fonts


typography_in_practice

Q: Two typefaces are set at the same point size and one appears noticeably larger. Why?
A. One file is scaled incorrectly
B. Point size measures the em box rather than any drawn feature, so a typeface whose x-height is a
   larger fraction of its em appears larger; matching apparent size requires matching x-heights, not
   point sizes
C. The rendering differs
D. One has a larger cap height
Reasoning: The em is an abstract unit that the designer fills as they choose. X-height relative to
em varies widely across typefaces, and since most of the text a reader sees is lowercase, x-height
dominates perceived size. This is why substituting one typeface for another at the same size
frequently requires a size adjustment. Answer: B.


typography_in_practice

## Font Technology and Rendering

A font file contains outlines, metrics, and tables describing behaviour. The outlines are described
by curves — quadratic or cubic depending on the format — that a rasterizer fills. Metrics give each
glyph's advance width and the spacing adjustments between specific pairs. Feature tables describe
substitutions and positioning that the layout engine applies, which is what makes ligatures,
contextual alternates, and complex script shaping possible.


typography_in_practice

Rendering converts outlines to pixels, and at typical text sizes the stem widths are on the order of
one or two pixels, so the fit between the outline and the pixel grid dominates the result. Hinting
is instruction embedded in the font that adjusts the outline at small sizes to align features with
the grid, producing crisp consistent stems at the cost of distorting the design. Modern
high-resolution displays reduce the need for it substantially, and rendering stacks have moved
toward respecting the outline and relying on antialiasing.


typography_in_practice

Antialiasing uses intermediate grey values to represent partial coverage, which the eye integrates
into a smoother shape. Subpixel rendering goes further by addressing the individual colour elements
of an LCD, tripling the effective horizontal resolution at the cost of colour fringing and
dependence on the display's subpixel arrangement, which is why it is applied less than it once was.
Gamma handling determines whether antialiased text appears the correct weight, and incorrect gamma
is why the same text can look too thin on one system and too heavy on another.


typography_in_practice

Font technology and rendering:
  outlines             curves filled by a rasterizer
  metrics              advance widths and pair adjustments
  kerning              adjustment between specific pairs
  feature tables       substitutions and positioning applied by the layout engine
  ligatures            glyph substitutions for specific sequences
  contextual alternates  glyphs chosen by surrounding context
  the pixel grid problem  stems one or two pixels wide at text sizes
  hinting              instructions aligning features to the grid
  the hinting tradeoff  crisp stems, distorted design
  high resolution      reduces the need substantially
  antialiasing         grey values representing partial coverage
  subpixel rendering   addressing an LCD's colour elements
  the subpixel costs   colour fringing and display dependence
  gamma handling       determines the apparent weight of antialiased text
  the cross-platform difference  identical text appearing thin on one system and
                       heavy on another, almost always a gamma or stem-darkening
                       difference rather than a font difference


typography_in_practice

## Text Layout and Typesetting

Layout arranges glyphs into lines and lines into blocks, and a small number of parameters carry most
of the readability. Line length is the most important: too short and the eye jumps back constantly,
too long and it loses the return position, with the comfortable range being roughly a alphabet and a
half to two and a half alphabets of characters. Line spacing must increase with line length, since a
longer line needs more vertical separation for the eye to find the next one reliably.


typography_in_practice

Justification distributes extra space to make lines flush at both edges, and doing it well requires
more than adding space between words. A greedy line-breaking algorithm that fills each line as much
as possible produces uneven spacing and rivers of white running down the block. A paragraph-level
algorithm that minimizes total badness across all lines produces markedly better results by
accepting a worse line here to enable a better one there, and it is available in typesetting systems
and generally not in web browsers.


typography_in_practice

Hyphenation reduces the spacing variation that justification requires, and it needs language-specific
rules or dictionaries since hyphenation points depend on morphology. Without it, justified text in a
narrow column has spacing so uneven that ragged-right setting is usually better. The practical
guidance is that justification without good hyphenation and good line breaking is worse than not
justifying at all.


typography_in_practice

Text layout:
  line length          the primary readability parameter
  the comfortable range  roughly one and a half to two and a half alphabets
  line spacing         must increase with line length
  the relationship     longer lines need more separation to find the next
  paragraph indication  indent or space, not both
  greedy line breaking  fills each line; uneven spacing and rivers
  paragraph optimization  minimizes total badness across lines
  the improvement      accepting a worse line to enable a better one
  availability         typesetting systems yes, browsers generally not
  hyphenation          reduces spacing variation
  language dependence  hyphenation points follow morphology
  the practical guidance  justification without hyphenation is worse than ragged
                       right
  widows and orphans   isolated lines at column boundaries; controlled by
                       adjusting the break, not by editing the text
  optical margin alignment  hanging punctuation slightly outside the margin so
                       the edge reads as straight; a small refinement with a
                       disproportionate effect on the perceived quality of a
                       block of text


typography_in_practice

## Internationalization and Complex Scripts

Text rendering beyond simple left-to-right alphabetic scripts requires capability that many systems
lack. Bidirectional text mixes right-to-left and left-to-right runs in one paragraph, and resolving
the display order requires an algorithm operating on character properties and embedding levels
rather than on simple reversal. Getting it wrong produces text that is not merely ugly but reordered
into a different meaning.


typography_in_practice

Complex scripts require shaping: the glyph drawn depends on context. Arabic letters have different
forms initially, medially, finally, and in isolation. Indic scripts form conjunct consonants and
reposition vowel marks around a cluster in ways that do not correspond to the storage order.
Handling these correctly requires a shaping engine and a font with the relevant feature tables, and
substituting a font without them produces text that is readable to nobody.


typography_in_practice

The unit distinctions matter for any text processing. A code point is one entry in the character
encoding. A grapheme cluster is what a user perceives as a character, which may be several code
points combined. A glyph is what is drawn, which may be one for several code points or several for
one. Cursor movement, selection, and character counting must operate on grapheme clusters, and code
that operates on code points or on encoded units produces cursors that land inside a character and
counts that surprise users.


typography_in_practice

Internationalization:
  bidirectional text   mixed direction runs in one paragraph
  the resolution algorithm  character properties and embedding levels
  the failure mode     reordering that changes meaning
  shaping              the glyph depends on context
  Arabic forms         initial, medial, final, isolated
  Indic clusters       conjuncts and repositioned marks
  the storage mismatch  display order differing from storage order
  shaping engines      required, along with fonts carrying the feature tables
  code point           one entry in the encoding
  grapheme cluster     what a user perceives as a character
  glyph                what is drawn
  the many-to-many relationship  none of the three correspond one to one
  cursor and selection  must operate on grapheme clusters
  string length        an ambiguous question; specify which unit
  font fallback        substituting another font for missing glyphs; the chain
                       and its ordering determine whether mixed-script text looks
                       coherent or assembled from unrelated designs
  vertical writing     supported by some scripts and requiring rotated and
                       substituted forms for others


typography_in_practice

## Variable Fonts and Practical Selection

A variable font contains a design space rather than a fixed set of instances, with axes along which
the outlines interpolate continuously. Weight and width are standard axes; optical size adjusts the
design for the intended rendering size, which restores a practice that predates digital type; and
custom axes can control anything the designer parameterizes. A single file replaces a family of
static instances, and any point in the space is available rather than only the named ones.


typography_in_practice

The practical benefits are file size for a full family, fine-grained control, and the ability to
animate between states. The costs are that some rendering paths handle variation poorly, that the
design space's corners may not be places the designer intended anyone to use, and that arbitrary
interpolated instances lack the individual attention that named weights receive. The optical size
axis is the one with the clearest quality benefit and it is the least used.


typography_in_practice

Selecting type for a project comes down to a few practical questions rather than to aesthetic
preference alone. What sizes and what rendering environment — a face designed for print at large
sizes fails as small screen text. What character coverage is needed — a beautiful face lacking the
scripts, diacritics, or numerals a project requires is unusable. What weights and widths are needed,
and does the family actually have them. And what the licensing permits, since font licences vary
widely in whether they cover web embedding, application bundling, and the volume of use anticipated.


typography_in_practice

Variable fonts and selection:
  design space         axes along which outlines interpolate
  standard axes        weight, width, optical size, slant, italic
  optical size         design adjusted to the rendering size; a restored practice
  custom axes          anything the designer parameterizes
  file size            one file for a full family
  fine-grained control  any point rather than named instances
  animation            interpolation between states
  the rendering caveat  some paths handle variation poorly
  the design space corners  not necessarily intended for use
  named instances      the points that received individual attention
  the underused axis   optical size, with the clearest quality benefit
  selection question one  what sizes and what rendering environment
  selection question two  what character and script coverage is required
  selection question three  what weights and widths, and does the family have them
  selection question four  what the licence permits for the intended use
  the pairing principle  typefaces combine well when they share proportions and
                       differ clearly in category, and a pairing that differs
                       slightly reads as a mistake rather than as a contrast


vr_ar_and_spatial

Virtual, Augmented, and Spatial Computing

## Displays, Optics, and the Perceptual Target

A head-mounted display presents a separate image to each eye through optics that place the virtual
image at a comfortable focal distance. The design targets are field of view, angular resolution,
persistence, and weight, and they conflict with each other in ways that make every headset a
particular set of compromises rather than a point on a single quality axis.


vr_ar_and_spatial

Angular resolution is the meaningful resolution measure, expressed in pixels per degree, because a
panel's pixel count means nothing without knowing across how wide a field it is spread. Human foveal
acuity corresponds to roughly sixty pixels per degree, and reaching that across a wide field
requires pixel counts far beyond current panels, which is why foveated rendering — full resolution
only where the eye is looking, tracked in real time — is the standard approach to closing the gap.