An API-only Python render engine — PBR meshes, point clouds, and IBL lighting with a deterministic CPU reference path
Render meshes and point clouds into lit, shadowed, tonemapped images — one render(...) call, tensor in, tensor out.
Quick Start · Screenshots · Feature Matrix · Architecture · User Guide · API Reference
IronEngine-BonaFide is a from-scratch, API-only render engine. You build a
Scene out of meshes, point clouds, lights, and image-based lighting; you call
render(engine, scene, camera, config); you get a torch.Tensor back —
RGB plus optional depth, normals, IDs, and albedo sensor outputs.
It is the drop-in renderer for the IronEngine family: 3DCreator (prompt → point cloud) integrates through a headless-safe shim.
The engine has three backend paths — CUDA (via optional gsplat / nvdiffrast /
NVIDIA Warp kernels), wgpu-py, and a pure NumPy/PyTorch CPU reference
rasterizer that is fully functional, deterministic, and perspective-correct.
Engine.auto() picks the best available and honestly falls back to CPU
when the GPU kernel extras are not installed.
We will not beat Vulkan or PhysX in raw throughput from Python. Our pitch is "lighter than panda3d, more capable than taichi, differentiable by design, tensor-native end-to-end." Today the battle-tested path is the CPU reference backend; the CUDA kernel extras and wgpu WGSL pipelines are real code but are explicitly roadmap (see the feature matrix). If that's what you need — read on.
Both frames were rendered end-to-end by BonaFide (CPU backend, 1280×720) from scenes exported by the IronEngine pipeline.
| Daylight | Golden hour |
|---|---|
![]() |
![]() |
Left: procedural-sky IBL + envmap background + cascaded shadow maps +
vertex-colored GLB assets. Right: warm low-sun IBL, long shadows, and
texture-mapped plank flooring sampled through the PBR pass.
Real-world assets loaded straight from disk — PLY, GLB (with embedded
textures), OBJ+MTL, and colored point clouds — rendered end-to-end by the
BonaFide CPU backend: auto-framed camera, procedural-sky IBL, envmap
background, CSM shadows, 1280×720.
Full write-up with per-model code: Gallery ·
Formats & recipes: Rendering Files ·
Reproduce locally: python examples/render_external.py.
| Stanford Bunny (PLY mesh) | Avocado (GLB) |
|---|---|
![]() |
![]() |
| Stanford 3D Scanning Repository — ascii PLY, 69k tris | Khronos sample model, CC0 (Microsoft) |
| BoomBox (GLB) | KayKit chest (OBJ) |
|---|---|
![]() |
![]() |
| Khronos sample model, CC0 (Microsoft) | KayKit Dungeon pack, CC0 (Kay Lousberg) |
| Dolphins point cloud (colored PLY) |
|---|
![]() |
| Ascii PLY point cloud, per-vertex RGB, LOD + surfels — MIT (three.js) |
pip install -e .Extras (all optional — the core engine runs on NumPy + PyTorch alone):
| Extra | Pulls | When |
|---|---|---|
[cuda] |
cupy-cuda12x, warp-lang, gsplat, nvdiffrast |
NVIDIA GPU kernels (roadmap paths) |
[wgpu] |
wgpu |
AMD / Intel / Apple GPU (roadmap path) |
[formats] |
pyktx, openvdb, usd-core, OpenEXR |
KTX2, VDB, USD asset support |
[viewers] |
rerun-sdk, polyscope |
Bring-your-own interactive viewer |
[dev] |
pytest, pyright, ruff |
Development |
[all] |
all of the above | Everything |
Verified against the current API — copy, paste, run:
import numpy as np
from ironengine_bonafide.api import (
Engine, Scene, Mesh, PBRMaterial, PerspectiveCamera,
DirectionalLight, RenderConfig, render,
)
engine = Engine.auto() # cuda → wgpu → cpu fallback
quad = Mesh.from_arrays(positions=np.array([[-1,-1,0],[1,-1,0],[1,1,0],[-1,1,0]], np.float32),
indices=np.array([[0,1,2],[0,2,3]]),
material=PBRMaterial(albedo=(0.85, 0.55, 0.3), roughness=0.45))
scene = Scene().add(quad).add(DirectionalLight(direction=(-0.4, -1.0, -0.3), intensity=3.0))
cam = PerspectiveCamera(position=(0, 0, 3), look_at=(0, 0, 0), fov_deg=45)
out = render(engine, scene, cam, RenderConfig(width=640, height=360, output_color_space="sRGB"))
out.rgb.save("preview.png", display_ready=True)More recipes in examples/ — GLB/OBJ mesh rendering, point
clouds, 3DCreator session → image, and an experimental differentiable
inverse-rendering demo.
# At app start, before any rendering happens:
from ironengine_bonafide.integrations.creator3d import install
install()
# 3DCreator's UI now renders through BonaFide. No 3DCreator code changed.Honest status — ✅ means implemented and covered by the test suite (119 passed, 10 skipped as of this release); 🚧 means real code exists but the path is not production-ready.
| Subsystem | Status | Notes |
|---|---|---|
| Sky pass | ✅ | Solid, gradient, and envmap equirect backgrounds |
| Image-based lighting | ✅ | Equirect diffuse irradiance + roughness-mip specular from HDR/EXR or in-memory pixels |
| CSM shadows | ✅ | Cascaded shadow maps on all backends, including CPU |
| CPU rasterizer | ✅ | Perspective-correct, deterministic (seeded, bit-exact within the backend) |
| PBR shading | ✅ | Cook-Torrance GGX specular; roughness / metallic / emissive honored |
| Texture maps | ✅ | Albedo / normal / metallic-roughness / AO map sampling in PbrPass — maps are supplied through the API |
| Tonemap | ✅ | Single, consistent ACES filmic → sRGB pipeline |
| GLB / glTF loader | ✅ | Node transforms, byteStride interleaved buffers, multi-buffer, normalized COLOR_0 |
.iemodel.json loader |
✅ | 3DCreator manifest sidecar, schema versions iemodel/1 and iemodel/2 |
| Asset formats | ✅ | PLY · PCD · OBJ · GLB · HDR · EXR · PNG/JPG (KTX2 / VDB / USD behind [formats]) |
| 3DCreator shim | ✅ | Headless-safe monkey-patch integration — 3DCreator's UI renders through BonaFide |
| Render bundles | ✅ | .bnf scene + camera + config snapshots round-trip for reproducibility |
| Sensor outputs | ✅ | RGB · depth · world normals · instance IDs · GBuffer albedo as torch.Tensors |
| Differentiable render | 🚧 | render_differentiable() exists (torch autograd through the CPU path); experimental |
| GLB embedded textures | ✅ | Embedded / data: / relative-URI baseColor textures decode to albedo_map — normal/MR/AO/emissive maps, KTX2, and KHR_texture_transform not yet |
| CUDA kernel extras | 🚧 | gsplat / nvdiffrast / Warp paths are wired but optional; Engine.auto() falls back to CPU when absent |
| wgpu WGSL pipelines | 🚧 | Backend scaffolding present; WGSL pipelines not feature-complete |
| TAA / SMAA | 🚧 | Pass stubs exist; true temporal/smaa anti-aliasing not yet (FXAA works) |
| Neural FX / volumetrics / fluids | 🚧 | Pass scaffolding only — denoise, upscale, relight, smoke, water are roadmap |
┌──────────────────────────────────────────────────────────────────┐
│ L5 Integrations: 3DCreator shim · CLI · folder mount │
├──────────────────────────────────────────────────────────────────┤
│ L4 Public API: render(scene, camera, config) → RenderOutputs │
├──────────────────────────────────────────────────────────────────┤
│ L3 Render passes: sky · CSM shadow · splat · PBR · post (ACES) │
├──────────────────────────────────────────────────────────────────┤
│ L2 Scene graph + asset cache + material binding + asset mount │
├──────────────────────────────────────────────────────────────────┤
│ L1 Kernel backends: CUDAPath · WGPUPath · CPUPath │
├──────────────────────────────────────────────────────────────────┤
│ L0 Tensor core: PyTorch + NumPy (CuPy/DLPack on the CUDA path) │
└──────────────────────────────────────────────────────────────────┘
Engine.auto() picks the best path available; you can pin one with
Engine.cuda(), Engine.wgpu(), Engine.cpu(). The CPU path is the
reference implementation every other backend is validated against.
- User Guide — installation, scenes, cameras, materials, recipes, troubleshooting
- Rendering Files — point clouds & external 3D models: formats, loaders, textures, per-format recipes
- API Reference — every class, method, and parameter
- Architecture Notes — layer-by-layer design rationale
- Performance Notes — honest comparison vs panda3d / taichi
- Not a Vulkan / PhysX competitor on raw FPS. We wrap Python-accessible kernels; native engines wrap C++.
- Not a real-time interactive viewer. We're API-only. Plug
rerun-sdkorpolyscopeif you need a window. - Not a NeRFstudio replacement. Neural-field training helpers are roadmap, not a shipped framework.
- Not another OpenGL/forward-PBR viewer app. That's what the sibling IronEngine projects are for.
Distributed under the MIT License. See LICENSE for full text.
Built on top of NumPy and PyTorch, with optional CUDA kernels (gsplat, nvdiffrast, NVIDIA Warp) and wgpu-py.
By DunknowCoding · part of the IronEngine family.





