For the DH2323 Computer Graphics and Interaction course at KTH, Oskar Hokkanen Eriksson and I extended Mesh2Splat, an open-source project from Electronic Arts that converts 3D meshes into 3D Gaussian Splatting (3DGS) models.
🔗 Our fork on GitHub · Project report (PDF) · Project blog
Background
3D Gaussian Splatting normally requires an expensive optimization pipeline: render a synthetic dataset of the model from many camera poses, then train the Gaussians over several minutes. Mesh2Splat sidesteps all of that by exploiting the GPU rasterizer — it projects each triangle into UV space in a geometry shader and lets the hardware interpolator generate one Gaussian per fragment, converting a mesh into splats in under a millisecond.
The Problem
That speed comes from a trade-off: the rasterizer samples points on a fixed screen-space grid. For triangles that are tilted relative to their projection plane, the grid sampling becomes uneven — producing jagged edges and distorted point distributions in the converted splat model. On hard-edged models, the artifacts are clearly visible.
Our Approach
We replaced grid-based sampling with barycentric coordinate sampling: generating uniformly distributed sample points directly on each triangle’s surface in 3D, independent of its orientation. A tilted triangle gets the same sampling density as an axis-aligned one.
We first validated the idea in a small standalone C++/SDL proof of concept, comparing sample distributions on a regular triangle versus a rotated one. We then integrated it into the Mesh2Splat codebase as a new CPU conversion path (convertMeshToGaussiansCPU) that plugs into the original pipeline in place of the rasterizer-based method, including interpolating material properties (diffuse, normals) for each sampled Gaussian.
Results
The difference is most visible along edges. The original method (left/top) shows jagged, uneven Gaussians where triangles meet at an angle; our method (right/bottom) produces cleaner, more uniform edges:
On the sci-fi helmet test model, our method at a sampling density of 16 per triangle edge produced ~3.5M Gaussians, comparable to the ~2.9M from the original method at its default settings — with visibly cleaner geometry on angled surfaces.
Limitations & Future Work
We were upfront about the trade-offs in the report:
- Narrow triangles — for very thin, elongated triangles, barycentric sampling can still distribute points unevenly, leaving artifacts.
- Overlapping Gaussians — samples from adjacent triangles overlap along shared edges. We prototyped a merging pass, but the naive O(N²) neighbor search was far too slow on CPU for complex models, so we left it as future work.
- CPU-only — our implementation is a proof of concept on the CPU, so it gives up the sub-millisecond speed of the original. The sampling itself is trivially parallel, so a GPU compute shader port is the natural next step — it would keep the quality improvement while restoring most of the performance.
Working inside an unfamiliar production codebase from EA — reading the geometry shader pipeline well enough to swap out its sampling core without breaking the rest — turned out to be as instructive as the sampling method itself.