# 3D rendering decision: desktop first, mobile later

**Decision for The Meridian Reach, November 2026:** continue building the solo gameplay reference in HTML/Three.js, then deliver the native PC and Android test version in **Unity URP**, as the project brief specifies. URP is the target, not an open engine choice. Run a small, matched render/device feasibility slice alongside the web milestone to measure the planet, station, lighting, and travel scene on a capable PC and a representative Android phone. Use that result to set quality tiers and art scope before the gameplay port; only reopen the renderer decision if the slice reveals a material technical blocker. URP provides one project for native desktop and phone builds, but it does not guarantee photorealism or good phone performance. If the desktop target eventually requires Unreal's features, that would entail funding a separate, reduced mobile rendering tier. [Unity's pipeline guidance](https://docs.unity.com/en-us/engine/6000.6/manual/render-pipelines/choose-a-render-pipeline/pipeline) explicitly distinguishes URP's broad platform support from HDRP's high-end focus and warns that switching pipelines later is costly.

The current concept is a small Three.js `WebGLRenderer` planet/station scene inside a web layout, with a browser `localStorage` save. It proves composition and the trade loop, not a production 3D ceiling. In HTML, a `<canvas>` can fill the whole viewport and DOM controls can overlay it; a narrow hero panel is a layout choice, not a limit of HTML or Three.js. [WebGL draws into canvas](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API), and [Three.js's responsive guide](https://threejs.org/manual/pages/responsive.html) shows that canvas display size and render resolution are separate costs.

## What the choices buy

| Path | Shippable 3D and lighting | Desktop, mobile, distribution, and cost |
| --- | --- | --- |
| **HTML + Three.js, browser** | Real GPU 3D with custom shaders, physically based materials, shadows, post effects, and artist-authored tricks. The practical ceiling depends on scene design, browser/GPU support, and the team's rendering work. Current `WebGLRenderer` uses WebGL 2. `WebGPURenderer` offers a WebGPU backend, node materials/TSL and a WebGL 2 fallback, but Three.js still labels it experimental; existing `ShaderMaterial`, `onBeforeCompile`, and `EffectComposer` work needs porting. WebGPU is an option to test, not a promised automatic quality or speed upgrade. [Three.js WebGLRenderer](https://threejs.org/docs/pages/WebGLRenderer); [Three.js WebGPURenderer](https://threejs.org/manual/pages/webgpurenderer). | One web client and immediate URL updates; easiest reuse of today's UI and game logic. Device pixel ratio, browser memory, shader compilation, and touch/thermal limits still need real-device profiling. A PWA adds installation and offline caching, but it runs the same web graphics code and browser APIs; install prompts vary by browser/platform and stale assets need a cache/update strategy. [PWA installability](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Guides/Making_PWAs_installable); [PWA caching](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Guides/Caching); [Three.js responsive guide](https://threejs.org/manual/pages/responsive.html). |
| **Three.js inside Electron** | Essentially the browser rendering path inside bundled Chromium, not a native game renderer. Pinning a Chromium version may make a desktop target more predictable; the wrapper does not supply Unreal-style lighting, asset streaming, or GPU headroom. This is an inference from [Electron's Chromium renderer model](https://www.electronjs.org/docs/latest/tutorial/process-model) and [Three.js's renderer architecture](https://threejs.org/manual/pages/webgpurenderer). | Desktop installer, OS integration and controlled local file access through a narrow preload/IPC bridge. Adds packaging, signing, updates, bundled runtime size, and Chromium security maintenance. Electron says vendors must ship framework updates to deliver security fixes; its security guide recommends isolation, sandboxing and not exposing Node capabilities to untrusted pages. It is not the later mobile build. [Distribution](https://www.electronjs.org/docs/latest/tutorial/distribution-overview); [updates](https://www.electronjs.org/docs/latest/tutorial/updates); [sandboxing](https://www.electronjs.org/docs/latest/tutorial/sandbox); [security](https://www.electronjs.org/docs/latest/tutorial/security). |
| **Native game + separate PWA** | A Unity or Unreal desktop client can use that engine's native rendering pipeline; the PWA can give phone players light tasks such as market review or company management. It will not turn the PWA into the native 3D client. | Useful only if a companion experience is a product goal. Two clients need separate navigation, input, UI, versioning, save reconciliation and authentication. Share a server API and economic rules where practical, but expect UI and rendering work twice. The [PWA install model](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Guides/Making_PWAs_installable) and [Unity's platform build profiles](https://docs.unity.com/en-us/engine/6000.6/manual/building-and-publishing/build-settings/create-build-profile) support the delivery distinction; the doubled client work is a planning inference. |
| **Unity URP native game** | Integrated scene, material, animation, lighting, profiling and platform build workflow. URP provides basic PBR, clear coat, baked GI, probes and custom Shader Graph/HLSL, but lacks HDRP's built-in screen-space GI/reflections/refractions and ray-traced effects. A convincing station interior will require authored lighting, reflection probes, texture quality and careful effects. [Pipeline comparison](https://docs.unity.com/en-us/engine/6000.6/manual/render-pipelines/choose-a-render-pipeline/pipeline); [feature table](https://docs.unity.com/en-us/engine/6000.6/manual/render-pipelines/choose-a-render-pipeline/feature-comparison). | Native Windows and mobile builds from one engine project, with platform quality settings and distinct touch UI. Unity lists URP on iOS and Android, HDRP on neither. A PC-quality URP scene still needs lower resolution, light/shader/texture budgets and different controls on phones. Rebuild the HTML interface in the engine or maintain a deliberate web bridge; HTML DOM does not become native engine UI automatically. [Feature table](https://docs.unity.com/en-us/engine/6000.6/manual/render-pipelines/choose-a-render-pipeline/feature-comparison); [build profiles](https://docs.unity.com/en-us/engine/6000.6/manual/building-and-publishing/build-settings/create-build-profile); [URP rendering-path choices](https://docs.unity.com/en-us/engine/6000.6/manual/render-pipelines/universal-render-pipeline/introduction/urp-concepts/rendering-paths/comparison). |
| **Unity HDRP or Unreal native game** | Strongest built-in desktop visual toolset here. HDRP adds more physically accurate materials and advanced screen-space/volumetric/ray-traced effects, but Unity cannot combine HDRP and URP in one running project. Unreal offers Nanite geometry and Lumen GI/reflections on supported desktop GPUs; those features have explicit shader-model/API/GPU requirements. Neither is a free shortcut to finished art, animation and direction. [Unity pipeline guidance](https://docs.unity.com/en-us/engine/6000.6/manual/render-pipelines/choose-a-render-pipeline/pipeline); [Unreal rendering requirements](https://dev.epicgames.com/documentation/en-us/unreal-engine/hardware-and-software-specifications-for-unreal-engine). | Best considered if desktop fidelity dominates. HDRP has no iOS/Android support. Unreal's standard mobile feature matrix excludes Nanite; Epic calls Lumen on select high-end Android devices experimental, with no iOS support and significant performance cost. Mobile needs a different quality path and likely re-authored lighting, geometry and materials. Native packaging and store updates replace web deployment. [Unity feature table](https://docs.unity.com/en-us/engine/6000.6/manual/render-pipelines/choose-a-render-pipeline/feature-comparison); [Unreal mobile feature matrix](https://dev.epicgames.com/documentation/en-us/unreal-engine/rendering-features-reference); [Lumen on mobile](https://dev.epicgames.com/documentation/en-us/unreal-engine/using-lumen-global-illumination-on-mobile-in-unreal-engine); [Unreal packaging](https://dev.epicgames.com/documentation/en-us/unreal-engine/packaging-your-project). |

**Team implication.** Three.js keeps the existing JavaScript/DOM skills and fastest iteration, but the team owns more of the graphics pipeline, asset optimization and browser compatibility. Unity URP adds C#, engine UI, import/build workflows and mobile device profiling; Unreal adds a larger content/rendering pipeline and more platform-specific quality work. Engine choice does not produce photorealistic assets or mobile usability by itself. This is a scope assessment grounded in the [Unity pipeline comparison](https://docs.unity.com/en-us/engine/6000.6/manual/render-pipelines/choose-a-render-pipeline/pipeline), [Unreal mobile rendering paths](https://dev.epicgames.com/documentation/en-us/unreal-engine/mobile-rendering-and-shading-modes-for-unreal-engine), and [Three.js renderer migration notes](https://threejs.org/manual/pages/webgpurenderer).

**Saves and accounts should be a separate architecture decision.** A local save can work in every path: today's `localStorage` is origin-scoped and may be unavailable or cleared; Unity provides a persistent data directory; Unreal provides `SaveGame`. Use a versioned save schema with export/restore and migration in the slice. Cross-device progression, purchases and any future shared economy require authenticated server state and conflict rules regardless of renderer. Do not treat local files or browser storage as authoritative for tradable online assets, and do not store secrets in Unity `PlayerPrefs` (Unity explicitly says it is unencrypted). [MDN localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage); [browser storage eviction](https://developer.mozilla.org/en-US/docs/Web/API/Storage_API/Storage_quotas_and_eviction_criteria); [Unity persistentDataPath](https://docs.unity.com/en-us/engine/6000.6/script-reference/unityengine/application/persistentdatapath); [Unreal SaveGame](https://dev.epicgames.com/documentation/en-us/unreal-engine/saving-and-loading-your-game-in-unreal-engine); [Unity PlayerPrefs](https://docs.unity.com/en-us/engine/6000.6/script-reference/unityengine/playerprefs). The server-authority recommendation is an architectural inference, not a renderer feature.

## One-to-two-week decision slice

Use one engineer familiar with each chosen stack plus one technical artist; with one developer, reduce this to a sequential two-week comparison and record labor hours. Build **the same 45–60 second playable sequence in current Three.js WebGL 2 and Unity URP** from the same licensed source meshes, texture resolution, camera moves, mood board and target output resolution. Keep Unreal to a short desktop feasibility check only if URP fails the visual bar; a third full implementation would swamp this schedule. No full economy port is needed: a shared small JSON state can drive a buy, route and arrival.

The slice must show a planet atmosphere, orbital station exterior, a small station interior with **glass/transparent panels**, metal, emissives and shadows, one animated crew portrait with an accessible trade overlay, a readable galaxy map, and one brief travel interstitial that can be skipped. Save, quit, reload into the same state; test a guest save plus one account sign-in/save round trip against a simple test service if cross-device play is in scope. Record which features are real-time versus baked or faked, shader/material variants and asset preparation time. On mobile, retain the same art direction but permit explicit quality tiers and a redesigned touch layout; do not demand identical pixel output.

Run packaged/native builds, not only editor previews, on a **named high-end Windows PC with a decent discrete GPU** and a **named mid-range Android phone**; add an iPhone before an iOS commitment. Log GPU/CPU frame times, 1% low FPS, peak memory, initial load and scene-switch times, package/download size, battery and 20-minute sustained phone thermals. Capture matching screenshots and video at fixed camera points. Proposed gates: stable 60 FPS at 1440p on the PC and sustained 30 FPS at native UI resolution with scaled 3D render resolution on the phone; no crash or lost save; trade totals and map labels readable without zoom; glass and interior pass a blind art review using the same reference images. These are **targets to test, not claims about results**. If URP passes, adopt it and budget the UI rebuild. If it misses only art quality, compare a short Unreal desktop scene and price a distinct mobile tier. If Three.js reaches those gates with less labor, keep the browser build as the low-friction reference while continuing the requested URP native target. Either way, keep the phone test in the first decision, not as a future promise. [Three.js resolution guidance](https://threejs.org/manual/pages/responsive.html); [Unity platform builds](https://docs.unity.com/en-us/engine/6000.6/manual/building-and-publishing/build-settings/create-build-profile); [Unreal mobile performance guidance](https://dev.epicgames.com/documentation/en-us/unreal-engine/performance-guidelines-for-mobile-devices-in-unreal-engine).
