中文 English

Jining Mido Information Technology Co., Ltd

Getting Real-World Scans into a Browser 3D Virtual World: Building 3D Gaussian Splatting In-House

3D Gaussian Splatting3DGS browser renderingreal-world scan 3Dphotorealistic scenesThree.js 3DGSPLY parsingspherical harmonicsself-hosted 3D virtual worldphotographic showroom

Everyone building 3D worlds hits the same wall: no matter how much you model by hand, the result looks like a model — clean edges, fake lighting, plastic materials. Scenes scanned from the real world (an old street, a gallery, a cliff face) carry photographic texture. How do you get those into a browser?

One answer is 3D Gaussian Splatting (3DGS): a cloud of colored Gaussians trained from real photos that reproduces the actual viewpoints. This article covers how we got 3DGS running inside our own browser-based 3D virtual world base layer — why we chose to build the parsing and rendering in-house, what the engineering involved, what the acceptance numbers are, and most importantly: what remains unmeasured, and which scenes 3DGS does not suit.

1. Which gap 3DGS fills

Until now, the "realistic" content in our world came from three sources: hand modeling (weakest texture), photo textures (flat), and video (you cannot walk into it). 3DGS fills the "a scanned scene you can walk into" slot: shoot a full circle around a real scene with mainstream scanning tools, train the Gaussian cloud, render it directly in the browser, and what you see carries the actual lighting and detail.

But it is not a replacement for geometric models. Gaussians have no editable mesh: collision, picking, re-texturing, resizing — the capabilities that belong to models — are simply unavailable in 3DGS. So its role in our base layer is the "photoreal backdrop layer," coexisting and mixing with GLB models and geometric geometry in the same world: a gallery's walls restored as a photographic splat, while the booths and interactive equipment remain geometric models.

2. Why in-house rather than an existing library

Open-source browser 3DGS renderers exist, and wiring one in looks like the shorter path. We chose to build it ourselves for two reasons:

Dependency discipline. The base layer's rendering kernel is our own Three.js r185/WebGL2 pipeline, with zero third-party 3DGS library dependencies across the world. An external rendering library brings its own loading, sorting, and dispose lifecycle running in parallel with the world's existing object lifecycle — you save integration time and owe maintenance on two lifecycles.

Pipeline consistency. In-house parsing and rendering ride the same WebGL2 pipeline: GLSL1-style code compiles automatically under the r185 WebGL2 context, and the manual pow(1/2.2) gamma step does not produce double encoding — confirmed by test, not assumed.

The cost, stated plainly: going in-house means the classic hard problems of splat rendering — sorting, compositing — are ours to carry, and generalization must be proven by our own acceptance tests. It is a trade-off, not a free lunch.

3. What the engineering involved

The in-house chain is four modules, each owning one segment:

ModuleResponsibility
LoaderBinary PLY parsing, including full reads of the spherical harmonics coefficients f_rest_0..8
RendererBufferGeometry + ShaderMaterial + Points; the full set uploaded to the GPU in one pass
World integrationPlugs into world object lifecycle: placeholder block before entry, dispose on unload, placeholder restored
Asset library routingRead-only scene library list, automatic same-name thumbnail matching, registry-name-first ordering

A few points worth calling out:

Broad format support. Five formats are accepted — .rad / .ply / .spz / .splat / .ksplat — so exports from mainstream 3DGS training tools generally work; the training side never has to accommodate us.

Upload is library entry. A Gaussian scene dropped into the public/scenes/3dgs directory becomes part of the asset library; the world editor has a "Splat" button for direct picking, no code required.

Lifecycle parity with GLB. Unloading goes through disposeSplat and restores the placeholder block; GPU memory is released on scene switches, so long sessions do not leak — the same full-chain reclamation discipline described in our multi-client article.

4. Acceptance numbers

ItemResult
Stage acceptance26/26 passed
Real rendering scalerenderer.info.render.points = 24000 points actually drawn
SampleScript-generated INRIA-standard 62-property PLY
Third-party 3DGS library dependencies0

