The system and scene description text files are just something I came up with to allow simple and repeatable settings for an application. In the end, it’s all just demo code.
The system description is simply meant to avoid adding all these individual control parameters to the executable command line options which would have been really messy to use.
The scene description is also just a simple way to build more complex scenes from either the runtime generated shapes at arbitrary geometric complexity (for the plane, sphere and torus), as well as loading triangle meshes from supported standard file formats using ASSIMP. It’s just meant to make the examples more useful and interesting.
For example I can create scenes which will exceed any graphics memory amount and thereby check if things work when sharing the data via CUDA peer-to-peer across two GPUs using NVLINK. It’s rather difficult to find real world scenes exceeding 48 GB in a usable model.
Both descriptions together allowed the verification of the correctness and performance of the renderer implementation, as well as showing some typical renderer features like instancing, texturing, etc.
If you have a way to load your models differently, nobody keeps you from using that method inside your own application. In the end, it’s just a matter of how you get your triangles into OptiX and the code doing that can be found inside my examples.
In my case, the scene description also loads an OBJ model like that. It’s effectively model assimp "cow.obj"
inside the scene description which tells the application to load the given OBJ file with the std::shared_ptr<sg::Group> Application::createASSIMP(std::string const& filename)
function which returns a subgraph of potentially multiple triangle meshes inside the loaded file which gets added to scene’s host side scene graph root node.
The device side render graph is flattened from that to a two-level IAS->GAS layout for better performance.
The material assignments looks for material reference names matching the material names inside assimp. For OBJ files without accompanying MTL file (like for the cow.obj), ASSIMP returns a material with the name DefaultMaterial
which can be defined inside the scene description. All materials for which no reference name is found will retry assigning the material with the name default
. If that is also not found, the scene loader fails.
Note that the OBJ and MTL file formats are more involved than you might think. Many OBJ files are partitioned into groups (and smoothing groups which affect the normal vector generation) with different materials. There are multiple ways to transport that over to an OptiX render graph.
I’m using different geometry acceleration structures (GAS) per triangle mesh (group inside the OBJ) which can be instanced. It would also be possible to implement each OBJ as a single GAS with multiple shader binding table entries and material assignments per face in OptiX. I kept it simple inside these examples.