Creating a Simple Scene Programmatically

In this article I am going to show you how to create a simple 3D scene, completely from scratch using RealityServer. You will learn about the anatomy of a RealityServer scene and the different components that go into making it up, including options, groups, instances, cameras, geometry and environment lighting. While the scene will be very simple there will be many key principles of RealityServer and NVIDIA Iray demonstrated which you can expand on to build more complex scenes.

Before You Begin

If you haven’t already done so, I highly recommend reading the article on Exploring the RealityServer JSON-RPC API. This article  will be assuming you are familiar with the information there, particularly how RealityServer commands work. The scene you will build here will be created entirely by giving RealityServer commands. To follow along you will need an environment from which to send these commands to RealityServer as well as a running instance of RealityServer itself. I recommend Postman for sending commands, however any tool that can send HTTP POST requests will do.

This article also assumes you are running RealityServer 4.4 build 1527.40 or later and uses some features introduced in that version. Even so the information can be easily adapted to earlier versions if needed.

What We Will Be Making

To the right you can see the image we will be making in this article. It includes a simple piece of geometry illuminated by daylight and the configuration of several Iray features such as the implicit ground plane and tone mapping.

We will use two HTTP requests to make this image, one with an array of commands to generate the scene and another with an array of commands to perform the rendering and clean up the database.

Finished Scene We Will Render

Finished Scene We Will Render

Terminology

In this article I will use a few terms which have important meanings. Here are two terms in particular that are used often which you need to understand as they might have different meanings in common language but mean something very specific in RealityServer.

Elements

An element in RealityServer is something that is created in the RealityServer database, usually to be added to a scene but not always. Elements are things like options, instances, groups, lights and many other items. Elements usually serve a specific purpose in Iray, refer to the RealityServer documentation for more details.

Attributes

Attributes represent information we can attach to elements. These have a type and a value and elements can have many attributes attached to them. These attributes usually represent options which tell the element to behave a certain way, For example, an instance element can have a visible attribute which controls whether you can see it or not.

Creating a Scope

We will cover scopes in more detail in another article, however when doing anything in RealityServer, usually you will utilise a unique scope in order to prevent other users of the server seeing or conflicting with your data. Let’s go ahead and create a scope and then instruct RealityServer to use that scope immediately for the duration of our request.

[
	{"jsonrpc": "2.0", "method": "create_scope", "params": {
		"scope_name" : "exScope"
	}, "id": 1},

	{"jsonrpc": "2.0", "method": "use_scope", "params": {
		"scope_name" : "exScope"
	}, "id": 2}
]

Normally you would use a unique identifier such as a UUID when making a scope to ensure it doesn’t clash with others. Since we are going to be testing on our own server we will just use a simple name. Notice the above request is a batch of two commands. Throughout this article the commands we are adding will be added to this single batch array of commands. Commands after the use_scope call above will be performed in the named scope.

Creating the Scene

In RealityServer, a scene holds references to everything needed to create a 3D rendering. There are three essential elements a scene must have, a root group, a camera instance and options. First we will create an empty scene element in the RealityServer database as follows.

[
	...
	
	{"jsonrpc": "2.0", "method": "create_scene", "params": {
		"scene_name" : "exScene"
	}, "id": 3}
]

You will need to use the scene_name often in future commands. Since the scene is created inside the scope you don’t need to ensure it is unique, as long as the scope is.

Creating the Options

The options element is basically a container for attributes that control various Iray rendering settings. These settings do not relate to specific elements but rather apply to the entire scene. Later we will attach attributes to the options to control the rendering. For now we just need to create the options and tell the scene to use them.

