Skip to main content

MLX3D

PyPI Python Tests Docs License: MIT

Differentiable 3D computer vision on Apple Silicon, built on MLX.

MLX3D brings the PyTorch3D workflow to Macs: batched 3D data structures, cameras, differentiable rendering, and modern view synthesis — NeRF and 3D Gaussian Splatting with custom Metal kernels — running natively on the Apple GPU.

📖 Documentation & tutorials

Features

  • Structures — batched Meshes / Pointclouds with list, packed and padded views; differentiable normals, areas, edges.
  • Cameras & transforms — OpenCV/COLMAP-convention pinhole cameras (ray generation, projection, look-at) and batched rotation conversions (quaternion, axis-angle, Euler, 6D).
  • Ops & losses — GPU brute-force k-NN, chamfer distance, area-weighted surface sampling, Laplacian/edge/normal-consistency mesh losses, PSNR and differentiable SSIM.
  • NeRF — positional encoding, the NeRF MLP, stratified + hierarchical sampling, volume rendering, Blender-synthetic dataset loader.
  • Mesh rendering — differentiable soft triangle rasterization, UV texture sampling for OBJ/MTL assets, and scalar-field mesh extraction.
  • Gaussian Splatting — a Metal translation of the reference CUDA rasterizer (tile-based forward & backward kernels wrapped in mx.custom_function), EWA projection, spherical harmonics, anti-aliased and arbitrary feature rendering, adaptive density control, COLMAP loading, and standard 3DGS .ply checkpoints. ~30 FPS forward at 720p with 100k Gaussians on an M-series GPU.
  • Capture pipelinemlx3d-capture photos_or_video goes from raw photos or a phone video to a trained splat in one resumable command: sharp-frame selection, COLMAP or built-in COLMAP-free SfM (with joint pose refinement during training), live training preview, and a compacted .ply export.
  • Fast splat viewing — a forward-only rasterization path (FastGaussianRenderer, mlx3d-view --fast) with fused Metal geometry kernels, cross-frame caching, and sync-free frames: 1.5–2× faster than the training rasterizer on real scenes (up to 3.7× for large splats) at 45+ dB parity, and 67 fps playback of dynamic 4D Gaussian sequences.
  • Interactive viewermlx3d-view point_cloud.ply opens a browser viewer with orbit/pan/zoom; frames are rendered on the Apple GPU by the Metal rasterizer and streamed live. Works for NeRFs too.
  • IO — OBJ and PLY (ascii + binary, including Gaussian Splatting checkpoint layouts), plus one-line image save_image / load_image for any renderer output.
  • Composable & extensible — every image renderer is a plain callable (camera, scene) -> {"image", "alpha", "depth"} (the Renderer protocol), so you can drop in your own rasterizer, shader, or ray tracer and reuse the rest of the pipeline — no base classes to subclass.

Installation

pip install mlx3d

Requires an Apple Silicon Mac and Python ≥ 3.10.

Photos → splat in minutes

Turn a folder of photos — or a phone video — into a trained 3D Gaussian Splat with one command, entirely on your Mac:

mlx3d-capture ./my_photos/          # or: mlx3d-capture walkaround.mp4

Left: one of 11 input photos. Right: the trained 3D Gaussian Splat rendered from the same viewpoint.
11 photos in, splat out — input photo (left) vs. the trained splat (right), poses from the built-in COLMAP-free SfM, ~5 minutes on an M-series laptop.

This runs the whole pipeline: frame extraction (with automatic motion-blur filtering for video) → camera poses → 3DGS training with a live browser viewer → a compacted splat.ply you can open in any splat viewer. Poses come from COLMAP when it's installed (brew install colmap); otherwise mlx3d's built-in COLMAP-free SfM (pip install "mlx3d[capture]") handles them and the trainer refines poses jointly with the splats. Stages are cached, so re-runs resume where they left off.

mlx3d-capture clip.mp4 --quality fast     # quick preview
mlx3d-capture ./my_photos/ --quality best # 30k iterations, full resolution

See the capture tutorial for capture tips and every option.

Quick example

import mlx.core as mx
from mlx3d.cameras import Camera
from mlx3d.splatting import GaussianModel

model = GaussianModel.from_points(
    points=mx.random.normal((10_000, 3)) * 0.5,
    colors=mx.random.uniform(shape=(10_000, 3)),
)
camera = Camera.look_at(eye=(0, 0, -4), at=(0, 0, 0), width=1280, height=720)
out = model.render(camera)            # differentiable end to end
print(out["image"].shape)             # (720, 1280, 3)

Train Gaussian Splatting on any COLMAP scene (same inputs as the original 3DGS):

