In App SDK plugin parameters are presented as properties of the Plugin type (or its descendent concrete plugin types) in the statically typed languages (C++, C#) or the runtime plugin objects in the dynamic languages (Python, JavaScript). Also they are often referred as properties in code comments and docs.
There are both simple properties in the languages that support them (C#, Python, JavaScript) and getter/setter methods in all languages. The later allow you to (optionally) specify at what time to read or write a value of an animated plugin parameter.
Properties are always read and written by value and always a full copy of their value is received on read and send on write (with a few exceptions, see Optimizations chapter, TypedLists, move semantics in C++ and maxTypedListsCopyByteSize in Node.js).
Parameter types
The following are the types recognized in a V-Ray scene (see V-Ray scene file format below). They have corresponding types in the different App SDK language bindings. The SDK uses the respective basic language types wherever possible and defines custom type classes for the rest.
- Basic types:
int
,bool
,float
,Color
(3 float RGB),AColor
(4 float ARGB),Vector
(3 float),Matrix
(3 Vectors, column-major),Transform
(a Matrix and a Vector for translation) andstring
(UTF-8). - Objects: references to other plugin instances (
Plugin
andPluginRef
types). - Typed lists: The typed lists in App SDK are
IntList
,FloatList
,ColorList
,VectorList
,TransformList
andPluginList
. - General heterogeneous lists: The C++ binding uses the
ValueList
(i.e.std::vector<Value>
) type for items in a general list. The .Net binding usesIList<object>
and Python and Node.js use their native heterogeneousarray
s/list
s. General lists can be nested. - Output parameters: These are additional values generated by a given plugin which may be used as input by others. For example the TexAColorOp plugin (discussed later in the Textures lessons) can be referenced directly as a texture, resulting in its default
AColor
texture output, but you can also refer to any of its other outputs, like sum, difference, maximum etc. for different results. The Plugin object itself, set as a value of another Plugin property (parameter) can be used as a reference to the Plugin default output and the PluginRef type is used as a reference to an alternative output.
Manipulating parameters
The Plugin type discussed in the previous chapter provides convenient getters and setters. In the strongly typed C++ and C# bindings these are members of the specialized plugin classes derived from the base Plugin class. There are also "generic" methods in the base class. In Python plugin objects expose their parameters as both attributes and dictionary-like keys. In Node.js the parameters are exposed as properties of Plugin objects. A very important point when dealing with parameter values is that all getters return copies of the underlying data in the render engine. If you make changes to them you are not making changes to the actual scene. Changes are applied only when you pass them back to the setter.
renderView.transform = vray.Transform() print(renderView.transform) # prints Transform(Matrix(Vector(0, 0, 0), Vector(0, 0, 0), Vector(0, 0, 0)), Vector(0, 0, 0)) copyTransform = renderView.transform copyTransform = copyTransform.replaceOffset(vray.Vector(5, copyTransform.offset.y, copyTransform.offset.z)) print(renderView.transform) # prints Transform(Matrix(Vector(0, 0, 0), Vector(0, 0, 0), Vector(0, 0, 0)), Vector(0, 0, 0)) renderView.transform = copyTransform print(renderView.transform) # prints Transform(Matrix(Vector(0, 0, 0), Vector(0, 0, 0), Vector(0, 0, 0)), Vector(5, 0, 0))
// default Transform constructor in C++ leaves it uninitialized for performance renderView.set_transform(VRay::Transform(0)); cout << renderView.get_transform() << endl; // prints Transform(Matrix(Vector(0, 0, 0), Vector(0, 0, 0), Vector(0, 0, 0)), Vector(0, 0, 0)) // Vector, Matrix, Transform, Color etc. are mutable only in C++ renderView.get_transform().offset[0] = 5.0f; cout << renderView.get_transform() << endl; // prints Transform(Matrix(Vector(0, 0, 0), Vector(0, 0, 0), Vector(0, 0, 0)), Vector(0, 0, 0)) Transform tm = renderView.get_transform(); tm.offset[0] = 5.0f; renderView.set_transform(tm); cout << renderView.get_transform() << endl; // prints Transform(Matrix(Vector(0, 0, 0), Vector(0, 0, 0), Vector(0, 0, 0)), Vector(5, 0, 0))
renderView.Transform = new Transform(0); Console.WriteLine(renderView.Transform); // prints Transform(Matrix(Vector(0, 0, 0), Vector(0, 0, 0), Vector(0, 0, 0)), Vector(0, 0, 0)) Transform copyTransform = renderView.Transform; copyTransform = copyTransform.ReplaceOffset(new Vector(5, copyTransform.Offset.Y, copyTransform.Offset.Z)); Console.WriteLine(renderView.Transform); // prints Transform(Matrix(Vector(0, 0, 0), Vector(0, 0, 0), Vector(0, 0, 0)), Vector(0, 0, 0)) renderView.Transform = copyTransform; Console.WriteLine(renderView.Transform); // prints Transform(Matrix(Vector(0, 0, 0), Vector(0, 0, 0), Vector(0, 0, 0)), Vector(5, 0, 0))
renderView.transform = vray.Transform(); console.log(renderView.transform); // prints Transform(Matrix(Vector(0, 0, 0), Vector(0, 0, 0), Vector(0, 0, 0)), Vector(0, 0, 0)) var copyTransform = renderView.transform; copyTransform = copyTransform.replaceOffset(vray.Vector(5, copyTransform.offset.y, copyTransform.offset.z)); console.log(renderView.transform); // prints Transform(Matrix(Vector(0, 0, 0), Vector(0, 0, 0), Vector(0, 0, 0)), Vector(0, 0, 0)) renderView.transform = copyTransform; console.log(renderView.transform); // prints Transform(Matrix(Vector(0, 0, 0), Vector(0, 0, 0), Vector(0, 0, 0)), Vector(5, 0, 0))
Output parameters and PluginRef
Texture plugins have output parameters for additional values that they can output (such as alpha, some kind of blend, etc). They can be connected as inputs to other plugins (like BRDFs) similarly to the way textures are connected for use of their default output. You only need to get a PluginRef handle for the specific output instead of the default Plugin handle.
PluginRef is a type which extends Plugin with information about the output that will be used when using the PluginRef instance as input to another Plugin. This was added in the v2 API. In other words previously we could only directly assign a Plugin to a parameter of type plugin and we had to use a special string-based method to specify the output parameter if we didn't want the default output to be used. Now PluginRef makes this task more natural and direct.
Here's an example of how to set an output parameter:
# brdfVRayMtl is a BRDFVRayMtl and texBitmap is a TexBitmap plugin # "generic" syntax with string name parameter brdfVRayMtl.opacity = texBitmap.getReference("out_alpha") # alternative syntax brdfVRayMtl.opacity = texBitmap.out_alpha # now the material opacity will come from the bitmap alpha channel
// brdfVRayMtl is a BRDFVRayMtl and texBitmap is a TexBitmap plugin // "generic" syntax with string name parameter brdfVRayMtl.setValue("opacity", PluginRef(texBitmap, "out_alpha")); // alternative syntax when using the concrete classes derived from Plugin // (the out_ prefix is applied to all output paramters so it duplicates the name) brdfVRayMtl.set_opacity(texBitmap.out_out_alpha()); // now the material opacity will come from the bitmap alpha channel
// brdfVRayMtl is a BRDFVRayMtl and texBitmap is a TexBitmap plugin // "generic" syntax with string name parameter brdfVRayMtl.SetValue("opacity", PluginRef.Create(texBitmap, "out_alpha")); // alternative syntax when using the concrete classes derived from Plugin // (the Out_ prefix is applied to all output parameters so it duplicates the name) brdfVRayMtl.Opacity = texBitmap.Out_OutAlpha; // now the material opacity will come from the bitmap alpha channel
// brdfVRayMtl is a BRDFVRayMtl and texBitmap is a TexBitmap plugin // "generic" syntax with string name parameter brdfVRayMtl.opacity = texBitmap.getReference("out_alpha"); // alternative syntax brdfVRayMtl.opacity = texBitmap.out_alpha; // now the material opacity will come from the bitmap alpha channel
Runtime types
Parameter polymorphism is an important feature of V-Ray. Texture parameters accept simple (basic) values, so instead of creating an additional texture plugin which generates a single color you just set a Color/AColor value to the texture slot. Same goes for float textures and single float values etc. You can also set the value of a texture parameter to an output parameter as described above.
There is some inconsistency in this regard in the various V-Ray plugins because they were written at different times. Some older plugins have separate single value and textured value parameters. For example BRDFDiffuse has a color and a color_tex parameter. In these cases the textured parameter slot overrides the single value when it is set. Notice that you can still set a single value to a textured slot in this case.
The following example shows how you can check the runtime type of a plugin parameter:
meta = brdfVRayMtl.getMeta('diffuse') # Output of this will depend on what is applied to this parameter slot print(meta['type'], meta['runtimeType']) # We can also check the size of lists from runtime meta information: meta = brdfLayered.getMeta('brdfs') print(meta['elementsCount'])
PropertyRuntimeMeta meta = brdfVRayMtl.getPropertyRuntimeMeta("diffuse"); // Output of these will depend on what is applied to this parameter slot cout << meta.getType() << " " << meta.getRuntimeType() << endl; // enum cout << meta.getTypeAsString()<< " " << meta.getRuntimeTypeAsString() << endl; // We can also check the size of lists from runtime meta information: meta = brdfLayered.getPropertyRuntimeMeta("brdfs"); cout << meta.getRuntimeElementsCount() << endl;
var meta = brdfVRayMtl.GetPropertyRuntimeMeta("diffuse"); // Output of these will depend on what is applied to this parameter slot Console.WriteLine("{0} {1}", meta.Type, meta.RuntimeType); // enum Console.WriteLine("{0} {1}", meta.TypeString, meta.RuntimeTypeString); // We can also check the size of lists from runtime meta information: meta = brdfLayered.GetPropertyRuntimeMeta("brdfs"); Console.WriteLine(meta.ElementsCount);
var meta = brdfVRayMtl.getMeta('diffuse'); // Output of this will depend on what is applied to this parameter slot console.log(meta.type, meta.runtimeType); // We can also check the size of lists from runtime meta information: meta = brdfLayered.getMeta('brdfs'); console.log(meta.elementsCount);
V-Ray scene file format
V-Ray uses a text based scene file format (.vrscene). It is quite simple which makes it convenient to debug and modify by hand. The format is case-sensitive and a little similar to JSON. Large data values, such as geometry definitions can be compressed (and text encoded). The file contains consecutive plugin instance definitions: type, instance name, parameter list. Nesting is not supported. The main rules are:
- Each plugin instance is defined on a new line starting with its type name followed by a space, an instance name, another space and an opening curly brace.
- Each parameter is written on a new line with its name, an equals sign with no whitespace on both sides and a value. The line ends with a semicolon. A parameter definition line may be split into multiple lines for long comma separated values such as lists.
- References to other plugins are defined by writing out their instance names without quotation marks. Output parameters are specified the same way with additional double colon and parameter name (instance_name::out_param_name).
- The end of the plugin definition is marked with a closing brace on a new line.
- C++ style single line comments are supported.
- Files can be stitched together with an #include "another.vrscene" directive like in C.
- References can be made to plugins which will be defined further down the file.
- The parser is indifferent to indentation and empty lines. The only whitespace rule is no whitespace around the value assignment operator (=) for parameters.
Scene files are supposed to be created by V-Ray. You shouldn't try to write them yourself, but you are of course free to modify them by hand.
It is important to note that the order of definition of plugin instances generally does not matter. This also applies to a scene created in memory, even when you don't export it to a file. There are a few exceptions such as camera related settings plugins, which may not work correctly if V-Ray doesn't process them in a particular order.
Default values
Every parameter has a default value, so even after you create an "empty" plugin instance it is actually fully functional. Of course it might need data, as for example with geometry plugins, but a light will work right away (placed at 0 coordinates). That being said, some plugins have inconvenient default values, which almost always need to be changed (for example some settings plugins, such as the image sampler settings or some shadow parameters). We usually can't just change the defaults in V-Ray, because it would break existing user scenes. Nevertheless, unless you know what you're doing, it is recommended to stick to the default values. You are free to experiment, of course, but don't use values which you don't understand as they may have performance implications or quality implications or they may even break physical plausibility. Note that when you export (save) a vrscene file it will always contain a bunch of settings plugins, even if you didn't create them. They will have default parameter values. This is how V-Ray always saves files.
subdivs parameters
You will see subdivs (subdivisions) parameters on many light and BRDF plugins. They control the number of new rays spawned for calculating glossy and diffuse effects on materials or the number of light and shadow evaluations and so on. The number of actual rays is proportional to the square of the parameter value. These can be used to increase or decrease sampling for the respective light or material, but we highly recommend leaving these at default values. We also recommend disabling local subdivs values altogether - see the Settings lesson for details. Some of the settings plugins also have subdivs parameters which are ok to change, like the Irradiance Map and Light Cache for example.
Note: The reason the renderer uses the square of the parameter value is the property of the Monte Carlo integration method that to reduce noise (variance) by half (1/2 noise), you need four times as many samples (4x), to get 1/10 the variance you need 100x more samples. This way we get linear results from linear increases in the subdivs parameters.