Iray Programmer's Manual

Progressive rendering of a scene

This topic introduces:

  1. Progressive rendering, which explains what progressive rendering is and when to use it
  2. example_progressive_rendering.cpp, which demonstrates how to set up progressive rendering for a render context

Progressive rendering

Progressive rendering is intended to provide users with fast feedback. The initial render call generates a somewhat low quality frame. Subsequent render calls refine the image incrementally.

Each frame generated by a progressive rendering operation is exported to a file. Displaying all files in sequence shows the incremental refinement of the image. On Linux, you can view this progression using the animate command from ImageMagick software:

animate -delay 10 `\ls -1 example_progressive_rendering_*.png`

There are a number of termination criteria used to determine when a progressive rendering operation is considered finished. The progressive rendering operation is restarted, for example, when the camera position changes or changes are made to the scene that would be visible in the rendered image. On the other hand, progressive rendering operation is ended when the image resolution of the last rendered frame satisfies the image resolution criterion.

See Progressive rendering in Iray Photoreal and Progressive rendering in Iray Interactive for detailed information about progressive rendering options supported by the respective rendering modes.

Example for progressive rendering

The example for progressive rendering is a modification of the example program used in A first image, Accessing the database, and Importing a scene file.

Note the following:

  • The interactive scheduling mode (default mode) is used.
  • The rendering logic has one modification: A loop is used to repeatedly call the render() method.
  • A custom canvas class is used, whose implementation you can see in Own canvas class.

example_progressive_rendering.cpp

