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 (210 passed, 1 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; sun/moon discs |
| Image-based lighting | ✅ | Equirect diffuse irradiance + roughness-mip specular from HDR/EXR or in-memory pixels |
| Shadows | ✅ | CSM (cascaded, texel-snapped, slope-scaled bias) and VSM (variance shadow maps, Chebyshev soft penumbra) on all backends |
| Lights | ✅ | Directional (CSM/VSM shadows) · point · spot (cone) · area (3×3 stratified quadrature, one-sided) · IBL |
| CPU rasterizer | ✅ | Perspective-correct, near-plane split, deterministic (seeded, bit-exact within the backend); line-segment raster too |
| PBR shading | ✅ | Cook-Torrance GGX specular; roughness / metallic / emissive honored |
| Texture maps | ✅ | Albedo / normal / metallic-roughness / AO / emissive 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, incl. wireframe edges and skeleton rig overlay (0.2.0 API) |
| Render bundles | ✅ | .bnf scene + camera + config snapshots round-trip bit-exact (meshes w/ UVs, clouds, volumes, softbodies, water, particles) |
| Sensor outputs | ✅ | RGB · depth · world normals · instance IDs · GBuffer albedo as torch.Tensors |
| GLB textures (full set) | ✅ | All five slots — baseColor / normal / metallic-roughness / occlusion / emissive — resolve embedded, data:, and relative-URI sources; KHR_texture_transform baked into UVs; KHR_materials_emissive_strength honored. KTX2 stays behind [formats] |
| Anti-aliasing | ✅ | SSAA (linear-HDR resolve) · FXAA · TAA (bounded-step jitter, Catmull-Rom motion-vector reprojection, depth rejection — ghost-free) · morphological SMAA |
| Upscaling | ✅ | FSR 1.0 (edge-adaptive EASU + RCAS sharpening, pure torch, every backend) · DLSS via BONAFIDE_DLSS_DLL NGX bridge with honest FSR fallback · EDSR checkpoint hook |
| Denoise | ✅ | SVGF-style edge-aware à-trous filter guided by normals + depth; optional U-Net via BONAFIDE_DENOISE_WEIGHTS |
| SSGI | ✅ | One-bounce screen-space GI (neural_relight="ssgi"): pyramid-blurred bounce, albedo bleed, depth-spread occlusion |
| Volumetrics | ✅ | Uniform + height fog · trilinear grid raymarch (Volume.from_grid, depth-clipped) |
| Water | ✅ | Gerstner-wave surfaces (WaterSurface): analytic plane hit, wave normals, fresnel sky/IBL reflection + sun glint, Beer absorption refraction; animates per frame |
| Particles | ✅ | Deterministic CPU particle systems (ParticleSystem): gravity/drag/lifetime, seeded emitter respawn, age-fade splats |
| Differentiable render | 🚧 | render_differentiable() exists (torch autograd through the CPU path); experimental |
| CUDA kernel extras | 🚧 | gsplat / nvdiffrast / Warp paths are wired but optional; Engine.auto() falls back to CPU when absent. The bonafide_native C++/CUDA extension (octree LOD, surfel kNN+PCA, disk-splat, async upload) builds via scripts/build_native.py |
| wgpu WGSL pipelines | 🚧 | Backend scaffolding present; WGSL pipelines not feature-complete |
| Neural IBL relight | 🚧 | neural_relight="neural_ibl" records an honest skip note; learned relighting is 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.





