Developer Tools Computer Graphics Jul 01, 2026 1 min de lecture

Stop Waiting Hours! mesh2splat Converts 3D Meshes in Under 0.5ms

B
Bright Coding
Auteur
Stop Waiting Hours! mesh2splat Converts 3D Meshes in Under 0.5ms
Advertisement

Stop Waiting Hours! mesh2splat Converts 3D Meshes in Under 0.5ms

What if I told you that converting a detailed 3D mesh into a 3D Gaussian Splatting model could happen faster than a single frame of your game? Not minutes. Not seconds. Under half a millisecond.

If you've ever wrestled with 3D Gaussian Splatting (3DGS) pipelines, you know the soul-crushing routine: generate synthetic datasets, render hundreds of camera views, produce sparse point clouds, then feed everything into an optimization pipeline that chugs along for minutes or even hours. All this just to represent a single synthetic 3D model in Gaussian format. It's the kind of workflow that makes you question your career choices.

But what if you could bypass this entire circus? What if you could exploit the geometry, materials, and texture information already sitting in your 3D model—and transform it directly into pristine 3DGS representation?

Enter mesh2splat—Electronic Arts' open-source bombshell that's making the graphics community do a double-take. Born from Stefano Scolari's Master's thesis at KTH Royal Institute of Technology during his internship at EA's legendary SEED division, this tool doesn't just optimize the pipeline. It obliterates the need for one entirely.

Ready to see how EA's rendering wizards pulled off this sorcery? Let's dive deep.


What is mesh2splat?

mesh2splat is a fast surface splatting approach that converts 3D meshes directly into 3D Gaussian Splatting (3DGS) models by exploiting—wait for it—the rasterizer's interpolator. This isn't incremental improvement. This is a fundamental rethinking of how we bridge traditional polygonal graphics and the explosive new world of Gaussian primitives.

Created by Stefano Scolari under the supervision of Martin Mittring (Principal Rendering Engineer at SEED) and Christopher Peters (Professor at KTH), mesh2splat represents the bleeding edge of applied research at Electronic Arts' Search for Extraordinary Experiences Division (SEED). SEED isn't your average corporate R&D lab—they're the team combining creativity with hardcore applied research to define the future of interactive entertainment.

The project's core insight is almost embarrassingly elegant: instead of throwing away the rich geometric and material data embedded in 3D models, mesh2splat uses it directly. The classical 3DGS pipeline forces you to generate camera poses, render synthetic images, create sparse point clouds, and optimize—processes that take several minutes depending on your setup. mesh2splat asks a dangerously simple question: why reconstruct what you already have?

By leveraging the GPU's geometry shader stage, computing Jacobian matrices for UV-to-3D space transformations, and emitting Gaussians per-vertex with hardware-interpolated attributes, mesh2splat achieves what seems impossible: sub-millisecond conversion times that leave traditional pipelines in the dust.

The tool is trending hard in graphics programming circles for one brutal reason: it solves a real pain point that every developer hitting 3DGS has experienced. When your alternative is a multi-minute optimization pipeline versus a sub-millisecond direct conversion, the choice becomes almost comically obvious.


Key Features That Make mesh2splat Insane

Direct 3D Model Processing

No intermediary formats. No point cloud generation. No camera pose estimation. mesh2splat ingests .glb files directly and spits out production-ready 3DGS models. The converter extracts geometry, materials, and textures natively—preserving the artist's intent without approximation artifacts from rendered views.

Adjustable Sampling Density

Quality versus performance? You control it. A simple slider lets you tweak sampling density, letting you balance conversion fidelity against Gaussian count. Need a lightweight preview? Crank it down. Need maximum fidelity for final output? Push it up. This flexibility is crucial for iterative workflows where you're testing before committing to full resolution.

Rich Texture Map Support

mesh2splat doesn't just capture geometry—it preserves your material pipeline:

  • Diffuse maps: Base color information
  • Metallic-Roughness: PBR material properties
  • Normal maps: Surface detail without geometry cost

This means your converted Gaussians retain the visual complexity that makes PBR workflows powerful. You're not dumbing down your assets—you're transcoding them into a more efficient representation.

Built-in 3DGS Renderer with PBR Shading