001 /******************************************************************************
002  * © 1986, 2014 NVIDIA Corporation. All rights reserved.
003  *****************************************************************************/
004 
005 // examples/example_progressive_rendering.cpp
006 //
007 // Renders a scene in progressive rendering mode.
008 //
009 // The example expects the following command line arguments:
010 //
011 //   example_progressive_rendering <scene_file> <mdl_path>
012 //
013 // scene_file       some scene file
014 // mdl_path         path to the MDL modules, e.g., iray-<version>/mdl
015 //
016 // The rendered images are written to files named "example_progressive_rendering_00.png", etc.
017 
018 #include <iomanip>
019 #include <iostream>
020 #include <sstream>
021 
022 #include <mi/neuraylib.h>
023 
024 // Include code shared by all examples.
025 #include "example_shared.h"
026 // Include an implementation of ITile, ICanvas, and IRender_target.
027 #include "example_render_target_advanced.h"
028 
029 void configuration( mi::base::Handle<mi::neuraylib::INeuray> neuray, const char* mdl_path)
030 {
031     // Configure the neuray library. Here we set the search path for .mdl files.
032     mi::base::Handle<mi::neuraylib::IRendering_configuration> rendering_configuration(
033         neuray->get_api_component<mi::neuraylib::IRendering_configuration>());
034     check_success( rendering_configuration.is_valid_interface());
035     check_success( rendering_configuration->add_mdl_path( mdl_path) == 0);
036 
037     // Load the FreeImage, Iray Photoreal, and .mi importer plugins.
038     mi::base::Handle<mi::neuraylib::IPlugin_configuration> plugin_configuration(
039         neuray->get_api_component<mi::neuraylib::IPlugin_configuration>());
040 #ifndef MI_PLATFORM_WINDOWS
041     check_success( plugin_configuration->load_plugin_library( "freeimage.so") == 0);
042     check_success( plugin_configuration->load_plugin_library( "libiray.so") == 0);
043     check_success( plugin_configuration->load_plugin_library( "mi_importer.so") == 0);
044 #else
045     check_success( plugin_configuration->load_plugin_library( "freeimage.dll") == 0);
046     check_success( plugin_configuration->load_plugin_library( "libiray.dll") == 0);
047     check_success( plugin_configuration->load_plugin_library( "mi_importer.dll") == 0);
048 #endif
049 }
050 
051 void rendering( mi::base::Handle<mi::neuraylib::INeuray> neuray,
052                 const char* scene_file)
053 {
054     // Get the database, the global scope, which is the root for all transactions,
055     // and create a transaction for importing the scene file and storing the scene.
056     mi::base::Handle<mi::neuraylib::IDatabase> database(
057         neuray->get_api_component<mi::neuraylib::IDatabase>());
058     check_success( database.is_valid_interface());
059     mi::base::Handle<mi::neuraylib::IScope> scope(
060         database->get_global_scope());
061     mi::base::Handle<mi::neuraylib::ITransaction> transaction(
062         scope->create_transaction());
063     check_success( transaction.is_valid_interface());
064 
065     // Import the scene file
066     mi::base::Handle<mi::neuraylib::IImport_api> import_api(
067         neuray->get_api_component<mi::neuraylib::IImport_api>());
068     check_success( import_api.is_valid_interface());
069     mi::base::Handle<const mi::IString> uri( import_api->convert_filename_to_uri( scene_file));
070     mi::base::Handle<const mi::IImport_result> import_result(
071         import_api->import_elements( transaction.get(), uri->get_c_str()));
072     check_success( import_result->get_error_number() == 0);
073 
074     // Create the scene object
075     mi::base::Handle<mi::neuraylib::IScene> scene(
076         transaction->create<mi::neuraylib::IScene>( "Scene"));
077     scene->set_rootgroup(       import_result->get_rootgroup());
078     scene->set_options(         import_result->get_options());
079     scene->set_camera_instance( import_result->get_camera_inst());
080     transaction->store( scene.get(), "the_scene");
081 
082     // Create the render context using the Iray Photoreal render mode
083     scene = transaction->edit<mi::neuraylib::IScene>( "the_scene");
084     mi::base::Handle<mi::neuraylib::IRender_context> render_context(
085         scene->create_render_context( transaction.get(), "iray"));
086     check_success( render_context.is_valid_interface());
087     scene = 0;
088 
089     // Render progressively at most 10 frames
090     for( mi::Size i = 0; i < 10; ++i) {
091 
092         // Create the render target and render the i-th frame of the scene
093         mi::base::Handle<mi::neuraylib::IRender_target> render_target(
094             new Render_target( 512, 384));
095         mi::Sint32 result = render_context->render( transaction.get(), render_target.get(), 0);
096         check_success( result >= 0);
097 
098         // Write the image to disk
099         mi::base::Handle<mi::neuraylib::IExport_api> export_api(
100             neuray->get_api_component<mi::neuraylib::IExport_api>());
101         check_success( export_api.is_valid_interface());
102         mi::base::Handle<mi::neuraylib::ICanvas> canvas( render_target->get_canvas( 0));
103         std::ostringstream str;
104         str << "example_progressive_rendering_" << std::setw( 2) << std::setfill( '0') << i
105             << ".png";
106         export_api->export_canvas( str.str().c_str(), canvas.get());
107 
108         // Leave render loop if the termination criteria have been met
109         if( result > 0)
110             break;
111     }
112 
113     // All transactions need to get committed or aborted.
114     transaction->commit();
115 }
116 
117 int main( int argc, char* argv[])
118 {
119     // Collect command line parameters
120     if( argc != 3) {
121         std::cerr << "Usage: example_progressive_rendering <scene_file> <mdl_path>" << std::endl;
122         keep_console_open();
123         return EXIT_FAILURE;
124     }
125     const char* scene_file  = argv[1];
126     const char* mdl_path = argv[2];
127 
128     // Access the neuray library
129     mi::base::Handle<mi::neuraylib::INeuray> neuray( load_and_get_ineuray());
130     check_success( neuray.is_valid_interface());
131 
132     // Configure the neuray library
133     configuration( neuray, mdl_path);
134 
135     // Start the neuray library
136     check_success( neuray->start() == 0);
137 
138     // Do the actual rendering
139     rendering( neuray, scene_file);
140 
141     // Shut down the neuray library
142     check_success( neuray->shutdown() == 0);
143     neuray = 0;
144 
145     // Unload the neuray library
146     check_success( unload());
147 
148     keep_console_open();
149     return EXIT_SUCCESS;
150 }