A black hole with a glowing golden accretion disc and a bright ring of lensed light, seen through tall windows of a Room in Locus
Event Horizon: Ring, made with these tools, seen from the Atrium Loft Room in a development build of Locus on the visionOS Simulator. Nebula imagery: NASA, ESA, CSA, and STScI (CC BY 4.0).

What you are making

A black-hole View is a complete Package v2 View with a blackHole profile. You sit still at a fixed distance from a non-spinning black hole, so everything about how gravity bends light can be worked out once, on your computer, before the View ever reaches Locus. Locus then only animates what changes over time: the gas orbiting in the disc, faster near the inner edge, a slow drift of the distant sky, short-lived flares and a soft glow. It never traces a ray on Apple Vision Pro.

It is a composition, not a place. The nebulae are real photographs placed and dimmed for the scene. No real black hole sits in front of them.

你需要准备什么

1 · Choose

Choose your nebulae

The sky behind the black hole is a procedural starfield with one or two nebula photos placed in it. Real nebulae are far fainter than a glowing disc, so they end up dimmed in the background. One photo usually sits right behind the hole, where the lens stretches it into arcs around the shadow; a second can sit exactly opposite so the drifting sky carries it behind the hole in turn.

On an ESA/Webb image page, download the Large JPEG, for example https://cdn.esawebb.org/archives/images/large/weic2212a.jpg. ESA/Webb images are under CC BY 4.0: credit them exactly as the image page asks, normally “NASA, ESA, CSA, and STScI”, without changing the wording, and say that you modified them. Keep the page address for your provenance in step 3.

Optional: give a nebula a dark margin with AI

If you love a nebula that glows to its edges, you can extend the photo with a generated margin that fades into black space. outpaint_fal.py keeps the photographed area unchanged in the middle of a larger canvas and asks Bria Expand on fal.ai to paint only the surroundings. It is optional and paid: it uses your own fal.ai key, costs about US$0.04 per run at the time of writing, and sends a smaller copy of the photo to fal.ai.

PhotoThe Crab Nebula photographed by Webb, its orange filaments and blue glow filling the frame to the edges
The Crab Nebula fills its frame.
OutpaintedThe same Crab Nebula photo, smaller, in the middle of a larger canvas, with generated wisps fading into black space around it
The photo is unchanged in the middle; only the fading margin is generated.

Crab Nebula: NASA, ESA, CSA, and STScI (CC BY 4.0), weic2326a; right, with a margin outpainted by Bria Expand.

export FAL_KEY=your-own-key     # never commit or share it
python3 outpaint_fal.py ~/bh/weic2326a.jpg ~/bh/crab-expanded.png \
  --confirm-paid \
  --prompt "The Crab Nebula fading gradually into empty black space"
Disclose AI-generated pixels. If an outpainted photo ends up in your View, set "aiGenerated": true and an "aiProvider" such as "Bria Expand (fal.ai), nebula margins only" in the recipe’s provenance, and say in modificationNotes what was generated. Locus rejects aiGenerated: true without a provider.

Then place the outpainted file with fade in step 2, as you would the original photo.

2 · Compose

Compose the sky

compose_sky.py draws about 260,000 stars over the whole sphere and places your photos on it. The result is a flat 2:1 sky, as seen without the black hole.

python3 compose_sky.py ~/bh/sky.png \
  --photo ~/bh/weic2212a.jpg,0,12,110,0.55,0.1,fade \
  --photo ~/bh/weic2207b.jpg,180,-12,50,0.5,0.2,add

Each --photo 是 PATH,YAW,ELEVATION,WIDTH,ROW,GAIN,MODE:

ModeWhat it doesUse it for
addAdds only the photo’s light above its own background level, so the stars show through the dark parts.Nebulae photographed on black space.
fadeLike add, then fades the photo to nothing toward its edges.Nebulae that still glow at the edges, and outpainted photos.
overReplaces the stars inside a softened rectangle.Rarely; only for a photo meant to fill its area completely.

It takes about ten seconds. Open sky.png and check it: it should look very dark, with the nebulae faint against the stars.

3 · Recipe

Write a recipe

A recipe is a JSON file with your View’s name, the black hole’s settings, the bake resolution, and its provenance. Start from the example, which is the composition of Locus’s own Event Horizon: Ring:

cp recipes/ring.view.json ~/bh/my-ring.view.json
  1. Give it your own identity. Change destinationID to a unique ID made of letters, digits, dots, dashes and underscores, such as destination.alex-black-hole, and set title 和 caption. Keep the same ID for later versions and raise contentVersion each time.
  2. Fill in the provenance. Replace “Your Name” with your name or studio; the baker refuses to run until you do. Name every photo you used in requestedCredit 和 modificationNotes, and set sourcePageURL to the main photo’s page.
  3. Adjust the look with the settings below, or keep the example values for your first bake.

离开 disc.exposure out and the baker picks a brightness for you; bake.exposureScale scales it. The tools README lists every field.

4 · Bake

Bake the View

python3 bake_view.py ~/bh/my-ring.view.json \
  --sky ~/bh/sky.png --out ~/bh/my-ring --stills 0,5,10

The baker prints each stage. With the example recipe it takes about a minute: the lens table in a couple of seconds, the disc map in about 25, then the turbulence, glow and an 8K panorama. It writes a Package v2 folder:

