A note on terminology
- plugin: We use the term plugin a lot. Technically it could mean a plugin DLL for V-Ray (even V-Ray itself is a kind of plugin) or the type defined in it, which is for example a class in the programming sense, or finally an instance of this class which resides in memory and can be saved to a scene file. We will be using the term plugin to refer to plugin instances.
- exporter/translator: We call the piece of software that translates some native scene format to the V-Ray scene format an exporter or a translator, interchangeably. Basically what it does is creating a bunch of V-Ray plugins and setting their parameters. Note that we also use the verb "to export" sometimes in reference to the act of saving out the scene (which was already translated) to a *.vrscene file.
Overview
Plugins are the building blocks in a V-Ray scene. Everything is a plugin - the lights, geometry, materials and settings.
We could informally define three kinds of plugins that build up a V-Ray scene. One would be the so called "top-level" plugins, which can exist on their own, without being part of some plugin tree. Lights are top-level plugins for example. They can also receive input from other plugins of course, but they do not output values to other plugins. The plugins which are not top-level serve as input for parameter slots which require a plugin of certain type. For example a material plugin may require an optional texture input and you'd reference a texture plugin there. The texture plugin may receive input from a UVW generator and so on. The third kind would be a special type of top-level plugins which only have one instance. These are basically settings plugins. Most of them have "Settings" in their name, but a few do not. The V-Ray camera is also defined by such a singleton plugin.
Each of the language bindings has a Plugin class which is a lightweight wrapper for the underlying instance in the V-Ray engine. These objects do not contain the actual property data, so they can be copied around (e.g. passed by value). In the statically typed languages we support - C++ and C# - there are concrete classes for the specific V-Ray plugin types as well as the generic Plugin type. They provide property getters and setters for convenience over the generic methods that use strings to identify the property.
Since Plugin objects are just wrappers, their going out of scope does not remove the actual V-Ray plugin from the scene. It's just a reference. Adding and removing instances is done through methods of the VRayRenderer class.
The default constructor for the Plugin class creates an invalid object. The object can be checked as a boolean value for validity. Some APIs such as getPlugin() return a Plugin object. It can be invalid if for example the requested instance name was not found. It is good practice to check such returned values for validity before using them further.
Getting a plugin reference
There are several ways of obtaining a reference to an existing plugin specific for each language (see also PluginRef in the next chapter). They are demonstrated in the following example:
# We know the plugin's name in advance renderView = renderer.plugins["renderView"] # or equivalently renderView2 = renderer.plugins.renderView assert renderView == renderView2
// We know the plugin's name in advance RenderView renderView = renderer.getPlugin<RenderView>("renderView"); // We know only the type of the plugin and that it's a singleton RenderView renderView2 = renderer.getInstanceOf<RenderView>(); // We get it as a generic plugin type Plugin renderView3 = renderer.getPlugin("renderView"); // We can use this special cast similar to static_cast if we are certain of the type RenderView renderView4 = plugin_cast<RenderView>(renderView3); // There is a checked version similar to dynamic_cast. It returns invalid Plugin if the type doesn't match RenderView renderView5 = plugin_checked_cast<RenderView>(renderView3); assert(renderView == renderView2); assert(renderView == renderView3); // note that the right side here is generic Plugin assert(renderView == renderView4); assert(renderView == renderView5);
// We know the plugin's name in advance RenderView renderView = renderer.GetPlugin<RenderView>("renderView"); // We know only the type of the plugin and that it's a singleton RenderView renderView2 = renderer.GetInstanceOf<RenderView>(); // We get it as a generic plugin type Plugin renderView3 = renderer.GetPlugin("renderView"); System.Diagnostics.Debug.Assert(renderView == renderView2); System.Diagnostics.Debug.Assert(renderView == renderView3);
var assert = require('assert'); // We know the plugin's name in advance var renderView = renderer.plugins["renderView"]; // or equivalently var renderView2 = renderer.plugins.renderView; assert(renderView == renderView2);
We can retrieve all plugin names or all possible plugin types. We can also retrieve all instances of a given plugin type, e.g. Node.
# Print the names of all plugin instances for plugin in renderer.plugins: print(plugin.getName()) # Print the names of all available plugin classes for cls in renderer.classes: print(cls.getName()) # Print all instance names of a given type for node in renderer.classes.Node.getInstances(): print(node.getName())
// Print the names of all plugin instances for (const Plugin& plugin : renderer.getPlugins()) cout << plugin.getName() << endl; // Print the names of all available plugin classes for (const string& className : renderer.getAllPluginTypes()) cout << className << endl; // Print all instance names of a given type for (const Plugin& node : renderer.getPlugins("Node")) cout << node.getName() << endl;
// Print the names of all plugin instances foreach (Plugin plugin in renderer.GetPlugins()) Console.WriteLine(plugin.GetName()); // Print the names of all available plugin classes foreach (string className in renderer.AllPluginTypes) Console.WriteLine(className); // Print all instance names of a given type foreach (Plugin node in renderer.GetPlugins("Node")) Console.WriteLine(node.GetName());
// Print the names of all plugin instances for (var plugName in renderer.plugins) console.log(plugName); // Or alternatively iterate over all plugin instances and print their names for (var plugin of renderer.plugins) console.log(plugin.getName()); // Print the names of all available plugin classes for (var className in renderer.classes) console.log(className); // Or alternatively iterate over all plugin classes and print their names for (var cls of renderer.classes) console.log(cls.getName()); // Print all instance names of a given type var nodeInstances = renderer.classes.Node.getInstances(); for (var node of nodeInstances) console.log(node.getName());
Metadata
All plugins expose info about their properties' names, types, default values and description. This information we call plugin's metadata. It can be accessed in the following way:
pluginDescription = renderer.classes.RenderView.getDescription() # Description of a render view (camera) -- position, field of view, etc. [gpuSupport=(partial)] pluginMeta = renderer.classes.RenderView.getMeta() for propName, propMeta in pluginMeta.items(): print("propName = " + repr(propName)) # 'transform', 'fov', ... propertyDescription = propMeta["description"] # 'Camera transform - position and rotation', 'Horizontal field of view', ... propertyType = propMeta["type"] # 'Transform', 'float', ... defaultVal = propMeta["defaultValue"] # 'Transform(Matrix(Vector(1, 0, 0), Vector(0, 1, 0), Vector(0, 0, 1)), Vector(0, 0, 0))', '0.785398', ... gpuParamSupport = propMeta["GPUSupport"] # 'Full', 'Full', ...
PluginMeta pluginMeta = renderer.getPluginMeta("RenderView"); string pluginDescription = pluginMeta.getDescription(); // Description of a render view (camera) -- position, field of view, etc. [gpuSupport=(partial)] const vector<string> propertyNames = pluginMeta.getPropertyNames(); // ["transform", "fov", ...] for (const string& propName : propertyNames) { PropertyMeta propertyMeta = pluginMeta.getPropertyMeta(propName); string propertyDescription = propertyMeta.getDescription(); // "Camera transform - position and rotation", "Horizontal field of view", ... string propertyType = propertyMeta.getTypeAsString(); // "Transform", "float", ... Value defaultVal = propertyMeta.getDefaultValue(); // "Transform(Matrix(Vector(1, 0, 0), Vector(0, 1, 0), Vector(0, 0, 1)), Vector(0, 0, 0))", "0.785398", ... GPUParamSupport gpuParamSupport = propertyMeta.getGPUSupport(); // GPUParamSupport::GPUParamSupport_Full, GPUParamSupport::GPUParamSupport_Full, ... }
PluginMeta pluginMeta = renderer.GetPluginMeta("RenderView"); string pluginDescription = pluginMeta.Description; // Description of a render view (camera) -- position, field of view, etc. [gpuSupport=(partial)] string[] propertyNames = pluginMeta.PropertyNames; // ["transform", "fov", ...] foreach (var propName in propertyNames) { PropertyMeta propertyMeta = pluginMeta.GetPropertyMeta(propName); string propertyDescription = propertyMeta.Description; // "Camera transform - position and rotation", "Horizontal field of view", ... string propertyType = propertyMeta.TypeString; // "Transform", "float", ... object defaultVal = propertyMeta.DefaultValue; // "Transform(Matrix(Vector(1, 0, 0), Vector(0, 1, 0), Vector(0, 0, 1)), Vector(0, 0, 0))", "0.785398", ... GPUParamSupport gpuParamSupport = propertyMeta.GPUSupport; // GPUParamSupport.GPUParamSupport_Full, GPUParamSupport.GPUParamSupport_Full, ... }
var pluginDescription = renderer.classes.RenderView.getDescription() // Description of a render view (camera) -- position, field of view, etc. [gpuSupport=(partial)] var pluginMeta = renderer.classes.RenderView.getMeta() for (var propName in pluginMeta) { var propMeta = pluginMeta[propName] // 'transform', 'fov', ... propertyDescription = propMeta['description'] // 'Camera transform - position and rotation', 'Horizontal field of view', ... propertyType = propMeta['type'] // 'Transform', 'float', ... defaultVal = propMeta['defaultValue'] // 'Transform(Matrix(Vector(1, 0, 0), Vector(0, 1, 0), Vector(0, 0, 1)), Vector(0, 0, 0))', '0.785398', ... gpuParamSupport = propMeta['GPUSupport'] // 'Full', 'Full', ... }
- Description is a string which can be placed in the UI.
- Type is a string, denoting one of the possible Property Types
- Default value is an object of type type.
- GPUParamSupport describes to what extent a property is supported by V-Ray GPU
Creating plugin instances
The following example show how new plugin instances are created. If the requested instance name is already used creation will fail.
# this will generate a unique name for the instance renderView = renderer.plugins.classes.RenderView() # or pass a name of your own renderView = renderer.plugins.classes.RenderView("myRenderView")
// this will generate a unique name for the instance RenderView renderView = renderer.newPlugin<RenderView>(); // or pass a name of your own RenderView renderView = renderer.newPlugin<RenderView>("myRenderView");
// this will generate a unique name for the instance RenderView renderView = renderer.NewPlugin<RenderView>(); // or pass a name of your own RenderView renderView = renderer.NewPlugin<RenderView>("myRenderView");
// this will generate a unique name for the instance var renderView = renderer.plugins.classes.RenderView(); // or pass a name of your own var renderView = renderer.plugins.classes.RenderView("myRenderView");
Additionally there is the getInstanceOrCreate() method which only creates the instance if one does not already exist. Otherwise it returns the existing instance. This is useful for settings plugins which should not have more than one instance in the scene. There is also the getInstanceOf() method in C++, GetInstanceOf() in C# and getInstance() in Python and Node.js that just finds the last, most recently added instance if one exists.
Removing plugin instances
When a plugin instance is removed from the scene all references to it are reset to null internally. Any Plugin objects you have that reference the deleted plugin instance become invalid, although performing a boolean check on them still returns True. Operations on them will fail. If you're not sure if an instance still exists, get a Plugin reference by name again from the renderer and perform a boolean check on it.
node = renderer.plugins['myNodeName'] del renderer.plugins['myNodeName'] # or del renderer.plugins.myNodeName # or del renderer.plugins[node] # or simply node.deleteThis() # node variable won't reference any plugin instance after this call
Node node = renderer.getPlugin<Node>("myNodeName"); renderer.deletePlugin(node); // or renderer.deletePlugin("myNodeName"); // or (but not recommended) renderer.deletePlugin(node.getName());
Node node = renderer.GetPlugin<Node>("myNodeName"); renderer.DeletePlugin(node); // or renderer.DeletePlugin("myNodeName"); // or (but not recommended) renderer.DeletePlugin(node.getName());
var node = renderer.plugins['myNodeName']; delete renderer.plugins['myNodeName']; // or delete renderer.plugins.myNodeName; // or delete renderer.plugins[node]; # or simply node.deleteThis(); // node variable won't reference any plugin instance after this call
Replacing plugin instances
In some cases you will want to use a new plugin instance in place of another that may be connected to multiple parameter slots. This is typical for changing materials or their textures for example. To avoid setting all the connections again yourself, use the plugin replacement API. You can also use it to reset connections to null.
oldPlugin = renderer.plugins["oldMaterial"] newPlugin = renderer.classes.MtlSingleBRDF("newMaterial") newPlugin.brdf = renderer.classes.BRDFDiffuse("grayDiffuse") oldPlugin.replaceWith(newPlugin) # or oldPlugin.replaceWith(None)
Plugin oldPlugin = renderer.getPlugin("oldMaterial"); Plugin newPlugin = renderer.newPlugin("MtlSingleBRDF", "newMaterial"); newPlugin.set_brdf(renderer.newPlugin("BRDFDiffuse", "grayDiffuse")); renderer.replacePlugin(oldPlugin, newPlugin); // or pass default constructed Plugin to reset to null renderer.replacePlugin(oldPlugin, Plugin());
Plugin oldPlugin = renderer.GetPlugin("oldMaterial"); Plugin newPlugin = renderer.NewPlugin("newMaterial", "MtlSingleBRDF"); newPlugin.Brdf = renderer.NewPlugin("BRDFDiffuse", "grayDiffuse"); renderer.ReplacePlugin(oldPlugin, newPlugin); // or renderer.ReplacePlugin(oldPlugin, null);
var oldPlugin = renderer.plugins["oldMaterial"]; var newPlugin = renderer.classes.MtlSingleBRDF("newMaterial"); newPlugin.brdf = renderer.classes.BRDFDiffuse("grayDiffuse"); oldPlugin.replaceWith(newPlugin); // or oldPlugin.replaceWith(null);