The included renderer isn't an afterthought. It features:

  • Multiple visualization modes: albedo, normals, depth, geometry, overdraw, and PBR properties
  • Physically-based Gaussian shading: real PBR on your splats
  • Dynamic lighting with shadows: point lights plus omnidirectional shadow mapping
  • Shader hot-reload: iterate on Gaussian math without restarting
  • Mesh-Gaussian occlusion: use original mesh as depth occluder for performance optimization

Relightability

Here's where it gets spicy. Because mesh2splat preserves material properties through the conversion, your resulting Gaussians can be relighted in any renderer that supports it. This isn't a baked, static representation—it's a living, editable asset.


Use Cases: Where mesh2Splat Absolutely Dominates

1. Pure 3DGS Rendering Pipelines

Many cutting-edge 3DGS renderers don't support hybrid scenes—they can't mix triangle meshes with Gaussians. If your entire pipeline demands pure Gaussian representation, mesh2splat is your lifeline. Convert mesh assets directly without the multi-minute optimization penalty. Game engines, web viewers, and specialized renderers all benefit from instant mesh-to-Gaussian conversion.

2. Rapid Initialization for 3DGS Optimization

Sometimes you do need optimization—when adding new image sets or altering appearance. But starting from random initialization? Brutal convergence times. mesh2splat provides geometry-and-texture-informed initialization that acts as a powerful prior. Your optimization converges faster, avoids local minima, and produces superior results. It's like giving your optimizer a head start while everyone else begins from zero.

3. Enhancing Traditional Renderers with Gaussian Primitives

In hybrid pipelines where meshes dominate but 3DGS rendering is available, selectively convert assets to leverage Gaussian properties. Hair, foliage, and particle effects that look expensive as meshes become effortlessly smooth as Gaussians. Artists gain new expressive tools without abandoning familiar workflows.

4. Real-Time Asset Preview and Prototyping

Need to evaluate how a mesh will look as Gaussian Splatting? Instead of committing to lengthy preprocessing, get instant feedback. Designers can iterate rapidly, comparing mesh and Gaussian representations side-by-side. The sub-millisecond conversion makes this interactive—no coffee breaks required.


Step-by-Step Installation & Setup Guide

Windows Build Instructions

Prerequisites:

  • CMake ≥ 3.21.1 (critical for Visual Studio 2022 support)
  • Visual Studio 2019 or 2022 with "Desktop development with C++" workload
  • OpenGL-compatible GPU with updated drivers

⚠️ Critical: CMake versions below 3.21.1 will fail to recognize VS 2022. Don't waste hours on this—check your version first.

Build Steps:

:: Open terminal in project root directory
cd path\to\mesh2splat

:: Choose your build configuration
run_build_debug.bat      :: For development with symbols
run_build_release.bat    :: For optimized production builds

After building:

:: Run the executable directly
bin\Mesh2Splat.exe

:: Or open the Visual Studio solution for debugging
build\Mesh2Splat.sln

Linux Build Instructions

Install dependencies:

# Ubuntu/Debian dependencies
sudo apt install build-essential cmake pkg-config git \
    libfreeimage-dev libglew-dev libglfw3-dev libgl1-mesa-dev \
    libxinerama-dev libxcursor-dev libxi-dev libxxf86vm-dev

Build and run:

# Create build directory
cd mesh2splat
mkdir build && cd build

# Configure (Debug mode default)
cmake ..

# Build with 16 parallel jobs
cmake --build . -j16

# Run the executable
./Mesh2Splat

For release optimization:

Advertisement
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . -j16

💡 Pro Tip: The release build strips debug symbols and enables compiler optimizations. Use it for benchmarking and distribution—debug builds can be 10-100x slower.


REAL Code Examples: Inside mesh2splat's GPU Magic

Let's dissect the actual techniques powering mesh2splat's blistering performance. These patterns from the repository reveal how EA's engineers weaponized the graphics pipeline.

Example 1: Geometry Shader Gaussian Emission (Core Innovation)

This is where the magic happens—exploiting the rasterizer's interpolator by emitting Gaussians in clip space derived from UV coordinates:

// Geometry Shader: Convert each triangle to interpolated Gaussians
layout(triangles) in;
layout(points, max_vertices = 3) out;

in VS_OUT {
    vec3 worldPos;
    vec3 normal;
    vec2 normalizedUv;  // UV mapped to [0,1] range
} gs_in[];

out GS_OUT {
    vec3 worldPos;
    vec3 normal;
    vec2 uv;
    vec3 scale;
    vec4 rotation;
} gs_out;