One row of that table deserves emphasis: the sample is a script-generated standard PLY, not real scan data. This means the chain's correctness — parsing, rendering, lifecycle, library entry — has acceptance backing, but the end-to-end test of "scan a real scene, export, upload, view in-world" has not been done. That is not a hidden trap; it requires real scanning hardware and a real scene, and we scheduled it later. If you plan to use 3DGS in production, test that link yourself first.

5. Where it fits and where it does not

ScenarioDoes 3DGS fit?
"Walk in and look" photographic showrooms, scenic areas, streetsYes — this is the reason it exists
Photoreal backdrops inside a world (mountains, cliffs, grand halls)Yes
Objects needing click interaction or physical collisionNo — use geometric models
Assets that need resizing, re-texturing, or disassemblyNo — Gaussians have no editable mesh

One sentence: 3DGS handles "looks real"; geometric models handle "touchable and editable." A world needs both — which is exactly why we built 3DGS to coexist with GLB rather than replace it.

6. Boundaries and unmeasured items

  • No end-to-end test with real scan data. The acceptance sample is a script-generated INRIA-standard 62-property PLY; the chain "real scan → export → upload → in-world" has not yet been run with photographic data.
  • Frame rates at large Gaussian counts are not fully measured. Acceptance covers 24,000 points actually drawn; behavior at hundreds of thousands or millions of points on weak devices is something you should measure on your target hardware.
  • Sorting and compositing are acknowledged hard problems in splat rendering. On the in-house route, generalization is covered by our own acceptance suite; we do not claim to cover every output variant of every training tool.
  • All numbers in the tables come from acceptance scripts in the repository, which are re-runnable; anything beyond them, verify yourself.

FAQ

Q: Is 3DGS the same thing as an ordinary point cloud?

A: No. An ordinary point cloud is discrete sampling — zoom in and you see dots. Each Gaussian in 3DGS carries an anisotropic shape, opacity, and spherical-harmonics color; composited, up close it reads as continuous photographic texture. The cost is much heavier data and rendering.

Q: Why support five formats?

A: The 3DGS training-tool ecosystem is fragmented, with different exports per tool. The base layer's stance is "the training side never accommodates us" — whoever scans the scene uses the tool they prefer, and the export just works.

Q: Can a Gaussian scene be moved and scaled like a model?

A: It can be placed into a world (with position and a placeholder mechanism), but it is a "photographic layer" with no editable mesh — there is no "stretch the splat cloud 1.2×" or "swap its material." For objects needing those operations, use GLB models.

Q: Isn't in-house slower than adopting a library?

A: In integration speed, yes — we do not dispute that account. But in-house buys a single pipeline, zero external dependencies, and lifecycle parity. For a base layer meant to be maintained long-term and deployed privately, we judged the trade worth it. If your project is a one-off showcase, adopting an existing library may suit you better.

Source & Repositories

The three mirrors are identical; the first two are faster inside China. The repos include deployment docs and a set of acceptance scripts you can run yourself to see the measured numbers.

  • Gitee (fastest in China): https://gitee.com/miduoxinxijeji/miduo.git
  • GitCode (China mirror): https://gitcode.com/qq_35054471/virtual-world
  • GitHub: https://github.com/miduo100/3d-virtual-world

About Genesis

Genesis is a self-hosted 3D virtual world system built on Three.js + WebGL, helping individuals and businesses build their own 3D spaces. Accessible directly from a browser, compatible with both PC and mobile, it supports multiplayer online, federated teleportation, a shop system, and Agent integration—where an AI can enter your world as an embodied character. Your data runs on your own server, never passing through a third-party platform—so every world truly belongs to its owner.

Want real-world scans inside your own 3D world? Genesis (a.k.a. the Genesis Virtual World CRM) is a Three.js 3D virtual world base layer that runs on your own server — the rendering kernel, asset pipeline, photographic-scene mixing, and AI access layers are already built, and scan data has somewhere to land the moment you export it. Search "Genesis Virtual World CRM" to find the site with a walkable demo world.

About the name: Genesis in this article is the same self-hosted 3D virtual world product also called the Genesis Virtual World CRM. If "Genesis" does not find us, search "Genesis Virtual World CRM".
← Back to Articles