• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

cmake/H07-Dec-2020-818660

deps/H07-Dec-2020-6,3244,106

examples/H03-May-2022-1,023,065944,327

images/H03-May-2022-

test/regression/possible-accuracy-problem-30/H07-Dec-2020-8267

.clang-formatH A D07-Dec-2020108 87

.gitignoreH A D07-Dec-2020585 5443

.travis.ymlH A D07-Dec-2020801 3533

LICENSEH A D07-Dec-20201.1 KiB2217

Makefile.devH A D07-Dec-2020132 64

README.mdH A D07-Dec-202010.1 KiB261207

appveyor.ymlH A D07-Dec-2020463 1814

nanort.ccH A D07-Dec-202020 21

nanort.hH A D07-Dec-202080.8 KiB2,8391,878

README.md

1# NanoRT, single header only modern ray tracing kernel.
2
3[![Travis Build Status](https://travis-ci.org/lighttransport/nanort.svg)](https://travis-ci.org/lighttransport/nanort)
4[![AppVeyor Build status](https://ci.appveyor.com/api/projects/status/k7j5d9v81qjm69j6?svg=true)](https://ci.appveyor.com/project/syoyo/nanort)
5
6![](images/render_path_traced.png)
7
8Path tracing example contributed by https://github.com/daseyb
9
10`NanoRT` is simple single header only ray tracing kernel.
11
12## Features
13
14* Portable C++
15  * Only use C++-03 features by default.
16  * C++11 feature(threads) is also available
17  * There is experimental C89 port of NanoRT in `c89` branch https://github.com/lighttransport/nanort/tree/c89
18* BVH spatial data structure for efficient ray intersection finding.
19  * Should be able to handle ~10M triangles scene efficiently with moderate memory consumption
20* Custom geometry & intersection
21  * Built-in triangle mesh gemetry & intersector is provided.
22* Cross platform
23  * MacOSX, Linux, Windows, iOS, Android, ARM, x86, SPARC, (maybe) MIPS, (will be) RISC-V, etc.
24  * For example, NanoRT works finely on Raspberry Pi 2 (arm 32bit) and Raspberrry Pi 3!(AARCH64 kernel)
25* GPU efficient data structure
26  * Built BVH tree from `NanoRT` is a linear array and does not have pointers, thus it is suited for GPU raytracing (GPU ray traversal).
27* OpenMP multithreaded BVH build.
28* Robust intersection calculation.
29  * Robust BVH Ray Traversal (using up to 4 ulp version): http://jcgt.org/published/0002/02/02/
30  * Watertight Ray/Triangle Intesection: http://jcgt.org/published/0002/01/05/
31* Double precision support
32  * Beneficial for HPC and scientific visualization.
33
34## Applications
35
36* Test renderer for your light transport algorithm development.
37* Test renderer for your shader language development.
38* Collision detection (ray casting).
39* BVH builder for GPU/Accelerator ray traversal.
40* Add 2D/3D rendering feature for non-GPU system.
41  * [ ] ImGui backend? https://github.com/syoyo/imgui/tree/nanort
42  * [ ] Nano SVG backend? https://github.com/syoyo/nanovg-nanort
43
44## Projects using NanoRT
45
46* lightmetrica https://github.com/hi2p-perim/lightmetrica-v2
47* OSPRay NanoRT module https://github.com/jeffamstutz/module_nanort/
48* Your project here!
49
50## API
51
52`nanort::Ray` represents ray. The origin `org`, the direction `dir` (not necessarily normalized), the minimum hit distance `min_t`(usually 0.0) and the maximum hit distance `max_t` (usually too far, e.g. 1.0e+30) must be filled before shooting ray.
53
54`nanort::BVHAccel` builds BVH data structure from geometry, and provides the function to find intersection point for a given ray.
55
56`nanort::BVHBuildOptions` specifies parameters for BVH build. Usually default parameters should work well.
57
58`nanort::BVHTraceOptions` specifies ray traverse/intersection options.
59
60```c
61template<typename T>
62class {
63  T org[3];        // [in] must set
64  T dir[3];        // [in] must set
65  T min_t;         // [in] must set
66  T max_t;         // [in] must set
67  unsigned int type;  // optional. ray type.
68} Ray;
69
70class BVHTraceOptions {
71  // Trace rays only in face ids range. faceIdsRange[0] < faceIdsRange[1]
72  // default: 0 to 0x3FFFFFFF(2G faces)
73  unsigned int prim_ids_range[2];
74  bool cull_back_face; // default: false
75};
76
77nanort::BVHBuildOptions<float> build_options; // BVH build option(optional)
78
79const float *vertices = ...;
80const unsigned int *faces = ...;
81
82// Need to specify stride bytes for `vertices`.
83// When vertex is stored XYZXYZXYZ... in float type, stride become 12(= sizeof(float) * 3).
84nanort::TriangleMesh<float> triangle_mesh(vertices, faces, /* stride */sizeof(float) * 3);
85nanort::TriangleSAHPred<float> triangle_pred(vertices, faces, /* stride */sizeof(float) * 3);
86
87nanort::BVHAccel<float> accel;
88ret = accel.Build(mesh.num_faces, triangle_mesh, triangle_pred, build_options);
89
90nanort::TriangleIntersector<> triangle_intersecter(vertices, faces, /* stride */sizeof(float) * 3);
91
92nanort::Ray<float> ray;
93// fill ray org and ray dir.
94...
95// fill minimum and maximum hit distance.
96ray.min_t = 0.0f;
97ray.max_t = 1.0e+30f;
98
99nanort::TriangleIntersection<float> isect;
100
101// Store nearest hit point to `isect` and returns true if the hit point found.
102BVHTraceOptions trace_options; // optional
103bool hit = accel.Traverse(ray, triangle_intersecter, &isect, trace_options);
104```
105
106Application must prepare geometric information and store it in linear array.
107
108For a builtin Triangle intersector,
109
110* `vertices` : The array of triangle vertices (e.g. xyz * numVertices)
111* `faces` : The array of triangle face indices (3 * numFaces)
112* `stride` : Byte stride of each vertex data
113
114are required attributes.
115
116
117## Usage
118
119```c
120// NanoRT defines template based class, so no NANORT_IMPLEMENTATION anymore.
121#include "nanort.h"
122Mesh mesh;
123// load mesh data...
124nanort::BVHBuildOptions<float> options; // Use default option
125nanort::TriangleMesh<float> triangle_mesh(mesh.vertices, mesh.faces, /* stride */sizeof(float) * 3);
126nanort::TriangleSAHPred<float> triangle_pred(mesh.vertices, mesh.faces, /* stride */sizeof(float) * 3);
127nanort::BVHAccel<float> accel;
128ret = accel.Build(mesh.vertices, mesh.faces, mesh.num_faces, options);
129assert(ret);
130nanort::BVHBuildStatistics stats = accel.GetStatistics();
131printf("  BVH statistics:\n");
132printf("    # of leaf   nodes: %d\n", stats.num_leaf_nodes);
133printf("    # of branch nodes: %d\n", stats.num_branch_nodes);
134printf("  Max tree depth   : %d\n", stats.max_tree_depth);
135
136std::vector<float> rgb(width * height * 3, 0.0f);
137const float tFar = 1.0e+30f;
138// Shoot rays.
139#ifdef _OPENMP
140#pragma omp parallel for
141#endif
142for (int y = 0; y < height; y++) {
143  for (int x = 0; x < width; x++) {
144    BVHTraceOptions trace_options;
145    // Simple camera. change eye pos and direction fit to .obj model.
146    nanort::Ray<float> ray;
147    ray.min_t = 0.0f;
148    ray.max_t = tFar;
149    ray.org[0] = 0.0f;
150    ray.org[1] = 5.0f;
151    ray.org[2] = 20.0f;
152    float3 dir;
153    dir[0] = (x / (float)width) - 0.5f;
154    dir[1] = (y / (float)height) - 0.5f;
155    dir[2] = -1.0f;
156    dir.normalize();
157    ray.dir[0] = dir[0];
158    ray.dir[1] = dir[1];
159    ray.dir[2] = dir[2];
160
161    nanort::TriangleIntersector<> triangle_intersecter(mesh.vertices, mesh.faces, /* stride */sizeof(float) * 3);
162    nanort::TriangleIntersection<> isect,
163    bool hit = accel.Traverse(ray, triangle_intersector, &isect, trace_options);
164    if (hit) {
165      // Write your shader here.
166      float3 normal;
167      unsigned int fid = triangle_intersector.intersect.prim_id;
168      normal[0] = mesh.facevarying_normals[3*3*fid+0]; // @todo { interpolate normal }
169      normal[1] = mesh.facevarying_normals[3*3*fid+1];
170      normal[2] = mesh.facevarying_normals[3*3*fid+2];
171      // Flip Y
172      rgb[3 * ((height - y - 1) * width + x) + 0] = fabsf(normal[0]);
173      rgb[3 * ((height - y - 1) * width + x) + 1] = fabsf(normal[1]);
174      rgb[3 * ((height - y - 1) * width + x) + 2] = fabsf(normal[2]);
175    }
176  }
177}
178```
179
180## Defines
181
182```
183NANORT_USE_CPP11_FEATURE : Enable C++11 feature
184NANORT_ENABLE_PARALLEL_BUILD : Enable parallel BVH build(OpenMP version is not yet fully tested).
185```
186
187## More example
188
189See `examples` directory for example renderer using `NanoRT`.
190
191* [x] [examples/path_tracer](examples/path_tracer) Path tracer example by https://github.com/daseyb
192  * [x] Better ortho basis generation: Building an Orthonormal Basis, Revisited http://jcgt.org/published/0006/01/01/
193* [x] [examples/bidir_path_tracer](examples/bidir_path_tracer) Bi-directional path tracer example by https://github.com/tatsy
194* [x] [examples/gui](examples/gui) Simple renderer with GUI(using ImGui)
195* [x] [examples/vrcamera](examples/vrcamera) Stereo VR Camera
196* [x] [examples/objrender](examples/objrender) Render wavefront .obj model using NanoRT.
197* [x] [examples/par_msquare](examples/par_msquare) Render heightfield by converting it to meshes using par_msquare(marching squares)
198* [x] [examples/las](examples/las) Visualize LiDAR(LAS) point cloud as sphere geometry.
199* [x] [examples/double_precision](examples/double_precision) Double precision triangle geometry and BVH.
200* [x] [examples/embree-api](examples/embree-api) NanoRT implementation of Embree API.
201* [x] [examples/ptex](examples/ptex) Ptex texturing.
202
203### Custom geometry
204
205Here is an example of custom geometry.
206
207* [x] Spheres(particles) `examples/particle_primitive/`
208* Cubic Bezier Curves
209  * [x] Approximate as lines `examples/curves_primitive/`
210  * [ ] Recursive Ray-Bezier intersection.
211* [x] Cylinders `examples/cylinder_primitive/`
212
213And plesae see API at wiki: https://github.com/lighttransport/nanort/wiki/API
214
215## License
216
217`nanort.h` is licensed under MIT license.
218
219`NanoRT` uses `stack_container.h` which is licensed under:
220
221    // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
222    // Use of this source code is governed by a BSD-style license that can be
223    // found in the LICENSE file.
224
225`NanoRT` examples use some external third party libraries. Licenses for such third party libraries obey their own license.
226
227Lucy statue model is from The Stanford 3D Scanning Repository http://graphics.stanford.edu/data/3Dscanrep/
228
229## TODO
230
231PR are always welcome!
232
233* [ ] Optimize ray tracing kernel
234  * [ ] Efficient Ray Tracing Kernels for Modern CPU Architectures http://jcgt.org/published/0004/04/05/
235  * [ ] ARM NEON SIMD
236  * [ ] Intel SSE SIMD
237* [ ] Better cmake build.
238* [ ] Implement more Embree compatible API.
239* [ ] Scene graph support.
240  * [x] NanoSG, Minimal scene graph library. [examples/nanosg](examples/nanosg)
241  * [ ] Instancing support.
242* [ ] Fix multi-hit ray traversal.
243* [ ] Optimize Multi-hit ray traversal for BVH.
244  * [ ] http://jcgt.org/published/0004/04/04/
245* [ ] Ray traversal option.
246  * [x] FaceID range.
247  * [x] Double sided on/off.
248  * [ ] Ray offset.
249  * [x] Avoid self-intersection(BVHTraceOptions.skip_prim_id).
250  * [x] Custom intersection filter through C++ template.
251* [ ] Fast BVH build
252  * [ ] Bonsai: Rapid Bounding Volume Hierarchy Generation using Mini Trees http://jcgt.org/published/0004/03/02/
253* [ ] Efficient BVH build
254  * [ ] Spatial split BVH
255* [ ] Motion blur
256  * [ ] STBVH: A Spatial-Temporal BVH for Efficient Multi-Segment Motion Blur http://www.highperformancegraphics.org/2017/program/
257* [ ] Fast, Accurate ray curve intersection
258  * [ ] Phantom Ray-Hair Intersector
259* [x] Example bi-directional path tracing renderer by @tatsy.
260
261