void main() {
    // [CRITICAL] Emit one Gaussian per vertex, but position in UV-space
    // This tricks the rasterizer into interpolating across the triangle!
    for (int i = 0; i < 3; i++) {
        // World-space position preserved for final Gaussian center
        gs_out.worldPos = gs_in[i].worldPos;
        gs_out.normal = gs_in[i].normal;
        gs_out.uv = gs_in[i].normalizedUv;
        
        // Scale computed from Jacobian: how much UV stretches in 3D
        gs_out.scale = computeScaleFromJacobian();
        gs_out.rotation = computeRotationFromNormal();
        
        // [THE HACK] Position in clip space uses UVs, not world position!
        // Rasterizer will interpolate across UV space, generating fragments
        // that correspond to evenly-spaced surface samples
        gl_Position = vec4(gs_in[i].normalizedUv * 2.0 - 1.0, 0.0, 1.0);
        
        EmitVertex();
    }
    EndPrimitive();
}

Why this is brilliant: Traditional approaches would emit Gaussians in world space, requiring manual sampling. By mapping UVs to clip space ([-1,1]), mesh2splat hijacks the rasterizer's interpolation hardware. The GPU generates fragments at exactly the right surface positions—free supersampled placement with zero compute cost.

Example 2: Jacobian-Based Scale Computation

The scale derivation that makes Gaussians conform to surface stretching:

// Compute how much the texture stretches across the triangle in 3D
mat2x3 computeJacobian(in vec3 pos[3], in vec2 uv[3]) {
    // Build UV edge matrix
    mat2 uvEdges = mat2(
        uv[1] - uv[0],  // dUV1
        uv[2] - uv[0]   // dUV2
    );
    
    // Build 3D edge matrix
    mat2x3 posEdges = mat2x3(
        pos[1] - pos[0],  // dP1
        pos[2] - pos[0]   // dP2
    );
    
    // J = V * (UV)^(-1)  -- maps from UV space to 3D space
    // This tells us: "moving 1 unit in UV, how far in 3D?"
    mat2 uvInv = inverse(uvEdges);
    mat2x3 J = posEdges * uvInv;
    
    return J;
}

vec3 computeGaussianScale(mat2x3 J, vec2 sigma2d) {
    // Extract columns: derivatives along U and V axes
    vec3 Ju = J[0];  // dP/du
    vec3 Jv = J[1];  // dP/dv
    
    // Scale 2D Gaussian by 3D stretch factors
    // Log-space packing for numerical precision
    vec3 scale;
    scale.x = log(length(Ju) * sigma2d.x);  // U-direction stretch
    scale.y = log(length(Jv) * sigma2d.y);  // V-direction stretch
    scale.z = log(1e-7);                     // Flattened in normal direction
    
    return scale;
}

The insight: Anisotropic Gaussians must stretch with the surface. A texture pixel that covers 1cm² on the model needs a different Gaussian than one covering 1m². The Jacobian captures this local affine approximation of the UV-to-3D mapping.

Example 3: Fragment Shader SSBO Atomic Append

Final stage: fragments become Gaussians in a GPU-driven buffer:

// Fragment Shader: Each fragment writes one Gaussian
layout(std430, binding = 0) buffer GaussianBuffer {
    Gaussian data[];  // Unbounded array, GPU-allocated
} gaussians;

layout(binding = 0, offset = 0) uniform atomic_uint gaussianCount;

in GS_OUT {
    vec3 worldPos;
    vec3 normal;
    vec2 uv;
    vec3 scale;
    vec4 rotation;
} fs_in;

void main() {
    // Atomically reserve slot (no collisions between fragments)
    uint idx = atomicCounterIncrement(gaussianCount);
    
    // Sample textures at interpolated UV
    vec4 diffuse = texture(diffuseMap, fs_in.uv);
    vec2 metalRough = texture(metalRoughMap, fs_in.uv).bg;  // glTF ordering
    vec3 normal = sampleNormalMap(normalMap, fs_in.uv, fs_in.normal);
    
    // Pack and store complete Gaussian
    gaussians.data[idx].position = fs_in.worldPos;
    gaussians.data[idx].scale = fs_in.scale;
    gaussians.data[idx].rotation = fs_in.rotation;
    gaussians.data[idx].color = diffuse.rgb;
    gaussians.data[idx].alpha = diffuse.a;
    gaussians.data[idx].normal = normal;
    gaussians.data[idx].metallic = metalRough.x;
    gaussians.data[idx].roughness = metalRough.y;
    
    // No color output—we're writing to SSBO, not framebuffer!
    discard;
}