python examples/train_gaussian_splatting.py --data /path/to/scene --iters 7000
mlx3d-view outputs/gs/point_cloud.ply --fast   # interactive viewer (forward-only fast rasterizer)
mlx3d-render outputs/gs/point_cloud.ply --out render.png --antialias
mlx3d-eval outputs/gs/point_cloud.ply --data /path/to/scene --views 20 --json-out metrics.json
mlx3d-compact outputs/gs/point_cloud.ply --out point_cloud_small.ply --max-gaussians 500000

For viewing-only workloads (viewers, flythroughs, 4D playback), the fast rasterization path renders the same checkpoints 1.5–2× faster at 45+ dB parity:

from mlx3d.splatting import FastGaussianRenderer

renderer = FastGaussianRenderer(model)     # caches activations, covariances, SH colors
out = renderer.render(camera)              # forward-only: {"image", "alpha"}

More in the docs: mesh optimization, point cloud fitting, NeRF, Gaussian Splatting.

Gallery

3D Gaussian Splatting render of the Tanks & Temples truck scene
3D Gaussian Splatting (Tanks & Temples truck), Metal rasterizer
Rendered normals of the truck scene
The same splat rendered as normals — any per-Gaussian feature works
Hash-grid NeRF render of the Lego scene
Instant-NGP-style hash-grid NeRF (Blender Lego)
Lit mesh render
Differentiable mesh rendering with Phong shading
Dynamic 4D Gaussian sequence played back with the fast rasterizer
Dynamic 4D Gaussians (336k splats × 150 timesteps) played back at 67 fps by the forward-only fast rasterizer

Examples

The examples/ folder has runnable scripts for every core feature. The self-contained ones generate their own synthetic data — no downloads — and finish in seconds:

uv run python examples/render_mesh.py        # soft mesh rasterization
uv run python examples/raytrace_volume.py    # ray casting + volume rendering
uv run python examples/extract_mesh.py       # marching cubes from an SDF
uv run python examples/fit_pointcloud.py     # point-cloud optimization
uv run python examples/fit_mesh.py           # mesh fitting (chamfer + regularizers)
uv run python examples/fit_nerf.py           # train a small NeRF
uv run python examples/fit_gaussians.py      # fit 3D Gaussians
uv run python examples/extend_renderer.py    # plug in a custom renderer

See examples/README.md for the full list, including the COLMAP/Blender training scripts.

Development

Development uses uv:

git clone https://github.com/amirhossein-razlighi/mlx3D
cd mlx3D
uv sync               # creates .venv with all dev dependencies
uv run pytest tests/
uv run mkdocs serve   # docs at http://127.0.0.1:8000

Prefer plain pip? The package installs editable with the standard dev extra:

python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest

[!NOTE] uv-created .venvs do not ship their own pip. Inside one, use uv pip ... (or uv run ...); a bare pip may resolve to a different Python and silently install into the wrong environment.

Contributions are welcome — see CONTRIBUTING.md for the workflow and guidelines, or file an issue to get started.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mlx3d-0.3.0.tar.gz (8.5 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mlx3d-0.3.0-py3-none-any.whl (169.7 kB view details)

Uploaded Python 3

File details

Details for the file mlx3d-0.3.0.tar.gz.

File metadata

  • Download URL: mlx3d-0.3.0.tar.gz
  • Upload date:
  • Size: 8.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for mlx3d-0.3.0.tar.gz
Algorithm Hash digest
SHA256 e9b50c0d304a938342ec420195fbf4a5dc3fa3bc45001ab88a533f2d6babb72e
MD5 c7503b15fd84e4def0447729484239b3
BLAKE2b-256 7a2b4b1730089f851fe0999690b8c401dfba39cfde639059c72129806d57c5ce

See more details on using hashes here.

Provenance

The following attestation bundles were made for mlx3d-0.3.0.tar.gz:

Publisher: publish.yml on amirhossein-razlighi/mlx3D

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mlx3d-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: mlx3d-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 169.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for mlx3d-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bdfdffe97d2a933afb6bdac2c01ae609c119bf1e22fe129469f4ab03a59439bf
MD5 2b9cbfb6258cdddc0ca270173839c269
BLAKE2b-256 1ce51a2604d71be0be55c2baf1f7625831f12063c96e1628240d7588d52c8a72

See more details on using hashes here.

Provenance

The following attestation bundles were made for mlx3d-0.3.0-py3-none-any.whl:

Publisher: publish.yml on amirhossein-razlighi/mlx3D

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 files

0.2.1

2 files

0.2.0

2 files

0.1.1

2 files

0.1.0

2 files

0.0.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page