#### <sup>[Ollin](../index.md) → Examples</sup>

---

## Ollin examples

| [![3D](https://media.ollin.art/groups/3D-640.jpg?v=93086923)](3d/index.md) | [![Audio](https://media.ollin.art/groups/Audio-640.jpg?v=5229f117)](audio/index.md) | [![Basic](https://media.ollin.art/groups/Basic-640.jpg?v=87cc5110)](basic/index.md) | [![Color](https://media.ollin.art/groups/Color-640.jpg?v=d25edf72)](color/index.md) |
|---|---|---|---|
| [3D](3d/index.md) | [Audio](audio/index.md) | [Basic](basic/index.md) | [Color](color/index.md) |
| [![Compute](https://media.ollin.art/groups/Compute-640.jpg?v=cbbed8a4)](compute/index.md) | [![Data](https://media.ollin.art/groups/Data-640.jpg?v=0a0bcb08)](data/index.md) | [![Effects](https://media.ollin.art/groups/Effects-640.jpg?v=800bb77d)](effects/index.md) | [![Export](https://media.ollin.art/groups/Export-640.jpg?v=81611d5e)](export/index.md) |
| [Compute](compute/index.md) | [Data](data/index.md) | [Effects](effects/index.md) | [Export](export/index.md) |
| [![Images](https://media.ollin.art/groups/Images-640.jpg?v=7bf66de8)](images/index.md) | [![Input](https://media.ollin.art/groups/Input-640.jpg?v=af47f1e4)](input/index.md) | [![Installation](https://media.ollin.art/groups/Installation-640.jpg?v=f10e701f)](installation/index.md) | [![Integration](https://media.ollin.art/groups/Integration-640.jpg?v=b8331369)](integration/index.md) |
| [Images](images/index.md) | [Input](input/index.md) | [Installation](installation/index.md) | [Integration](integration/index.md) |
| [![Live](https://media.ollin.art/groups/Live-640.jpg?v=7773d6c6)](live/index.md) | [![Motion](https://media.ollin.art/groups/Motion-640.jpg?v=d405aefc)](motion/index.md) | [![Patterns](https://media.ollin.art/groups/Patterns-640.jpg?v=e420cadf)](patterns/index.md) | [![Physics](https://media.ollin.art/groups/Physics-640.jpg?v=22aef076)](physics/index.md) |
| [Live](live/index.md) | [Motion](motion/index.md) | [Patterns](patterns/index.md) | [Physics](physics/index.md) |
| [![Randomness](https://media.ollin.art/groups/Randomness-640.jpg?v=7f0bd6fe)](randomness/index.md) | [![Recreations](https://media.ollin.art/groups/Recreations-640.jpg?v=a68626bc)](recreations/index.md) | [![Rendering](https://media.ollin.art/groups/Rendering-640.jpg?v=9e014439)](rendering/index.md) | [![Shaders](https://media.ollin.art/groups/Shaders-640.jpg?v=91f273a5)](shaders/index.md) |
| [Randomness](randomness/index.md) | [Recreations](recreations/index.md) | [Rendering](rendering/index.md) | [Shaders](shaders/index.md) |
| [![Shapes](https://media.ollin.art/groups/Shapes-640.jpg?v=ee7af08f)](shapes/index.md) | [![Simulation](https://media.ollin.art/groups/Simulation-640.jpg?v=65db53d6)](simulation/index.md) | [![Text](https://media.ollin.art/groups/Text-640.jpg?v=07f581d8)](text/index.md) | [![Video](https://media.ollin.art/groups/Video-640.jpg?v=76b194e7)](video/index.md) |
| [Shapes](shapes/index.md) | [Simulation](simulation/index.md) | [Text](text/index.md) | [Video](video/index.md) |
| [![Vision](https://media.ollin.art/groups/Vision-640.jpg?v=dd4a2bb3)](vision/index.md) | [![Web](https://media.ollin.art/groups/Web-640.jpg?v=fd88be70)](web/index.md) |  |  |
| [Vision](vision/index.md) | [Web](web/index.md) |  |  |

The examples are small, runnable sketches. Together they form a learning path, in the style of openFrameworks. Each example is one self-contained `@main` file that shows a single idea. The examples are maintained and versioned with the API, so they always build against current Ollin.

### Layout

Examples are grouped into **category** folders, and each example gets its own folder inside its category. One example is one executable target, because SwiftPM allows only one `@main` per target. The sketch file is always `Sketch.swift`, at `Examples/<Category>/<Name>/Sketch.swift`. The folder name is therefore the example's identity, and the folder also holds the sketch's own resources (fonts, images, shaders). A category that has grown large can group its sketches one level deeper, at `Examples/<Category>/<Group>/<Name>/Sketch.swift`. `3D/` is grouped by topic this way, and `Recreations/` is grouped by artist. The group name also becomes part of the target name (`Example-<Category>-<Group>-<Name>`). Each category has its own README that lists the sketches inside it:

| Category | What's inside |
|---|---|
| [3D](3d/index.md) | the 3D mode: meshes, camera, materials, lighting, environments, raymarched SDFs, depth feeds |
| [Audio](audio/index.md) | sound-reactive sketches (`import OllinAudio`) |
| [Basic](basic/index.md) | the smallest starting point |
| [Color](color/index.md) | palettes, colormaps, and color over time |
| [Compute](compute/index.md) | GPU compute: a million particles, and reaction-diffusion / texture simulations |
| [Data](data/index.md) | drawing from data: CSV tables and JSON documents, a polled feed, a pushed stream, and the weather over a city |
| [Effects](effects/index.md) | layered effects: GPU filters, feedback, generators, and the `compose { }` stack |
| [Export](export/index.md) | saving a sketch out: raster frame grab, vector SVG, and plotter hatching |
| [Images](images/index.md) | loading, drawing, tinting, and authoring images, plus glyph mosaics, pixel sorting, single-line renderings, and slit scan |
| [Input](input/index.md) | mouse-driven sketches |
| [Installation](installation/index.md) | pieces left running unattended, on a wall or in a window |
| [Integration](integration/index.md) | connecting to other apps and hardware: OSC, MIDI, DMX lighting, Syphon (`import OllinOSC` / `OllinMIDI` / `OllinDMX` / `OllinSyphon`) |
| [Live](live/index.md) | tunable `@Param` parameters under OllinLive |
| [Motion](motion/index.md) | animation driven by `time` |
| [Patterns](patterns/index.md) | generative patterns: grids, tessellations, rule-based repetition |
| [Physics](physics/index.md) | simulated motion (`import OllinPhysics`) |
| [Randomness](randomness/index.md) | `random`, `noise`, and scatter |
| [Rendering](rendering/index.md) | how the frame composites: blending, accumulation, HDR tone mapping, sandpainting |
| [Shaders](shaders/index.md) | writing your own GPU code: user shaders inline and from files, and fluent `Visual` chains |
| [Shapes](shapes/index.md) | the shape-drawing vocabulary: primitives, stroke and hollow modes, booleans, and SDF combinators |
| [Simulation](simulation/index.md) | systems evolving on the GPU: sim fields (`simField`), artificial life, particle fluids and soft bodies |
| [Text](text/index.md) | drawing text: bitmap, outline, and stroke fonts over one `drawText` |
| [Video](video/index.md) | recorded footage as drawing material (`import OllinVideo`) |
| [Vision](vision/index.md) | the camera plus on-device perception (`import OllinVision`) |
| [Web](web/index.md) | sketches made for a web page, limited to what a browser supports |
| [Recreations](recreations/index.md) | homages to past computer artists, by artist |

### Running

The examples are a package of their own, so run them from this directory. Each
one is a target whose name starts with `Example-`:

```sh
cd Examples
swift run Example-Basic-HelloCircle
swift run Example-Motion-SineSweep
```

Run `swift run` with no argument to list every runnable target. To run an example
from the repo root instead, name the package: `swift run --package-path Examples Example-Basic-HelloCircle`.

The commands in each category's README assume you are in this directory.
The examples are a separate package because SwiftPM builds every target of a
package. When the 350 sketch executables were in the root package, that meant
every `swift test` linked all of them.

You can also browse them all in one window. From the repo root, run:

```sh
swift run OllinExamples
```

The example list is on the left, grouped like the folders, with a filter bar at the bottom. The arrow keys move through the list. When you click a sketch, it compiles and runs in the middle. An inspector with live stats and `@Param` parameters is docked on the right. Both sidebars collapse from the title bar.

### Adding an example

1. Create `Examples/<Category>/<Name>/Sketch.swift` with an `@main final class <Name>: Sketch { … }`. You do not need an `OllinApp.run(...)` line, because `Sketch.main()` starts the sketch for you.
2. Add one line, `example("<Category>/<Name>")`, to the targets list in `Examples/Package.swift`. The helper derives the target name from the folder path, so the two cannot drift apart. A sketch that needs a satellite library passes it as the second argument, and co-located assets go in `resources:`.
3. Add a row to the category's `README.md`. A new category also needs its own `README.md` and a row in the table above.

By convention, a feature is not done until it has an example, and every example must compile. If a sketch is awkward to write, treat that as a sign that the API needs work, not the example.

### Recreations

`Recreations/` is a special section. Its sketches **recreate the work of past computer artists**, and they are organized by artist. SFPC's [Recreating the Past](https://sfpc.io/recreatingthepast-spring2020/) class inspired the section. Each sketch is a homage after the artist, not a reproduction, and the artist has not endorsed it. A short per-artist `README.md` introduces each artist. Each target name includes the artist's name:

```sh
swift run Example-Recreations-VeraMolnar-Interruptions
```

See [`Recreations/README.md`](recreations/index.md) for the full explanation.

### Attribution & sources

An example often *ports* a sketch from somewhere else. When one does, credit the source and respect its license:

- Add a header at the top of `Sketch.swift` that names the source:

  ```swift
  //  Ported from "<sketch>" by <author> — <url>
  //  Original license: <license>. Reworked for Ollin's API (Swift; Vector2/polyline).
  ```

- **Only port sources whose license permits redistribution under MIT:** MIT, BSD, Apache-2.0, CC0/public domain, or CC-BY (with credit). For GPL/LGPL, CC-BY-NC, or CC-BY-SA sources, rewrite the sketch as original work and use the source only as inspiration. Then credit it as "inspired by" instead.

An original sketch with no specific source needs no header. When something inspired it, you can add a one-line "inspired by …" note.

A sketch based on the maintainer's own work is credited by **serial number**. The header names the author and the S/N, not the private sketchbook the sketch came from. Use `// Ported from @eaviles's sketch 2025.003.` for a faithful port, or `// Based on elements of @eaviles's sketch 2023.023.` for a sketch that takes only some elements from the original. In both cases, follow the line with `Reworked for Ollin's API.`

For a **recreation** of a named artist's work (see `Recreations/`), also credit the artist in the header and in the per-artist `README.md`. Frame the sketch as a homage after the artist, not a reproduction, and note that the artist or their estate has not endorsed it.
