by billpwchan
霓虹天頂 — a rain-soaked vertical cyberpunk city you can fly through in the browser. three.js WebGPU + TSL, a Blender-baked Hong Kong night market, procedural megacity, time trials.
# Add to your Claude Code skills
git clone https://github.com/billpwchan/neon-zenithSee how neon-zenith compares with popular alternatives.
neon-zenith is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by billpwchan. 霓虹天頂 — a rain-soaked vertical cyberpunk city you can fly through in the browser. three.js WebGPU + TSL, a Blender-baked Hong Kong night market, procedural megacity, time trials. It has 50 GitHub stars.
neon-zenith's catalog security scan is still queued. You can run an instant dependency and prompt-injection check now with the "Scan for vulnerabilities" button above.
Clone the repository with "git clone https://github.com/billpwchan/neon-zenith" and add it to your Claude Code skills directory (see the Installation section above).
neon-zenith is primarily written in JavaScript. It is open-source under billpwchan on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh neon-zenith against similar tools.
No comments yet. Be the first to share your thoughts!
Available after the catalog security scan passes.
⚠️ Third-Party Software Notice
This skill is third-party open-source software developed and hosted independently on GitHub. SkillsLLM is an informational directory and does not control or maintain the underlying repository.
Any security checks, ratings, or warnings displayed by SkillsLLM are automated and limited in scope. They do not constitute a security certification or guarantee that the software is safe, error-free, or free from malicious code, vulnerabilities, compromised dependencies, or prompt-injection risks.
Review the source code, permissions, dependencies, and configuration before installing or running any third-party skill. Use is at your own risk. To the maximum extent permitted by applicable law, SkillsLLM is not liable for losses arising from third-party software.
The deep catalog scan for this skill is still queued. Run an instant dependency check now instead.
A rain-soaked vertical city you can fly through, in your browser.
Drive the Temple Street night market, lift off into the sky lanes, punch through the storm deckand land on a spire 1,418 metres up. Real-time, open source, built on three.js WebGPU.
▶ Play it now · How it works · Run it locally · Credits
Neon Zenith is a single, continuous city of 9,373 buildings on a 3.2 km grid, ringed by a harbour and a far shore. Every building, sign, awning, lamp post and rooftop water tank is solid. You can land on any roof, slide under the signs that hang over the street, or thread the canyon between two towers at full boost. Nothing is a skybox.
| Keyboard | Gamepad | Touch | |
|---|---|---|---|
| Thrust / brake | W / S |
RT / LT |
stick |
| Steer | A / D |
left stick | stick |
| Climb / descend | Space / C |
right stick | UP / DOWN |
| Boost (drift when turning at speed) | Shift |
RB |
BOOST |
| Camera | V |
CAM |
|
| Map · reset to street · horn · radio | M · R · F · B |
MAP |
|
| Menu | Esc |
☰ |
Everything renders through three.js's WebGPURenderer, and every material is written in TSL (three.js's node shading language). TSL compiles to WGSL on WebGPU and to GLSL on the WebGL2 fallback, so there is one source for both. The repository has no .glsl file.
src/city/layout.js lays out streets, districts (market, mixed, centre, estates, docks, the outer ring), blocks, lots, alleys, shops and signs from one seed. It does this in a single pass, and the hand-built district is keyed to the building ids that pass produces. src/city/massing.js then shapes every building from its own random stream, rngFor(seed, salt). That way new architecture never shifts a lot, a sign or the baked street.
Determinism matters more than it looks. The usual shortcut, array.sort(() => rng() - 0.5), is not deterministic in V8: the engine calls the comparator a different number of times depending on JIT state. We measured 4 calls in 98% of runs and 5 in the rest. Each extra call consumes a random number, so the city changed from load to load. Shuffles here use a seeded Fisher-Yates (src/core/rng.js).
| Distance | What you see | How |
|---|---|---|
| < 180 m | Modelled facade kits: recessed windows, frames, AC units, grilles | Cells sliced from CC BY models in Blender (kit_slice.py), instanced along facades, with LODs |
| any | Captured facades of real-looking HK blocks | Orthographic Blender renders of whole modelled buildings (facade_ortho.py), packed into texture arrays of albedo, glass/window-id mask and normal. Each window gets its own interior-mapped room with parallax walls, furniture, curtains and a lamp, lit or dark per room. |
| any | Procedural curtain walls on towers | Analytic in the shader, sharp at any distance. Every tower draws its own grid, floor height, glazing ratio, glass tint and spandrel colour. Offices light by tenant: runs of bays per floor in warm, neutral or daylight tones, with corridor lights left on after hours. |
assets-src/district/compose.py builds the street in Blender. export.py unwraps and bakes each object's diffuse light in Cycles, then shelf-packs the results into one 4096² lightmap at roughly 10–14 px/m. It also bakes the light at street level top-down for the ground and for anything that moves. pack.mjs writes meshopt-compressed glTF and KTX2 textures: ETC1S for colour, UASTC for normals and data, and UASTC HDR for the lightmap. Props get distance LODs, and phones load 1K texture variants.
Thousands of neon signs, shop windows and street lamps can't each be a real light, so their spill is rendered once into a top-down 2048² street-light map covering 3.5 km (lightmap.js). Roads, facades, rain, the fog and the underside of the cloud deck all sample it. Colour from every emitter costs one texture read. Walls also take a city-glow ambient term, warm and neon-tinted near the street and fading to the clouds' violet above. Dark glass picks up a matching reflection.
atmos/fog.js) is analytic. Exponential height haze plus a cloud slab are integrated along each view ray, coloured by the street-light map below and moonlit from above.atmos/rain.js) is stateless. Each drop is a pure function of its index and time, drawn as a streak along its velocity relative to the camera, with splashes near the ground.core/post.js) is scene, then bloom, grade, ACES, chromatic fringe and vignette, FXAA, and grain.A frame-time governor (core/governor.js) scales the scene pass when frames are missed and probes back up after a run of clean ones. Measured on an Apple M4 Max at 1920×1080 and device-pixel-ratio 2 (3840×2160 internal), headed Chrome:
| View | Frame time p95 | Frames > 20 ms | Draw calls | Triangles |
|---|---|---|---|---|
| Street level, Temple Street | 18.6 ms | 0 % | ~2,000 | 23 M |
| Mid-air over the markets | 18.5 ms | 0 % | ~1,330 | 19 M |
| Central business district | 18.6 ms | 0 % | ~1,300 | 10 M |
| High over the city | 18.6 ms | 0 % | ~830 | 8 M |
That is a locked 60 fps (vsync) with the resolution scale at 1.00 throughout. Most geometry is instanced in