[
	...

	{"jsonrpc": "2.0", "method": "create_element", "params": {
		"element_name" : "exOptions",
		"element_type" : "Options"
	}, "id": 4},

	{"jsonrpc": "2.0", "method": "scene_set_options", "params": {
		"scene_name" : "exScene",
		"options" : "exOptions"
	}, "id": 5}

Here we call the create_element command for the first time. With the exception of scenes (which use the special create_scene command), the create_element command is used to add new elements to the database. For a list of available element types refer to the documentation for the command.

Creating the Root Group

The root group is a container which holds references to all of the instances, geometry, lights and other groups which will be used to render the scene. Every scene needs a root group so let’s create an empty one to begin with.

[
	...

	{"jsonrpc": "2.0", "method": "create_element", "params": {
		"element_name" : "exRootGroup",
		"element_type" : "Group"
	}, "id": 6},

	{"jsonrpc": "2.0", "method": "scene_set_rootgroup", "params": {
		"scene_name" : "exScene",
		"group" : "exRootGroup"
	}, "id": 7}
]

This is the same process used for the options. For geometry to actually render it must be attached to the root group. We will cover this a bit later on.

Creating the Camera

Now for something with a bit more complexity. We need to create a camera which will define the viewpoint for our rendering. The scene needs a camera instance rather than the camera itself so we will need to make that as well.

[
	...

	{"jsonrpc": "2.0", "method": "create_element", "params": {
		"element_name" : "exCamera",
		"element_type" : "Camera"
	}, "id": 8},

	{"jsonrpc": "2.0", "method": "camera_set_resolution", "params": {
		"camera_name" : "exCamera",
		"resolution" : { "x" : 640, "y" : 480 }
	}, "id": 9},

	{"jsonrpc": "2.0", "method": "create_element", "params": {
		"element_name" : "exCameraInstance",
		"element_type" : "Instance"
	}, "id": 10},

	{"jsonrpc": "2.0", "method": "instance_set_world_to_obj", "params": {
		"instance_name" : "exCameraInstance",
		"transform" : {
			"xx": -1.0, "xy": 0.0,                 "xz": 0.0,                 "xw": 0.0,
			"yx": 0.0,  "yy": 1.0,                 "yz": 0.20395425411200102, "yw": 0.0,
			"zx": 0.0,  "zy": 0.20395425411200102, "zz": -1.0,                "zw": 0.0,
			"wx": 8.0,  "wy": -5.0,                "wz": -25.0,               "ww": 1.0
		}
	}, "id": 11},

	{"jsonrpc": "2.0", "method": "instance_attach", "params": {
		"instance_name" : "exCameraInstance",
		"item_name" : "exCamera"
	}, "id": 12},

	{"jsonrpc": "2.0", "method": "group_attach", "params": {
		"group_name" : "exRootGroup",
		"item_name" : "exCameraInstance"
	}, "id": 13},

	{"jsonrpc": "2.0", "method": "scene_set_camera_instance", "params": {
		"scene_name" : "exScene",
		"camera_instance" : "exCameraInstance"
	}, "id": 14}
]

First we create the actual camera. Immediately afterwards we call one of the specialised camera commands camera_set_resolution to set the size of the image we want to render. You can find other camera commands in the camera group of the command documentation. We use the defaults for focal length and aperture for now but there are commands to set these available.

Once the camera is made we create a new instance element. Instances are special elements which reference something in the scene and allow you to position it by applying a transformation matrix. We do that here with the instance_set_world_to_obj command which sets the 4×4 matrix representing the world to object space transform of the instance. In this case we are using it to move the camera along the Z-axis, raise it up the Y-axis and tilt it downwards.

For the instance to actually reference the camera element we need to attach it using the instance_attach command. We then place the instance in our root group with the group_attach command. Finally with this all setup we can tell the scene which camera to use by calling the scene_set_camera_instance command.

Turning on the Light

If we were to render the scene now we would just get a black image because there is no environment or light source. For this example we are going to setup a daylight environment which will be used both as the background and as the source of illumination in the scene. We use the physically based sun_and_sky function provided by MDL for this. This function is provided in the MDL base module. The base module is a special case, even though we are going to call import_scene_elements to load it from a file that file actually doesn’t exist anywhere. It is a special internal file, later when we load a material we will load a read MDL file from disk. Here are the commands for making the daylighting and turning it on.

[
	...

	{"jsonrpc": "2.0", "method": "import_scene_elements", "params": {
		"filename": "${shader}/base.mdl"
	}, "id": 15},

	{"jsonrpc": "2.0", "method": "create_function_call_from_definition", "params": {
		"arguments" : {
			"multiplier" : 0.10132,
			"rgb_unit_conversion" : { 
				"r" : 1.0,
				"g" : 1.0,
				"b" : 1.0
			},
			"sun_disk_intensity" : 1.0,
			"physically_scaled_sun" : true,
			"sun_direction" : { "x" : 0.0, "y" : 0.5, "z" : -1.0 }
		},
		"function_definition_name" : "mdl::base::sun_and_sky(bool,float,color,float,float,float,float,float,color,color,float3,float,float,float,bool,int,bool)",
		"function_name" : "exSunSky"
	}, "id": 16},

	{"jsonrpc": "2.0", "method": "element_set_attribute", "params": {
		"element_name" : "exOptions",
		"attribute_type" : "Ref",
		"attribute_name" : "environment_function",
		"attribute_value" : "exSunSky",
		"create" : true
	}, "id": 17}
]

So there are three steps, first import the MDL module containing the function, then create a function call from the function definition and finally set an attribute on our options element to tell Iray which MDL function to use to generate the environment. You will note a few things about the create_function_call_from_definition command used above. Firstly, you can see that you can provide initial values for the various attributes of the function at the time of creation. If there are parameters which do not have defaults you will need to provide values for them here otherwise you will get an error.

Secondly, note the odd value for the function_definition_name parameter. This is the function signature. Since MDL supports overloading of functions (similar to various Object Oriented programming languages), the function needs to be referenced by its full signature. You can find the signatures of the loaded functions by calling import_scene_elements with the “import_options” : { “list_elements” : true } parameter. You can also call the get_function_definition_overloads command if you know the function name. This will give you an array of strings representing the function signatures.

When setting the environment_function attribute on the options, we use the Ref attribute type since while we are using a name this particular attribute expects a reference to a function.

Setting up Tonemapping

Now if we rendered the scene we wouldn’t get a black image, we would get a completely white image! Well that’s progress but really we want to see the sky we just created. For this we need to turn on the tonemapping functionality of Iray which controls how the physically correct values generated by Iray are mapped to the limited range of RGB colour values used to display images on computer screens.

[
	...

	{"jsonrpc": "2.0", "method": "element_set_attributes", "params": {
		"create" : true,
		"element_name" : "exCamera",
		"attributes" : {
			"tm_tonemapper" : {
				"type" : "String",
				"value" : "mia_exposure_photographic"
			},
			"mip_cm2_factor" : {
				"type" : "Float32",
				"value" : 1.0
			},
			"mip_film_iso" : {
				"type" : "Float32",
				"value" : 100.0
			},
			"mip_camera_shutter" : {
				"type" : "Float32",
				"value" : 250.0
			},
			"mip_f_number" : {
				"type" : "Float32",
				"value" : 8.0
			},
			"mip_gamma" : {
				"type" : "Float32",
				"value" : 2.2
			}
		}
	}, "id": 18}
]

We are using a new command here, element_set_attributes, which is basically the same as element_set_attribute used earlier but allows us to set multiple attributes on an element in a single call. Since we are creating the attributes we must provide the type as well as the value for each. The attributes created above are attached to the camera (not the camera instance). You can find more details on how tone mapping works in the RealityServer documentation.

Geometry

The scene would now render with a sky and horizon but no objects which is a bit boring so we’ll add some geometry to the scene. We will use a command that was introduced in RealityServer 4.4 for this, generate_extrusion.

[
	...

	{"jsonrpc": "2.0", "method": "generate_extrusion", "params": {
		"name" : "exObject",
		"profile" : [
			{ "x" : 0.0, "y" : 0.0 },
			{ "x" : 4.0, "y" : 0.0 },
			{ "x" : 4.0, "y" : 6.0 },
			{ "x" : 8.0, "y" : 1.0 },
			{ "x" : 12.0, "y" : 6.0 },
			{ "x" : 12.0, "y" : 0.0 },
			{ "x" : 16.0, "y" : 0.0 },
			{ "x" : 16.0, "y" : 12.0 },
			{ "x" : 12.0, "y" : 12.0 },
			{ "x" : 8.0, "y" : 7.0 },
			{ "x" : 4.0, "y" : 12.0 },
			{ "x" : 0.0, "y" : 12.0 }
		],
		"length" : 12.0
	}, "id": 19},

	{"jsonrpc": "2.0", "method": "element_set_attribute", "params": {
		"element_name" : "exObject",
		"attribute_type" : "Boolean",
		"attribute_name" : "visible",
		"attribute_value" : true,
		"create" : true
	}, "id": 20},

	{"jsonrpc": "2.0", "method": "create_element", "params": {
		"element_name" : "exObjectInstance",
		"element_type" : "Instance"
	}, "id": 21},

	{"jsonrpc": "2.0", "method": "instance_attach", "params": {
		"instance_name" : "exObjectInstance",
		"item_name" : "exObject"
	}, "id": 22},

	{"jsonrpc": "2.0", "method": "group_attach", "params": {
		"group_name" : "exRootGroup",
		"item_name" : "exObjectInstance"
	}, "id": 23}
]

We give the generate_extrusion command a list of points defining an M shape from which it can build a nice mesh for us to render. The geometry created by this command has no attributes assigned to it and by default objects are not visible so we need to call element_set_attribute to set the visible attribute to true so we can see it.

In order to actually place the object in the scene we need to first create an instance to reference it, then as we did with the camera we attach the object to the instance and add the instance to the root group. At this point we could render the scene and we would get a big M with a funny pink material.

Defining a Material

The M renders pink because we haven’t defined a material for it yet. RealityServer ships with some materials you can use and setup so we’ll import one of those and change its parameters to suit our needs.

[
	...

	{"jsonrpc": "2.0", "method": "import_scene_elements", "params": {
		"filename": "${shader}/material_examples/architectural.mdl"
	}, "id": 24},

	{"jsonrpc": "2.0", "method": "create_material_instance_from_definition", "params": {
		"arguments": {
			"diffuse" : { "r" : 0.8, "g" : 0.1, "b" : 0.25 },
			"reflectivity" : 0.5,
			"refl_gloss" : 0.3
		},
		"material_definition_name": "mdl::material_examples::architectural::architectural",
		"material_name": "exMaterial"
	}, "id": 25},

	{"jsonrpc": "2.0", "method": "instance_set_material", "params": {
		"instance_name" : "exObjectInstance",
		"material_name" : "exMaterial"
	}, "id": 26}
]

Before making an instance of the MDL material we need to load its definition from disk. We use import_scene_elements for this purpose. The ${shader} path causes RealityServer to look in all MDL search paths for the file specified. With the MDL file loaded we can now call create_material_instance_from_definition to create a material within our scene based on the definition contained in the MDL file. In a similar way to when we made the function for the environment, we can set the initial values of any arguments we want. Here we make the material bit red and setup a glossy reflection.

Finally we call the instance_set_material command (this was introduced in RealityServer 4.4 build 1527.40) to actually assign the material to the instance of our M object. If we render the scene now we will get a nice red M lit by daylight, however it will look like it is floating in space, so let’s fix that next.

Turning on the Ground

Iray has a nice feature called the implicit ground plane. This is a special option you can enable which creates an automatic ground surface in the scene which can catch shadows and reflections from objects in the scene. The beauty of this feature is you just turn it on and everything is automatic, there is no need to model very large planes or surface. We turn it on simply by setting attributes on our options element.

[
	...

	{"jsonrpc": "2.0", "method": "element_set_attributes", "params": {
		"element_name" : "exOptions",
		"create" : true,
		"attributes" : {
			"environment_dome_ground" : {
				"type" : "Boolean",
				"value" : true
			},
			"environment_dome_ground_reflectivity" : {
				"type" : "Color",
				"value" : { "r" : 0.4, "g" : 0.4, "b" : 0.4 }
			},
			"environment_dome_ground_glossiness" : {
				"type" : "Float32",
				"value" : 1000.0
			},
			"environment_dome_ground_shadow_intensity" : {
				"type" : "Float32",
				"value" : 0.8
			}
		}
	}, "id": 27}
]

In this case we turn on the ground, then give it a reflectivity, glossiness and slightly reduce the shadow intensity. We use the element_set_attributes command again to set multiple attributes in one go. At this stage we now have a complete scene which we can render to produce the image shown at the start of this article.

Putting it All Together

So we broke down all of the commands needed to make the scene above, now let’s put it all together in a single call we can make to RealityServer to generate the scene. There are 27 commands in all and here they are in one go. You can cut and past this into a tool like Postman and send it a post request to RealityServer and it will create the scene for you and it will reside in the scope. After reviewing the full scene creation request below we will finally make one more request to do the actual rendering. Here is the complete scene generation request. Click the box below to show the full source.

Complete Scene Creation Request (Click to Expand)

[
  {"jsonrpc": "2.0", "method": "create_scope", "params": {
    "scope_name" : "exScope"
  }, "id": 1},
  {"jsonrpc": "2.0", "method": "use_scope", "params": {
    "scope_name" : "exScope"
  }, "id": 2},
  {"jsonrpc": "2.0", "method": "create_scene", "params": {
    "scene_name" : "exScene"
  }, "id": 3},
  {"jsonrpc": "2.0", "method": "create_element", "params": {
    "element_name" : "exOptions",
    "element_type" : "Options"
  }, "id": 4},
  {"jsonrpc": "2.0", "method": "scene_set_options", "params": {
    "scene_name" : "exScene",
    "options" : "exOptions"
  }, "id": 5},
  {"jsonrpc": "2.0", "method": "create_element", "params": {
    "element_name" : "exRootGroup",
    "element_type" : "Group"
  }, "id": 6},
  {"jsonrpc": "2.0", "method": "scene_set_rootgroup", "params": {
    "scene_name" : "exScene",
    "group" : "exRootGroup"
  }, "id": 7},
  {"jsonrpc": "2.0", "method": "create_element", "params": {
    "element_name" : "exCamera",
    "element_type" : "Camera"
  }, "id": 8},
  {"jsonrpc": "2.0", "method": "camera_set_resolution", "params": {
    "camera_name" : "exCamera",
    "resolution" : { "x" : 640, "y" : 480 }
  }, "id": 9},
  {"jsonrpc": "2.0", "method": "create_element", "params": {
    "element_name" : "exCameraInstance",
    "element_type" : "Instance"
  }, "id": 10},
  {"jsonrpc": "2.0", "method": "instance_set_world_to_obj", "params": {
    "instance_name" : "exCameraInstance",
    "transform" : {
      "xx": -1.0, "xy": 0.0,                 "xz": 0.0,                 "xw": 0.0,
      "yx": 0.0,  "yy": 1.0,                 "yz": 0.20395425411200102, "yw": 0.0,
      "zx": 0.0,  "zy": 0.20395425411200102, "zz": -1.0,                "zw": 0.0,
      "wx": 8.0,  "wy": -5.0,                "wz": -25.0,               "ww": 1.0
    }
  }, "id": 11},
  {"jsonrpc": "2.0", "method": "instance_attach", "params": {
    "instance_name" : "exCameraInstance",
    "item_name" : "exCamera"
  }, "id": 12},
  {"jsonrpc": "2.0", "method": "group_attach", "params": {
    "group_name" : "exRootGroup",
    "item_name" : "exCameraInstance"
  }, "id": 13},
  {"jsonrpc": "2.0", "method": "scene_set_camera_instance", "params": {
    "scene_name" : "exScene",
    "camera_instance" : "exCameraInstance"
  }, "id": 14},
  {"jsonrpc": "2.0", "method": "import_scene_elements", "params": {
    "filename": "${shader}/base.mdl"
  }, "id": 15},
  {"jsonrpc": "2.0", "method": "create_function_call_from_definition", "params": {
    "arguments" : {
      "multiplier" : 0.10132,
      "rgb_unit_conversion" : { 
        "r" : 1.0,
        "g" : 1.0,
        "b" : 1.0
      },
      "sun_disk_intensity" : 1.0,
      "physically_scaled_sun" : true,
      "sun_direction" : { "x" : 0.0, "y" : 0.5, "z" : -1.0 }
    },
    "function_definition_name" : "mdl::base::sun_and_sky(bool,float,color,float,float,float,float,float,color,color,float3,float,float,float,bool,int,bool)",
    "function_name" : "exSunSky"
  }, "id": 16},
  {"jsonrpc": "2.0", "method": "element_set_attribute", "params": {
    "element_name" : "exOptions",
    "attribute_type" : "Ref",
    "attribute_name" : "environment_function",
    "attribute_value" : "exSunSky",
    "create" : true
  }, "id": 17},
  {"jsonrpc": "2.0", "method": "element_set_attributes", "params": {
    "create" : true,
    "element_name" : "exCamera",
    "attributes" : {
      "tm_tonemapper" : {
        "type" : "String",
        "value" : "mia_exposure_photographic"
      },
      "mip_cm2_factor" : {
        "type" : "Float32",
        "value" : 1.0
      },
      "mip_film_iso" : {
        "type" : "Float32",
        "value" : 100.0
      },
      "mip_camera_shutter" : {
        "type" : "Float32",
        "value" : 250.0
      },
      "mip_f_number" : {
        "type" : "Float32",
        "value" : 8.0
      },
      "mip_gamma" : {
        "type" : "Float32",
        "value" : 2.2
      }
    }
  }, "id": 18},
  {"jsonrpc": "2.0", "method": "generate_extrusion", "params": {
    "name" : "exObject",
    "profile" : [
      { "x" : 0.0, "y" : 0.0 },
      { "x" : 4.0, "y" : 0.0 },
      { "x" : 4.0, "y" : 6.0 },
      { "x" : 8.0, "y" : 1.0 },
      { "x" : 12.0, "y" : 6.0 },
      { "x" : 12.0, "y" : 0.0 },
      { "x" : 16.0, "y" : 0.0 },
      { "x" : 16.0, "y" : 12.0 },
      { "x" : 12.0, "y" : 12.0 },
      { "x" : 8.0, "y" : 7.0 },
      { "x" : 4.0, "y" : 12.0 },
      { "x" : 0.0, "y" : 12.0 }
    ],
    "length" : 12.0
  }, "id": 19},
  {"jsonrpc": "2.0", "method": "element_set_attribute", "params": {
    "element_name" : "exObject",
    "attribute_type" : "Boolean",
    "attribute_name" : "visible",
    "attribute_value" : true,
    "create" : true
  }, "id": 20},
  {"jsonrpc": "2.0", "method": "create_element", "params": {
    "element_name" : "exObjectInstance",
    "element_type" : "Instance"
  }, "id": 21},
  {"jsonrpc": "2.0", "method": "instance_attach", "params": {
    "instance_name" : "exObjectInstance",
    "item_name" : "exObject"
  }, "id": 22},
  {"jsonrpc": "2.0", "method": "group_attach", "params": {
    "group_name" : "exRootGroup",
    "item_name" : "exObjectInstance"
  }, "id": 23},
  {"jsonrpc": "2.0", "method": "import_scene_elements", "params": {
    "filename": "${shader}/material_examples/architectural.mdl"
  }, "id": 24},
  {"jsonrpc": "2.0", "method": "create_material_instance_from_definition", "params": {
    "arguments": {
      "diffuse" : { "r" : 0.8, "g" : 0.1, "b" : 0.25 },
      "reflectivity" : 0.5,
      "refl_gloss" : 0.3
    },
    "material_definition_name": "mdl::material_examples::architectural::architectural",
    "material_name": "exMaterial"
  }, "id": 25},

  {"jsonrpc": "2.0", "method": "instance_set_material", "params": {
    "instance_name" : "exObjectInstance",
    "material_name" : "exMaterial"
  }, "id": 26},
  {"jsonrpc": "2.0", "method": "element_set_attributes", "params": {
    "element_name" : "exOptions",
    "create" : true,
    "attributes" : {
      "environment_dome_ground" : {
        "type" : "Boolean",
        "value" : true
      },
      "environment_dome_ground_reflectivity" : {
        "type" : "Color",
        "value" : { "r" : 0.4, "g" : 0.4, "b" : 0.4 }
      },
      "environment_dome_ground_glossiness" : {
        "type" : "Float32",
        "value" : 1000.0
      },
      "environment_dome_ground_shadow_intensity" : {
        "type" : "Float32",
        "value" : 0.8
      }
    }
  }, "id": 27}
]

Rendering an Image

Creating a scene is great but of course we actually want to render an image of our creation. We will do that in a separate request where we setup some rendering settings first then perform a batch render. This request is special because it will return an image rather than a JSON response. For the scene creation part it was useful to leave out the render command since if there are any errors during the scene creation we want to see those and returning an image would prevent us from seeing any errors. You can however create the scene and render the image in a single request if needed. Here is what we need to render our image.

[
	{"jsonrpc": "2.0", "method": "use_scope", "params": {
		"scope_name" : "exScope"
	}, "id": 1},

	{"jsonrpc": "2.0", "method": "element_set_attributes", "params": {
		"element_name" : "exOptions",
		"create" : true,
		"attributes" : {
			"progressive_rendering_max_samples" : {
				"type" : "Sint32",
				"value" : 100
			},
			"progressive_rendering_max_time" : {
				"type" : "Sint32",
				"value" : 10
			}
		}
	}, "id": 2},

	{"jsonrpc": "2.0", "method": "render", "params": {
		"scene_name" : "exScene",
		"renderer" : "iray",
		"render_context_options" : {
			"scheduler_mode" : {
				"type" : "String",
				"value" : "batch"
			}
		}
	}, "id": 3},

	{"jsonrpc": "2.0", "method": "delete_scope", "params": {
		"scope_name" : "exScope"
	}, "id": 4}
]

The first command in our batch must be the use_scope command so that the other commands can “see” the scene we created. Without calling this everything we created will be invisible to the other commands. We then set two new attributes on our options element to control when rendering will terminate, if either of these conditions is met rendering will finish. So in our case it will render either 100 iterations or for 10 seconds, which ever comes first.

We then make a call to the render command and provide a special render_context_options parameter where we set the Iray scheduler_mode to batch. This causes Iray to render continuously until the termination conditions are met and only return after that. Usually you might want to render in stages so you can retrieve intermediate images but here we will just render to the end and return the completed image. To the right we can see the completed image once again, you can click this one to enlarge and view a higher resolution version.

Final Result

Final Result (Cilck to Enlarge)

Finally after rendering we call delete_scope to remove the scene we made and everything associated with it. This cleans up the database and frees memory for other users and tasks. Of course if we wanted to perform further actions on the scene we would omit this command.

Summary

In this article we have covered all of the steps necessary to create  simple scene entirely in code without any pre-existing geometry elements. You have learned about many key RealityServer commands which are needed to perform common operations as well as how to combine them in useful ways. With this experience you can, with the aid of the RealityServer Command Documentation create much more complex scenes and manipulate other scenes you might load from disk. Think about where you could use dynamic scene creation in your next RealityServer project. Contact us if you want more details or would like to request an evaluation of RealityServer.

Paul Arden

Paul Arden has worked in the Computer Graphics industry for over 20 years, co-founding the architectural visualisation practice Luminova out of university before moving to mental images and NVIDIA to manage the Cloud-based rendering solution, RealityServer, now managed by migenius where Paul serves as CEO.

More Posts - LinkedIn

Articles Tutorials
Get in Touch