An ambient automotive soundscape for focus and calm. (한국어 별칭: 차멍)
Feel nice and relax with the ambient soundscape of M4 Competition.
It is a totally personal toy project, not a commercial product, and runs entirely in the browser.
- Vite 5 + React 18 + TypeScript (strict mode)
- Three.js 0.169 via
@react-three/fiberand@react-three/drei - Web Audio API for the looped soundscape
- Self-hosted Draco decoder under
public/draco/
The site loads a 20 MB GLB, a ~735 KB Three.js bundle, and a few hundred KB of audio. Nothing about the payload is large by desktop standards, but the browser's WebGL implementation matters more than raw device specs.
On page load the app runs a small probe (src/utils/detectWebGL.ts) that calls the exact WebGL call Three.js initialises with; if it fails, the page stays up in audio-only mode — the engine idle and turn-signal loops still play, only the 3D scene is hidden.
| Platform | Status | Notes |
|---|---|---|
| Desktop Chrome / Edge / Firefox (2022+) on macOS / Windows / Linux | ✅ Works | Primary target. Any dGPU or integrated GPU from the last ~6 years is comfortably enough. |
| Desktop Safari 16+ on macOS | ✅ Works | Same WebGL2 backend as Chromium on Apple Silicon. |
| Android Chrome / Chromium (2020+ flagships and tablets) | ✅ Works | Confirmed on Galaxy Tab S7+ (Snapdragon 865+). Android Chromium ships its own ANGLE-backed WebGL stack that isn't subject to the iOS WebKit quirks below. |
| iPadOS (Safari, Chrome iOS, Firefox iOS) | ✅ Works in most cases | Confirmed on iPad Air 4 (Chrome iOS). All iOS/iPadOS browsers share WebKit under the hood, so browser choice doesn't change behaviour much. |
| iPhone Safari / Chrome iOS | 🟡 Usually works, some devices fall back | Same WebKit stack as iPadOS, but some iPhones hit gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT) === null and auto-switch to audio-only. Known triggers listed below. |
| Low-RAM (≤ 3 GB) Android devices | 🟡 May fall back | GLB parse peaks around ~100–200 MB transient RAM; older devices may fail the probe under memory pressure. |
npm install
npm run dev # http://localhost:5173
npm run build # tsc -b && vite build → dist/
npm run preview # serve dist/ at :4173This is an unofficial personal ambient web experiment.
It is not affiliated with, endorsed by, sponsored by, or connected to BMW AG, BMW M GmbH, Sketchfab, or the referenced asset creators. All trademarks and model names belong to their respective owners.
The full asset attribution, with sources and licenses, lives in:
- The in-app Credits modal (bottom-right of the page).
public/assets/models/model-attribution.txtpublic/assets/audio/audio-attribution.txt
비공식 개인 토이 프로젝트입니다.
BMW AG · BMW M GmbH · Sketchfab · 에셋 제작자와 제휴/후원/보증 관계가 없습니다. 모든 상표와 모델명은 각 권리자에게 있습니다.
| Path | Size | Source | Notes |
|---|---|---|---|
public/assets/models/m4-competition.glb |
~20 MB | Sketchfab, d3f07b47… by Ricy (@ngon_3d) — CC BY 4.0 |
Committed in repo (no Git LFS). The fallback primitive coupe still renders if the file is missing or fails to load. |
public/assets/audio/engine_idle.mp3 |
352 KB | Edited from "AUDIO M4 WAV" by Andreabarata (Freesound, CC0) | Committed. |
public/assets/audio/indicator_loop.{mp3,ogg} |
~52 KB | "BMW Indicator" by The_Cri (Freesound, CC0) | Committed. |
public/draco/draco_decoder.{js,wasm} |
~700 KB | Three.js examples/jsm/libs/draco/gltf/ |
Self-hosted at /draco/ so the runtime never reaches a CDN. |
All runtime assets — including the 20 MB GLB — are committed in this repo
under public/, so a fresh clone runs end-to-end without any manual download step. The model is included strictly under the existing Creative Commons Attribution 4.0 terms granted by the original author — see the Trademark & attribution section above for the BMW trademark posture.
- 3D model — Ricy / @ngon_3d on Sketchfab, title "2021 BMW M4 Competition", under Creative Commons Attribution.
- Engine sound — Andreabarata on Freesound / mirrored on Pixabay, title "AUDIO M4 WAV", under CC0.
- Turn-signal sound — The_Cri on Freesound / mirrored on Pixabay, title "BMW Indicator", under CC0.
- Draco decoder — Google, distributed with Three.js.
