OBJ Loading¶
RayON imports triangle meshes from Wavefront .obj files and renders them with the same materials, lights and acceleration as the analytic geometry. Materials can come from the YAML scene or from the .mtl file the OBJ references, and UV-mapped image textures are sampled on the GPU.
Supported format¶
| Feature | Supported |
|---|---|
Vertex positions (v) | ✓ |
Vertex normals (vn) | ✓ smooth per-vertex normals |
Texture coordinates (vt) | ✓ UV-mapped image textures |
Triangular faces (f) | ✓ |
| Quad faces | triangulated into two triangles |
Material groups (usemtl) | ✓ per-group materials from the MTL |
MTL files (mtllib) | ✓ Kd, Ke, Ni, Ns, d, illum, map_Kd |
Faces with more than four vertices are not supported; export triangulated meshes.
Loading a mesh¶
geometry:
- type: "obj"
material: "plastic_white" # optional: fallback for groups without usemtl
file: "../models/stanford-bunny.obj"
scale: [1.0, 1.0, 1.0] # per-axis scale
position: [0.0, 0.0, 0.0] # translation applied after scaling
The file path is resolved relative to the scene file. When the OBJ carries a mtllib, the material key may be omitted and every usemtl group uses its MTL material; a YAML material is the fallback for faces without one.
Each triangle becomes one geometry entry of the scene description, so a 250 000-triangle dragon is 250 000 entries: enable use_bvh: true for any mesh.
MTL materials¶
| MTL property | Effect in RayON |
|---|---|
Kd r g b | Diffuse albedo |
Ke r g b | Emission; a non-zero value makes a light material |
Ns exponent | Converted to roughness (1 − √(Ns / 1000)) |
Ni ior | Refractive index of glass materials |
d opacity | Below 0.5 selects a glass material |
illum 0–2 | Lambertian (illum 2 is the usual exporter default for a diffuse surface) |
illum 3 and above | Rough mirror, roughness from Ns |
illum 5 / 7 | Glass |
map_Kd path | Image texture, resolved relative to the .mtl file |
Image textures¶
A map_Kd texture, or a texture: key on a YAML material, is decoded with stb_image and uploaded as a CUDA texture object. At a hit the UVs are interpolated with the barycentric weights of the triangle,
and the texel replaces the material's albedo. Textures are loaded once and shared by path.
13_texture_test1.yaml).
14_texture_test2.yaml).Triangle intersection¶
The CUDA back-end intersects triangles with the Möller–Trumbore algorithm. For a ray \(\mathbf{o} + t\mathbf{d}\) and a triangle \((\mathbf{v}_0, \mathbf{v}_1, \mathbf{v}_2)\), with \(\mathbf{e}_1 = \mathbf{v}_1 - \mathbf{v}_0\), \(\mathbf{e}_2 = \mathbf{v}_2 - \mathbf{v}_0\), \(\mathbf{p} = \mathbf{d} \times \mathbf{e}_2\), \(\mathbf{t} = \mathbf{o} - \mathbf{v}_0\) and \(\mathbf{q} = \mathbf{t} \times \mathbf{e}_1\):
The OptiX back-end hands every triangle to the RT cores: all triangles of the scene go into one geometry acceleration structure with the built-in intersector, and a per-triangle table holds the material, the normals, the UVs and the visible flag.
Smooth normals¶
With vn records the shading normal is interpolated across the face, \(\hat{n} = (1 - u - v)\,\hat{n}_0 + u\,\hat{n}_1 + v\,\hat{n}_2\), which makes a low-polygon mesh look smooth. Without them the flat face normal is used.
show_normals material (key N in the GUI).Included models¶
resources/models/ ships a set of test meshes, among them:
| File | Triangles | Used by |
|---|---|---|
bunny-3.obj, bunny-2.obj, stanford-bunny.obj | 22 k, 69 k, 69 k | 10_isc_neons_bunny, 17_cloud_bunny |
xyzrgb_dragon.obj | 250 k | 04_obj_dragon |
dragon.obj | 871 k | the largest mesh, for BVH tests |
victory.obj | 17 k | 04_obj_statue |
nefertiti.obj, nefertiti2.obj | 100 k, 50 k | |
suzanne.obj, teapot.obj | 500, 6 k | 12_clearcoat_pokemonball |
tetrahedron, cube, octahedron, dodecahedron, icosahedron | 4 to 20 | 03_platonic_solids |
cube_uv.obj, sphere_uv.obj, plane_uv.obj | 13_texture_test1 (generated by scripts/generate_uv_models.py) | |
shelby-car.obj, sci-fi.obj, PokemonBall.obj, isc-text.obj | 291 k, 37 k, 7 k, 15 k |
The Stanford models are used under the Stanford 3D Scanning Repository terms.