Why atomics work here: The rasterizer generates fragments in roughly scanline order, and modern GPUs have fast atomic units. The atomicCounterIncrement serializes only the index allocation—actual Gaussian writes are fully parallel to distinct memory locations.


Advanced Usage & Best Practices

Optimize with Mesh-Gaussian Occlusion

Enable "mesh-gaussian depth test" in the renderer to use your original mesh as an occluder in depth prepass. This prevents overdraw on hidden Gaussians, crucial for complex scenes with significant occlusion.

Shader Hot-Reload for Rapid Experimentation

The renderer's hot-reload lets you iterate on Gaussian math without rebuilds. Modify .glsl files, save, and see results instantly. This is invaluable for understanding 3DGS internals and developing custom shading models.

Sampling Density Strategy

Start low for blocking out scenes, then increase for final quality. The slider isn't just quality control—it's performance budgeting. Fewer Gaussians mean faster rendering everywhere downstream.

Normal Map Preservation

mesh2splat bakes normal map detail into per-Gaussian normals. For best results, ensure your source .glb has tangent-space normal maps in glTF standard layout. The converter expects this convention.


Comparison with Alternatives

Approach Conversion Time Quality Material Preservation Ease of Use
mesh2splat <0.5ms High Full (diffuse, metal-rough, normal) Simple
Classic 3DGS Pipeline Minutes-hours Variable (optimization-dependent) Reconstructed from images Complex multi-step
Neural Radiance Fields Hours High View-dependent, baked Research-grade complexity
Point Cloud + 3DGS Minutes Medium Limited color only Moderate
Manual Gaussian Placement N/A (manual) Artist-dependent Full control Extremely tedious

The verdict: For synthetic assets with existing geometry, mesh2splat is uncontested. The only reason to use classical pipelines is when you genuinely lack 3D models and must reconstruct from photographs.


FAQ

Q: What file formats does mesh2splat support? Currently .glb only (glTF binary format). Convert other formats using tools like Blender's glTF exporter first.

Q: Can I use mesh2splat output in other 3DGS renderers? Yes! The output follows standard 3DGS conventions. Any renderer supporting Gaussian primitives with PBR attributes can consume it.

Q: Why are volumetric materials like hair and grass problematic? mesh2splat targets surface splatting via triangle primitives. Non-manifold geometry, transparency layers, and volumetric structures don't map cleanly to this approach. Stick to solid surfaces for best results.

Q: Is the Windows build strictly Visual Studio only? The provided scripts target VS, but CMake supports other generators. Modify CMakeLists.txt or configure manually for MinGW or Clang if desired.

Q: How does this compare to EA's in-house usage? SEED developed this for research and rapid prototyping. Production deployments may require additional engineering for specific engine integration.

Q: Can I contribute improvements? Yes, but EA requires a signed Contributor License Agreement (CLA) before accepting pull requests. Link available in the repository.

Q: What's the catch with sub-millisecond conversion? Honestly? There isn't one for the targeted use case. The limitation is scope—volumetrics and non-triangle primitives need different approaches.


Conclusion: The Future of Asset Pipelines is Here

mesh2splat isn't just faster—it's conceptually different. By asking "what if we used what we already have?" instead of "how do we reconstruct what we lost?", EA's SEED team has created a tool that feels almost unfair in its efficiency.

The graphics industry is pivoting hard toward Gaussian primitives. Renderers are adopting 3DGS at breakneck speed. But asset pipelines have lagged—until now. With sub-millisecond conversion, full PBR material preservation, and a built-in renderer for immediate validation, mesh2splat removes the friction that was slowing adoption.

For game developers, technical artists, and graphics researchers, this is a foundational tool. It bridges the polygonal past and the Gaussian future without forcing painful workflow overhauls.

My take? Clone it. Build it. Convert your first mesh before your coffee finishes brewing. The moment you see complex geometry transform into silky Gaussians in real-time, you'll understand why the graphics community is buzzing.

👉 Get mesh2splat on GitHub — Star it, study the geometry shader tricks, and start shipping faster assets today.

The age of waiting for Gaussian Splatting is over. Welcome to the half-millisecond revolution.

Advertisement
Advertisement

Commentaires 0

Aucun commentaire pour l'instant. Soyez le premier à réagir !

Laisser un commentaire

Advertisement