my-ring/
├── locusplace.json
└── catalog/destinations/<your destinationID>/
    ├── destination.json        # with the blackHole profile
    ├── panorama.jpg            # the View at time zero
    ├── lighting.jpg
    ├── thumbnail.jpg           # the Places cover
    ├── provenance.json
    └── black-hole/
        ├── sky.jpg  lens.png  disc-map.png  disc-texture.png  glow.png

panorama.jpg is exactly the first frame Locus shows, and the picture it keeps showing when motion is off. The other images let Locus animate the disc without tracing rays.

Sky inA flat two-to-one starry sky, mostly black, with the Tarantula Nebula faint at the centre and the Southern Ring Nebula split across the left and right edges
The composed sky, brightened here so you can see it: the Tarantula Nebula ahead, the Southern Ring Nebula behind you at the edges.
Panorama outThe baked two-to-one panorama: the black hole and its golden disc at the centre, with the nebula behind it stretched into arcs around the shadow
The baked panorama: the lens wraps the nebula behind the hole into arcs around its shadow.

Tarantula Nebula (weic2212a) and Southern Ring Nebula (weic2207b): NASA, ESA, CSA, and STScI (CC BY 4.0), dimmed and lensed.

5 · Preview

Preview frames

--stills 0,5,10 renders 1920 × 1080 views centred on the hole at those seconds, into my-ring-stills. They use the same mathematics Locus uses on the packaged files, so they show what the moving disc will look like. To preview an existing bake, or an Edit View setting, use --view 和 --control:

python3 bake_view.py ~/bh/my-ring.view.json --view ~/bh/my-ring \
  --stills 5 --control doppler=1
python3 bake_view.py ~/bh/my-ring.view.json --view ~/bh/my-ring \
  --frames ~/bh/frames --seconds 20

--frames writes a numbered PNG sequence, and reference.mp4 too if ffmpeg is installed. A 20-second sequence takes several minutes.

A preview still of the baked black hole: a golden disc seen nearly edge-on, its far side arched over a black shadow and a thin bright ring, with nebula wisps behind
A preview still five seconds in. Nebula imagery: NASA, ESA, CSA, and STScI (CC BY 4.0).

A flat preview cannot tell you how the View feels around you. Check brightness, motion and comfort on Apple Vision Pro after you import it.

6 · Pack

Pack and validate

python3 pack_view.py ~/bh/my-ring ~/bh/my-ring.locusplace

The packer lists every file with its size and SHA-256 in locusplace.json, adds the package’s contentHash, writes the archive and then checks it much as Locus will when you import it. A good result ends with:

VALID: destination.alex-black-hole 1.0.0 (1 View) -> /Users/you/bh/my-ring.locusplace

If something is wrong it prints INVALID: with the field to fix, and no archive is written. You can check an archive again at any time with python3 validate_view.py ~/bh/my-ring.locusplace. The extension can be .locusplace 或者 .zip.

7 · Import

Import it into Locus

  1. Move the file to Apple Vision Pro, for example with AirDrop or by saving it to iCloud Drive.
  2. In Locus, open Places, then choose Import.
  3. Choose Import a View, then Files, and pick your .locusplace file. Locus checks it before installing anything.
  4. Find it in Places under Views. Its card is marked Imported and shows your cover. Pair it with any Room, then choose Enter Place.

To replace it with a new version, raise contentVersion in the recipe, bake and pack again, and import the new file.

8 · In Locus

Adjust it in Edit View → Motion

在 空间,打开您的景观菜单并选择 编辑景观。那个 动态 section has a Black Hole group. Your recipe’s values are the defaults, and changes are saved for this View.

The Motion section of Edit View in Locus: the Black Hole group with Sky Drift, Disc Flow Speed and Disc Brightness sliders and a collapsed Advanced row
Motion: Sky Drift, Disc Flow Speed and Disc Brightness.
The Advanced group expanded below Disc Brightness, with Doppler Beaming, Turbulence Detail, Disc Glow and Flares sliders
Advanced: Doppler Beaming, Turbulence Detail, Disc Glow and Flares.

Values shown are from a test build. Your View starts at your recipe’s values, for example Sky Drift 0.3 °/s.

ControlRangeWhat it does
Sky Drift0⁠–⁠2 °/sHow fast the distant sky turns behind the hole. 0 holds it still.
Disc Flow Speed0.25⁠–⁠3×How fast the gas and flares orbit.
Disc Brightness50⁠–⁠200%Overall brightness of the disc.
Doppler Beaming (Advanced)0⁠–⁠100%Makes the side moving toward you brighter and bluer, and the other side dimmer and redder. 100% is physical.
Turbulence Detail (Advanced)0.5⁠–⁠2×Finer or coarser streaks in the gas.
Disc Glow (Advanced)0⁠–⁠200%Strength of the bloom around the disc. Its colour follows the baked look, not later Doppler changes.
Flares (Advanced)0⁠–⁠200%Brightness of the orbiting hot spots; 0 removes them. Shown only when the recipe has flares.

选择 Reset All Changes in Edit View to return to your recipe’s values. If you like a setting enough to make it the default, put the same value in the recipe and bake again.

Troubleshooting

Keep it comfortable

When the whole sky turns, some people feel as if they are moving. Keep the drift slow: the example uses 0.3 °/s, a full turn every 20 minutes. Visitors can set Sky Drift to 0 in Edit View. When Reduce Motion is on, or Animated View is off, Locus stops all black-hole motion and shows your still panorama instead. Keep flares moderate too, since bright pulses can be tiring over a long session. Try your View on Apple Vision Pro for a while before you share it.

Credits and licensing

Share what you make on r/EnterLocus.