---
title: "UI and VFB"
canonical: "https://documentation.chaos.com/space/APPSDK/132811386/UI%20and%20VFB"
format: markdown
---
## **Introduction**

---

- **Image preview**:  
Loads render elements channels via a dropdown list;  
Works with display corrections;  
Loads various 8bit and 32bit file formats, including V-Ray resumable files;  
Image comparison between 2 or 4 renders;

- **Image management**:  
Keeps the rendered image in full 32-bit floating point format;  
Can store history of rendered images with their post rendering corrections;  
Can save corrected output to various image formats;

- **Image editing and post processing**:  
Set Color Corrections to rendered image and its elements;  
Composite mode for Back to Beauty workflow including layers corrections;  
LightMix control on lights contribution in the rendered image;

- **Scene editing**:  
Can modify actual lights values by transferring updated intensity and color from LightMix mode (requires implementation);  
IPR camera navigation control from inside VFB;

- **Render management**:  
Denoiser control;  
Region rendering control;  
Allows you to choose the order in which the buckets are rendered;

## **User Interface**

---

### VFB Menu

---

| **Menu** | **Menu Options** |
| --- | --- |
| **File** | **Save current channel** – Saves the currently loaded channel to an image file format.<br>**Save all image channels to separate files** – Saves all the render elements to separate files.<br>**Save all image channels to single file** – Saves the image to a single multi-channel EXR or *.vrimg* file.<br>**Load image** – Opens an image file to be previewed in the V-Ray Frame Buffer.<br>**Batch image processing** – Allows processing of multiple .vrimg files with the same layer tree changes at the same time. | Batch Image Processing<br>![image](media://c863879f-d079-4e97-87f6-f5cefc01db36)<br>Input folder – Specifies a path to start images.<br>Output folder – Specifies a path for the output images.<br>Layer preset – Specifies a layer tree corrections preset.<br>Output filenames suffix – Specifies a suffix added to the output image filenames.<br>Overwrite existing – Enables overwrite of existing files with the same name in the output folder. |
| **Render** | **Start interactive rendering** – Calls the `VFBRenderInteractive` callback. Requires `showVfbButtonInteractiveStart` to be set to true in `RendererOptions`.<br>**Abort rendering** – Stops the current rendering.<br>**Render** – Starts rendering. If the `VFBRenderLast` callback is set, it will **not** start rendering, only call the callback. |
| **Image** | **Follow mouse** – Renders the closest bucket found to the mouse pointer, when using the bucket image sampler. If the progressive sampler is used, V-Ray samples the closest pixels to the mouse pointer.<br>**Follow mouse** – Drag the mouse over the VFB while rendering to change what part of the image is sampled first;  
**Follow mouse (locked)** – Locks the bucket (or sampling) starting point.<br>**Copy current channel to clipboard** – Copies the current channel to the clipboard.<br>**Clear image** – Clears the contents of the frame buffer. This is useful when starting a new render to prevent confusion with the previous image. |
| **View** | **Display color space** –Specifies the color space, in which the image is displayed.<br>**None** – Does not specify a color space;  
**sRGB** – Displays the image in sRGB color space;  
**OCIO** – Displays the image in a color space loaded from an OCIO configuration file;  
**ICC** – Displays the image in a color space loaded from an ICC configuration file;  
**Gamma 2.2** – Displays the image in Gamma 2.2 color space.<br>**Zoom VFB** – Zooms in/out the rendered image in the VFB.<br>**Zoom 50%** – Zooms out to 50%;  
**Zoom 100%** – Zooms to 100%. Alternatively, double-click in the VFB with the left mouse button;  
**Zoom 150%** – Zooms in to 150%.  
**Zoom to fit** – Zooms the current image to fit in the VFB. If Render Region is active – zooms to the region.<br>**Channels** – Chooses which channels to see.<br>**View red channel** – Displays the red channel;  
**View green channel** – Displays the green channel;  
**View blue channel** – Displays the blue channel;  
**Switch to alpha channel** – Displays the alpha channel;  
**Monochromatic mode** –Displays the image in monochromatic mode.<br>**Color clamping** – Opens the color clamping submenu options:<br>Force color clamping – Forces color clamping;  
View clamped colors – Displays the clamped colors.<br>**Use pixel aspect** – Enables visualization of the pixel aspect ratio.<br>**Panorama View** – Shows the image in <span style="color: #172b4d">360° view.</span><br>**Show History** – Shows the History panel.<span style="color: #172b4d"> </span><br>**Show Layers** – Shows the Layers panel. |
| **Options** | **VFB settings** – Opens the VFB Settings window where you can adjusts settings for Render View, Render Region, History and Layers. |

### VFB Toolbar

---

|  |  |
| --- | --- |
| ![image](media://bbab16ea-c3a5-4965-806c-21120639143f) | This dropdown gives access to render elements rendered for the scene. The selected render element is displayed in the VFB. By default, the RGB color and Alpha render elements are available. Any additional render elements that have been added to the scene also appear in the drop-down. |
| ![image](media://37fa96e6-487f-4723-bd82-618ab2b76d92) | Displays the coordinates of the mouse pointer. |
| ![image](media://da39927d-5c77-49a5-aed8-4494224eecf2) | Specifies the sampled area size. Click on the arrow to open a context menu with the available sampled area sizes: 1x1, 3x3, 5x5, and 7x7. |
| ![image](media://a92cb946-b237-45f3-98ca-0746cae850b3) | Specifies whether color and display corrections are applied (RGB) or not (Raw) when showing the sampled pixel values at the current mouse pointer position. |
| ![image](media://5bf3fb1a-d300-4842-a8bd-aa65b6f466a5) | Displays the RGB pixel values at the current mouse pointer position before applying any color corrections. |
| ![image](media://9d35faa7-befd-4f0b-b015-7c597e121e64) | Specifies RGB values. Click on the arrow to open a context menu with the available option.<br>None – Does not specify the RGB value.  
HSV – Specifies the Hue, Saturation and Value of the pixel under the current mouse position.  
Web – Specifies the HEX of the pixel under the current mouse position.  
8bit – Specifies the 8bit color palette of the pixel under the current mouse position. |
| ![image](media://bb22926f-1160-4a2b-8b39-73bb0041715b) | Displays the Hue, Saturation and Value of the pixel under the current mouse position when HSV is selected. |
| ![image](media://46d87039-2cd2-4065-9e9f-bc91af000adf) | Displays the HEX of the pixel under the current mouse position when Web is selected. |
| ![image](media://df147149-d450-4f12-9a8d-e22c6c3d4f38) | Displays the 8bit color palette of the pixel under the current mouse position when 8bit is selected. |

|  |  |
| --- | --- |
| ![image](media://2cd012bc-d46c-46cb-a6c6-40b2f39c22a4) | Locks the mouse pointer coordinates and displays information for the selected pixel. |
| ![image](media://05f2ff14-881a-4287-bd65-f4b0e759bf1f) | Shows corrected colors. |
| ![image](media://e54cd3de-dfd8-4f0a-9b57-675d51e3060e) | Shows the V-Ray log. |
| ![image](media://d9a0fbdd-abc5-4872-8f86-1689fa805425) | Displays the Alpha channel. |
| ![image](media://b3344e2c-27ed-4c20-b527-72380f725319) | Displays the red channel. |
| ![image](media://3e6f3993-f467-4400-9acb-8eb2cc76c49e) | Displays the green channel. |
| ![image](media://12cc4fcd-0cda-42b4-adfd-e15fe8a35014) | Displays the blue channel. |
| ![image](media://f6ab0d4f-5145-4acf-9623-f479afb9f84a) | Saves the image to disk. Press and hold the icon to bring up the submenu:<br>Save current channel – Saves the current channel to an image file format;  
Save all image channels to separate files – Saves all the render elements into separate files;  
Save all image channels to single file – Saves the image into a single multi-channel EXR or *.vrimg* file. |
| ![image](media://5d40f8aa-a6ea-4e3e-aa40-31d95787b4e5) | Clears the contents of the frame buffer. This is useful when starting a new render to prevent confusion with the previous image. |
| ![image](media://a8a6ae30-f197-4f63-8c04-df980d917959) | Renders the closest bucket found to the mouse pointer, when using the bucket image sampler. If the progressive sampler is used, V-Ray samples the closest pixels to the mouse pointer. With this option enabled, you can right-click on the image and select Lock bucket starting point to lock the bucket (or sampling) starting point. |
| ![image](media://3d39d67f-85d0-4ec6-ab26-77db016df8e6) | Allows you to render regions in the VFB. *See the Render Region section for more information.* |
| ![image](media://558be55a-1ee7-4838-94fb-913cb9a47c91) | Starts IPR. |
| ![image](media://bed2b8f1-ba06-457e-83f0-dfd5ffe0b7c3) | Stops the current rendering. |
| ![image](media://1e51a4e6-9b7d-4461-986e-8bc0d7dadbb1) | Starts rendering. |

### Render History

---

|  |  |
| --- | --- |
| ![image](media://dc7771b4-995c-451e-be0f-b6739d61d7c4) | Enables or disables image A/B vertical comparison. Select images A and B from the render history. |
| ![image](media://0fb1c3ad-19d3-45e1-bb9b-e762acae283c) | Enables or disables image A/B horizontal comparison. Select images A and B from the render history. |
| ![image](media://1b02787e-12f8-41ff-a86c-2e471b97cfd0) | Enables or disables image A/B/C/D comparison. Select images A, B, C and D from the render history. |
| ![image](media://a715e56e-3436-41e4-9f34-9cb91c81bbbf) | Saves the current image from the VFB to the render history. The image is placed at the top of the render history list. |
| ![image](media://0f6cb4c9-8de8-4e89-a2e1-68eb97cd75bb) | Loads the selected image from the render history to the VFB. |
| ![image](media://af4426b6-2097-433d-9e18-3b7928663128) | Removes the selected image from the render history. |

|  |  |
| --- | --- |
| ![image](media://9855cf6f-4dea-4e2c-88d2-32487a6c6c8c) | <span style="color: #172b4d">A search field where you can filter the images based on the scene paths and notes.</span> |

### Layers

---

### Stats

---

> ℹ️ Right-click to display a context menu that allows you to copy the Stats values.

![image](media://43ca8da2-7d27-4a59-bb5a-7c024a77ceeb)



### Render Region

---

### VFB Shortcuts

---

| **Mouse** | **Description** |
| --- | --- |
| Mouse wheel | Zoom in/Zoom out |
| Double-click left button | Zoom to 100% |
| Middle button dragging | Pan (hand tool) |
| <span style="color: #172b4d">Ctrl+Shift+Left click</span> | <span style="color: #172b4d">Zoom in the rendered image</span> |
| <span style="color: #172b4d">Ctrl+Shift+Right click</span> | Zoom out the rendered image |
|  |  |
| **Keyboard** | **Description** |
| Ctrl+Shift+left click, + / = | Zoom in |
| Ctrl+Shift+right click, -/_ | Zoom out |
| Double click, * | Zoom to 100% |
| Arrow keys | Pan left, up, right, down |
| F | Fit region or whole image in the VFB |
| Esc | Abort render |
| Q | Set history A/B vertical compare mode |
| W | Set history A/B horizontal compare mode |
| E | Enable history A/B/C/D compare mode |
| 1-9 | Load the respective image from the VFB history |
| H | Show/hide history |
| Ctrl+L | Show/hide whole right panel |
| P | Show/hide only layers tree |
| L | Locks the mouse pointer coordinates and displays information for the selected pixel, i.e. activates the Lock pixel info coordinates button. |

### Camera control for interactive (RT) rendering

---

|  |  |
| --- | --- |
| Shift & mouse wheel scroll | Move the camera forward or backward |
| Ctrl & mouse wheel scroll | Change camera FoV, effectively zooming in/out |
| Shift & drag with left mouse button | Orbit the camera around the scene |
| Ctrl & drag with left mouse button | Pan the camera |

## **Control from code**

---

<details>
<summary>Python</summary>

```python
with vray.VRayRenderer(showFrameBuffer=False) as renderer:
```
</details>

<details>
<summary>C++</summary>

```c++
RendererOptions options;
options.showFrameBuffer = false;
VRayRenderer renderer(options);
```
</details>

<details>
<summary>C#.NET</summary>

```csharp
RendererOptions options = new RendererOptions();
options.ShowFrameBuffer = false;
 
using (VRayRenderer renderer = new VRayRenderer(options))
{
}
```
</details>

<details>
<summary>Node.js</summary>

```javascript
var renderer = vray.VRayRenderer({
    showFrameBuffer: false
})
```
</details>

### The VFB class

<details>
<summary>Python</summary>

```python
with vray.VRayRenderer() as renderer:
    vfb = renderer.vfb
    vfb.shown = True             # Can be used to hide and show the window
    vfb.interactivity = True     # Whether camera mouse control is enabled
    vfb.position = (0,0)         # Position of the window in screen-space coordinates
    vfb.size = (800, 600)        # Size of the window in pixels
    vfb.alwaysOnTop = True       # Toggles always-on-top window behavior
    stateBuffer = vfb.getState() # Can be used to save serialized window state
    vfb.setState(stateBuffer)    # Can be used to restore serialized window state
```
</details>

<details>
<summary>C++</summary>

```c++
VRayRenderer renderer;
VRayRenderer::VFB& vfb = renderer.vfb;
vfb.show(true /*show*/, true /*setFocus*/);     // The window is visible and auto focused
vfb.enableInteractivity(true);                  // Whether camera mouse control is enabled
vfb.setPositionAndSize(0, 0, 800, 600);         // Position in screen-space and size in pixels
vfb.setAlwaysOnTop(true);                       // Toggles always-on-top window behavior
size_t numBytes = 0;
VFBState *stateBuffer = vfb.getState(numBytes); // Can be used to save serialized window state
vfb.setState(stateBuffer, numBytes);            // Can be used to restore serialized window state
```
</details>

<details>
<summary>C#.NET</summary>

```csharp
using (VRayRenderer renderer = new VRayRenderer())
{
	VFB vfb = renderer.Vfb;
	vfb.Shown = true;                       // Can be used to hide and show the window
	vfb.Interactivity = true;               // Whether camera mouse control is enabled
	vfb.SetPositionAndSize(0, 0, 800, 600); // Position in screen-space and size in pixels
	vfb.AlwaysOnTop = true;                 // Toggles always-on-top window behavior
	byte[] stateBuffer = vfb.GetState();    // Can be used to save serialized window state
	vfb.SetState(stateBuffer);              // Can be used to restore serialized window state
}
```
</details>

<details>
<summary>Node.js</summary>

```javascript
var renderer = vray.VRayRenderer();
var vfb = renderer.vfb;
vfb.shown = true;                       // Can be used to hide and show the window
vfb.interactivity = true;               // Whether camera mouse control is enabled
vfb.position = { x: 0, y: 0 };          // Position of the window in screen-space coordinates
vfb.size = { width: 800, height: 600 }; // Size of the window in pixels
vfb.alwaysOnTop = true;                 // Toggles always-on-top window behavior
stateBuffer = vfb.getState();           // Can be used to save serialized window state
vfb.setState(stateBuffer);              // Can be used to restore serialized window state
```
</details>

### **VFB Progress Bar**

### VFB Viewport Context Menu

<details>
<summary>Python</summary>

```python
# VFB Context menu entries
contextMenuItems = [
    {'id': 0, 'type': 'normal',   'text': 'Custom option'},
    {'id': 1, 'type': 'normal',   'text': 'Custom disabled option', 'enabled': False},
    {'id': 2, 'type': 'checkbox', 'text': 'Custom checkbox'},
    {'id': 3, 'type': 'checkbox', 'text': 'Custom checkbox 2', 'defaultValue': 1}
]


# VFB Context menu callback
def onContextMenu(renderer, command, x, y):
    if command == 0:
        print("Custom option clicked")
    elif command == 1:
        print("This is disabled")
    elif command == 2:
        print("Value of Custom checkbox is", renderer.getVFBContextMenuItemValue(command))
        # Note that the value will not change automatically, you must change it yourself
    elif command == 3:
        value = renderer.getVFBContextMenuItemValue(command)
        renderer.setVFBContextMenuItemValue(command, 1 - value)
        print("Value of Custom checkbox 2 changed from", value, "to", 1 - value)
    else:
        print('Command %d not implemented' % command)


renderer.setVFBContextMenuItems(contextMenuItems)
renderer.setOnVFBContextMenuSelected(onContextMenu)
```
</details>

<details>
<summary>C++</summary>

```c++
// Context menu callback
void onContextMenu(VRayRenderer& renderer, int command, int x, int y, void*) {
	int value = 0;
	switch (command) {
	case 0:
		printf("Custom option clicked\
");
		break;
	case 1:
		printf("This is disabled\
");
		break;
	case 2:
		renderer.getVFBContextMenuItemValue(command, value);
		printf("Value of Custom checkbox is %d\
", value);
		// Note that the value will not change automatically, you must change it yourself
		break;
	case 3:
		renderer.getVFBContextMenuItemValue(command, value);
		renderer.setVFBContextMenuItemValue(command, 1 - value);
		printf("Value of Custom checkbox 2 changed from %d to %d\
", value, 1 - value);
		break;
	default:
		printf("Command %d not implemented\
", command);
	}
}
 
void setupContextMenu(VRayRenderer& renderer) {
	vector<VFBContextMenuItem> contextMenuItems;
 
	// Context menu items
	contextMenuItems.push_back({ 0, VFBMenuItemType::normal,   0, true,  "Custom option" });
	contextMenuItems.push_back({ 1, VFBMenuItemType::normal,   0, false, "Custom disabled option" });
	contextMenuItems.push_back({ 2, VFBMenuItemType::checkbox, 0, true,  "Custom checkbox" });
	contextMenuItems.push_back({ 3, VFBMenuItemType::checkbox, 1, true,  "Custom checkbox 2"});

	renderer.setVFBContextMenuItems(contextMenuItems);
	renderer.setVFBContextMenuSelectedCallback(onContextMenu);
}
```
</details>

<details>
<summary>C#.NET</summary>

```csharp
using (VRayRenderer renderer = new VRayRenderer())
{
    // Context menu items
    List<VFBContextMenuItem> contextMenuItems = new List<VFBContextMenuItem>();
    contextMenuItems.Add(new VFBContextMenuItem(0, VFBMenuItemType.normal,  "Custom option"));
    contextMenuItems.Add(new VFBContextMenuItem(1, VFBMenuItemType.normal,  "Custom disabled option", false));
    contextMenuItems.Add(new VFBContextMenuItem(2, VFBMenuItemType.checkbox, "Custom checkbox"));
    contextMenuItems.Add(new VFBContextMenuItem(3, VFBMenuItemType.checkbox, "Custom checkbox 2", true, 1));

    renderer.SetVFBContextMenuItems(contextMenuItems);

    // Context menu callback
    renderer.VFBContextMenuSelected += new EventHandler<VFBContextMenuSelectedEventArgs>((source, e) =>
    {
        int value = 0;
        switch (e.CommandId)
        {
            case 0:
                Console.WriteLine("Custom option clicked");
                break;
            case 1:
                Console.WriteLine("This is disabled");
                break;
            case 2:
                renderer.GetVFBContextMenuItemValue(e.CommandId, out value);
                Console.WriteLine(String.Format("Value of Custom checkbox is {0}", value));
                // Note that the value will not change automatically, you must change it yourself
                break;
            case 3:
                renderer.GetVFBContextMenuItemValue(e.CommandId, out value);
                renderer.SetVFBContextMenuItemValue(e.CommandId, 1 - value);
                Console.WriteLine(String.Format("Value of Custom checkbox 2 changed from {0} to {1}", value, 1 - value));
                break;
            default:
                Console.WriteLine(String.Format("Command {0} note implemented", e.CommandId));
                break;
        }
    });

    renderer.Vfb.Shown = true;
    renderer.WaitForVFBClosed();
}
```
</details>

<details>
<summary>Node.js</summary>

```javascript
// VFB Context menu entries
contextMenuItems = [
    {'id': 0, 'type': 'normal',   'text': 'Custom option'},
    {'id': 1, 'type': 'normal',   'text': 'Custom disabled option', 'enabled': false},
    {'id': 2, 'type': 'checkbox', 'text': 'Custom checkbox'},
    {'id': 3, 'type': 'checkbox', 'text': 'Custom checkbox 2', 'defaultValue': 1}
]

renderer.setVFBContextMenuItems(contextMenuItems)
// VFB Context menu callback
renderer.on('vfbContextMenuSelected', function (command, x, y) {
    switch(command){
        case 0:
            console.log("Custom option clicked")
            break
        case 1:
            console.log("This is disabled")
            break
        case 2:
            console.log("Value of Custom checkbox is", renderer.getVFBContextMenuItemValue(command))
            // Note that the value will not change automatically, you must change it yourself
            break
        case 3:
            value = renderer.getVFBContextMenuItemValue(command)
            renderer.setVFBContextMenuItemValue(command, 1 - value)
            console.log("Value of Custom checkbox 2 changed from", value, "to", 1 - value)
            break
        default:
            console.log('Command', command, 'not implemented')
    }
})
```
</details>

### Light Mix and Transfer to scene

<details>
<summary>Python</summary>

```python
# Compatibility with Python 2.7.
from __future__ import print_function

# The directory containing the vray shared object should be present in the PYTHONPATH environment variable.
# Try to import the vray module from VRAY_SDK/python, if it is not in PYTHONPATH
import sys, os
VRAY_SDK = os.environ.get('VRAY_SDK')
if VRAY_SDK:
    sys.path.append(os.path.join(VRAY_SDK, 'python'))
import vray
import threading

SCENE_PATH = os.path.join(os.environ.get('VRAY_SDK'), 'scenes')
# Change process working directory to SCENE_PATH in order to be able to load relative scene resources.
os.chdir(SCENE_PATH)
# An event used for waiting on the callback
event = threading.Event()

# Create an instance of VRayRenderer.
# The renderer is automatically closed after the `with` block.
with vray.VRayRenderer() as renderer:
    # Usually it's a good idea to have a log callback handler, but we will not add one for this example.
    # Load scene from a file.
    renderer.load(os.path.join(SCENE_PATH, 'cornell_new.vrscene'))
    # Add the LightMix plugin. No need to keep the reference, because you can't do anything with this plugin.
    # It just has to exist in the scene.
    renderer.classes.RenderChannelLightMix()
    # Environment light select
    ls_env = renderer.classes.RenderChannelLightSelect('LSEnvironment')
    ls_env.light_select_mode = 10  # 10 is a special, undocumented value used for environment light
    ls_env.name = 'Environment'
    # Self illumination light select
    ls_self = renderer.classes.RenderChannelLightSelect('LSSelfIllumination')
    ls_self.light_select_mode = 11  # 11 is a special, undocumented value used for self illumination light
    ls_self.name = 'Self Illum.'
    # A full light light select
    ls_light = renderer.classes.RenderChannelLightSelect('LSCeilingLight')
    ls_light.light_select_mode = 4  # full light (direct + indirect)
    ls_light.name = 'Ceiling Light'
    # Adding a light to a light select
    light_rect = renderer.plugins['VRayLightRectShape1']
    light_rect.channels_full = [ ls_light ]
    def lightMixTransfer(r, changes, instant):
        # Each LightMixChange object contains:
        #    - the render element plugin
        #    - isApplied flag (bool) - This must be set by the user and it will reset the change in the VFB
        #    - enabled flag (bool) - Whether the light select is enabled or not in the VFB. This is *not* reset even when isApplied is true.
        #    - intensity multiplier (float)
        #    - color multiplier (VRay::Color)
        for change in changes:
            if change['plugin']:
                print('\	[{}]: mult: {:.2f}, \	{}'.format(change['plugin'].name, change['intensityMult'], change['colorMult']))
                if change['plugin'].getName() == 'LSCeilingLight':
                    # Apply the change to the actual light plugin and mark it as applied, so it will be reset in the VFB.
                    # Note: You will need to keep track of which lights are in which light select render elements.
                    light_rect = r.plugins['VRayLightRectShape1']
                    # Don't forget the changes are multipliers, not overrides.
                    light_rect.color *= change['colorMult']
                    light_rect.intensity *= change['intensityMult']
                    # Mark this change as applied.
                    change['isApplied'] = True
            else:
                # The plugin being empty, means that it's the special "Rest" channel.
                # It contains all the lights that were not added in other light selects.
                print('\	[Rest]: mult: {:.2f}, \	{}'.format(change['intensityMult'], change['colorMult']))
        # Save the image with the corrections applied.
        r.vfb.saveImage('lightmix_vfb.png', {'singleChannel':True, 'applyColorCorrections':True})
        # Notify the main thread that the callback is done.
        event.set()
    # Set the callback
    renderer.setOnLightMixTransferToScene(lightMixTransfer)

    # Avoid getting stuck if VFB is closed
    def vfbClosed(r, _):
        r.stop()
        event.set()
    renderer.setOnVFBClosed(vfbClosed)

    # Start rendering
    renderer.startSync()
    print('Choose Source: LightMix from the layers panel and change the color and intensity of the lights.\
')
    print('Please note, that those are multipliers, not overrides.\
')
    print('When you are done, stop the rendering (if it hasn\'t completed) from the VFB button')
    print('and press the "To Scene" button. This will call the callback function.\
')
    print('Note: The LC pass must end, before the Light Select render elements take effect.\
')
    # Wait for the callback to be executed
    event.wait()
    # Start rendering again, this time with some of the changes applied to the lights in the scene
    renderer.startSync()
    renderer.vfb.shown=1
    print("\
Now, some of the changes are applied to the scene and reset in the LightMix layer.")
    print("The rendered image should look the same.")
    # Wait for rendering to end.
    renderer.waitForRenderEnd()
    # Save the new image.
    renderer.vfb.saveImage('lightmix_scene.png', {'singleChannel':True, 'applyColorCorrections':True})
```
</details>

<details>
<summary>C++</summary>

```c++
#define VRAY_RUNTIME_LOAD_PRIMARY
#include <condition_variable>
#include "vraysdk.hpp"
#include "vrayplugins.hpp"
#include "utils.h"

using namespace VRay;
using namespace VRay::Plugins;
using namespace std;

const char *BASE_PATH = getenv("VRAY_SDK");
string SCENE_PATH = (BASE_PATH ? string(BASE_PATH) : string(".")) + PATH_DELIMITER + "scenes";
mutex m;
condition_variable cv;

// The transfer to scene callback function.
int onTransferToScene(VRayRenderer& r, const vector<LightMixChange>& changes, double instant, void*) {
	// Save the image with the corrections applied.
	ImageWriterOptions iwo;
	iwo.flags.singleChannel = true;
	iwo.flags.applyColorCorrections = true;
	r.vfb.saveImage("lightmix_vfb.png", iwo);
	printf("Transfer to scene callback called:");
	for (auto& change : changes) {
		// The LightMixChange object contains:
		//    - the render element plugin
		//    - isApplied flag (bool) - This must be set by the user and it will reset the change in the VFB
		//    - enabled flag (bool) - Whether the light select is enabled or not in the VFB. This is *not* reset even when isApplied is true.
		//    - intensity multiplier (float)
		//    - color multiplier (VRay::Color)
		if (change.plugin.isNotEmpty()) {
			printf("\	[%s]: mult: %f.2,\	%s\
", change.plugin.getName(), change.intensityMult, change.colorMult.toString().c_str());
			if (!strcmp(change.plugin.getName(), "LSCeilingLight")) {
				// Apply the change to the actual light plugin and mark it as applied, so it will be reset in the VFB.
				// Note: You will need to keep track of which lights are in which light select render elements.
				LightRectangle light_rect = r.getPlugin<LightRectangle>("VRayLightRectShape1");
				// Don't forget the changes are multipliers, not overrides.
				light_rect.set_color(light_rect.get_color() * AColor(change.colorMult));
				light_rect.set_intensity(light_rect.get_intensity() * change.intensityMult);
				// Mark this change as applied.
				change.isApplied = true;
			}
		}
		// The plugin being empty, means that it's the special "Rest" channel.
		// It contains all the lights that were not added in other light selects.
		else
			printf("\	[Rest]\
");
	}
	// Notify the main thread that the callback is complete.
	cv.notify_all();
	return 0;
}

// On VFB closed callback function.
void onVfbClosed(VRayRenderer& r, double instant, void*) {
	r.stop();
	cv.notify_all();
}

int main() {
	// Change process working directory to SCENE_PATH in order to be able to load relative scene resources.
	changeCurrentDir(SCENE_PATH.c_str());
	VRayInit init(NULL, true);
	VRayRenderer renderer;
	// It's recommended to always have a console log, but we will not set it for this example
	// Set the transfer to scene callback. Called when the "To Scene" button is pressed in the VFB
	renderer.setOnLightMixTransferToScene(onTransferToScene);
	// Avoid getting stuck if VFB is closed
	renderer.setOnVFBClosed(onVfbClosed);
	// Load a scene from file.
	renderer.load("cornell_new.vrscene");
	// Add the LightMix plugin. No need to keep the reference, because you can't do anything with this plugin.
	// It just has to exist in the scene.
	renderer.newPlugin<RenderChannelLightMix>();
	// Environment light select
	RenderChannelLightSelect ls_env = renderer.newPlugin<RenderChannelLightSelect>("LSEnvironment");
	ls_env.set_light_select_mode(10); // 10 is a special, undocumented value used for environment light
	ls_env.set_name("Environment");
	// Self illumination light select
	RenderChannelLightSelect ls_self = renderer.newPlugin<RenderChannelLightSelect>("LSSelfIllumination");
	ls_self.set_light_select_mode(11); // 11 is a special, undocumented value used for self illumination light
	ls_self.set_name("Self Illum.");
	// A full light light select
	RenderChannelLightSelect ls_light = renderer.newPlugin<RenderChannelLightSelect>("LSCeilingLight");
	ls_light.set_light_select_mode(4); // full light (direct + indirect)
	ls_light.set_name("Celiling Light");
	// Adding a light to a light select
	LightRectangle light_rect = renderer.getPlugin<LightRectangle>("VRayLightRectShape1");
	light_rect.set_channels_full({ Value(ls_light) });
	// Start rendering
	renderer.startSync();
	printf("Choose Source: LightMix from the layers panel and change the color and intensity of the lights.\
\
");
	printf("Please note, that those are multipliers, not overrides.\
\
");
	printf("When you are done, stop the rendering (if it hasn't completed) from the VFB button\
");
	printf("and press the \"To Scene\" button. This will call the callback function.\
\
");
	printf("Note: The LC pass must end, before the Light Select render elements take effect.\
");
	// Wait for the callback to complete.
	// This can only happen after the rendering is stopped, because the button is disabled while rendering.
	{
		unique_lock<mutex> lk(m);
		cv.wait(lk);
	}
	printf("\
Now, some of the changes are applied to the scene and reset in the LightMix layer.\
");
	printf("The rendered image should look the same.\
");
	// Render again, this time with the lights changed in the scene.
	renderer.startSync();
	renderer.vfb.show(true);
	renderer.waitForRenderEnd();
	// Save the image with the corrections applied.
	ImageWriterOptions iwo;
	iwo.flags.singleChannel = true;
	iwo.flags.applyColorCorrections = true;
	renderer.vfb.saveImage("lightmix_scene.png", iwo);

	return 0;
}
```
</details>

<details>
<summary>C#.NET</summary>

```csharp
using System;
using System.IO;
using System.Threading;
using System.Collections.Generic;
using VRay;
using VRay.Plugins;

namespace _09_lightmix
{
	class Program
	{
		static void Main(string[] args)
		{
			AutoResetEvent autoResetEvent = new AutoResetEvent(false);
			string SCENE_PATH = Path.Combine(Environment.GetEnvironmentVariable("VRAY_SDK"), "scenes");
			// Change process working directory to SCENE_PATH in order to be able to load relative scene resources.
			Directory.SetCurrentDirectory(SCENE_PATH);
			// Create an instance of VRayRenderer with default options. The renderer is automatically closed after the `using` block.
			using (VRayRenderer renderer = new VRayRenderer())
			{
				// It's usually a good idea to have a listener for any type of log message, but we will not add one for this example.
				ImageWriterOptions iwo = new ImageWriterOptions();
				iwo.SingleChannel = true;
				iwo.ApplyColorCorrections = true;
				// Avoid getting stuck if VFB is closed
				renderer.VFBClosed += new EventHandler<VRayEventArgs>((source, e) =>
				{
					renderer.Stop();
					autoResetEvent.Set();
				});
				renderer.LightMixTransferToScene += new EventHandler<LightMixTransferToSceneEventArgs>((source, e) =>
				{
					// Save the image with the corrections applied.
					renderer.Vfb.SaveImage("lightmix_vfb.png", iwo);
					Console.WriteLine("Transfer to scene callback called:");
					foreach (var change in e.Changes)
					{
						// The LightMixChange object contains:
						//    - The render element plugin
						//    - IsApplied flag (bool) - This must be set by the user and it will reset the change in the VFB
						//    - Enabled flag (bool) - Whether the light select is enabled or not in the VFB. This is *not* reset even when isApplied is true.
						//    - Intensity multiplier (float)
						//    - Color multiplier (VRay::Color)
						if (change.Plugin != null)
						{
							Console.WriteLine(String.Format("\	[{0}]: mult: {1:F2},\	{2}", change.Plugin.GetName(), change.IntensityMult, change.ColorMult.ToString()));
							if (change.Plugin.GetName() == "LSCeilingLight")
							{
								// Apply the change to the actual light plugin and mark it as applied, so it will be reset in the VFB.
								// Note: You will need to keep track of which lights are in which light select render elements.
								LightRectangle lightRect = renderer.GetPlugin<LightRectangle>("VRayLightRectShape1");
								// Don't forget the changes are multipliers, not overrides.
								lightRect.Color = lightRect.Color * new AColor(change.ColorMult, 1);
								lightRect.Intensity = lightRect.Intensity * change.IntensityMult;
								// Mark this change as applied.
								change.IsApplied = true;
							}
						}
						// The plugin being empty, means that it's the special "Rest" channel.
						// It contains all the lights that were not added in other light selects.
						else
							Console.WriteLine("\	[Rest]\
");
					}
					// Notify the main thread that the callback is complete.
					autoResetEvent.Set();
				});
				// Load scene from a file.
				renderer.Load("cornell_new.vrscene");
				// Add the LightMix plugin. No need to keep the reference, because you can't do anything with this plugin.
				// It just has to exist in the scene.
				renderer.NewPlugin<RenderChannelLightMix>();
				// Environment light select
				RenderChannelLightSelect ls_env = renderer.NewPlugin<RenderChannelLightSelect>("LSEnvironment");
				ls_env.LightSelectMode = 10; // 10 is a special, undocumented value used for environment light
				ls_env.SetName("Environment");
				// Self illumination light select
				RenderChannelLightSelect ls_self = renderer.NewPlugin<RenderChannelLightSelect>("LSSelfIllumination");
				ls_self.LightSelectMode = 11; // 11 is a special, undocumented value used for self illumination light
				ls_self.SetName("Self Illum.");
				// A full light light select
				RenderChannelLightSelect ls_light = renderer.NewPlugin<RenderChannelLightSelect>("LSCeilingLight");
				ls_light.LightSelectMode = 4; // full light (direct + indirect)
				ls_light.SetName("Celiling Light");
				// Adding a light to a light select
				LightRectangle light_rect = renderer.GetPlugin<LightRectangle>("VRayLightRectShape1");
				light_rect.ChannelsFull = new List<object>() { ls_light };
				// Start rendering.
				renderer.StartSync();
				Console.WriteLine("Choose Source: LightMix from the layers panel and change the color and intensity of the lights.\
");
				Console.WriteLine("Please note, that those are multipliers, not overrides.\
");
				Console.WriteLine("When you are done, stop the rendering (if it hasn't completed) from the VFB button");
				Console.WriteLine("and press the \"To Scene\" button. This will call the callback function.\
");
				Console.WriteLine("Note: The LC pass must end, before the Light Select render elements take effect.\
");
				// Wait for the callback to complete.
				// This can only happen after the rendering is stopped, because the button is disabled while rendering.
				autoResetEvent.WaitOne();
				Console.WriteLine("\
Now, some of the changes are applied to the scene and reset in the LightMix layer.");
				Console.WriteLine("The rendered image should look the same.");
				// Render again, this time with the lights changed in the scene.
				renderer.StartSync();
				renderer.Vfb.Shown = true;
				renderer.WaitForRenderEnd();
				renderer.Vfb.SaveImage("lightmix_scene.png", iwo);
			}
		}
	}
}
```
</details>

<details>
<summary>Node.js</summary>

```javascript
var path = require('path');
var vray = require(path.join(process.env.VRAY_SDK, 'node', 'vray'));

var SCENE_PATH = path.join(process.env.VRAY_SDK, 'scenes');
// Change process working directory to SCENE_PATH in order to be able to load relative scene resources.
process.chdir(SCENE_PATH);

// Create an instance of VRayRenderer.
var renderer = vray.VRayRenderer();
// It's recommended to always have a console log callback but we will not add one for this example.

// Close the renderer when VFB is closed.
renderer.on("vfbClosed", function(instant) {
	// This call is mandatory in order to free up the event loop.
	// The renderer object is unusable after closing since its resources
	// are freed. It should be released for garbage collection.
	renderer.close();
});

renderer.on("lightMixTransferToScene", function(changes, count) {
	// Each LightMixChange object contains:
	//    - the render element plugin
	//    - isApplied flag (bool) - This must be set by the user and it will reset the change in the VFB
	//    - enabled flag (bool) - Whether the light select is enabled or not in the VFB. This is *not* reset even when isApplied is true.
	//    - intensity multiplier (float)
	//    - color multiplier (VRay::Color)
	changes.forEach(change => {
		if (change.plugin != null) {
			console.log(`\	[${change.plugin.name}]: mult: ${change.intensityMult.toFixed(2)}, \	${change.colorMult}`);
			if (change.plugin.getName() == "LSCeilingLight") {
				// Apply the change to the actual light plugin and mark it as applied, so it will be reset in the VFB.
				// Note: You will need to keep track of which lights are in which light select render elements.
				light_rect = renderer.plugins["VRayLightRectShape1"];
				// Don't forget the changes are multipliers, not overrides.
				light_rect.color = light_rect.color.mul(vray.AColor(change.colorMult));
				light_rect.intensity *= change.intensityMult;
				// Mark this change as applied.
				change.isApplied = true;
			}
		}
		else {
			// The plugin being empty, means that it's the special "Rest" channel.
			// It contains all the lights that were not added in other light selects.
			console.log(`\	[Rest]: mult: ${change.intensityMult.toFixed(2)}, \	${change.colorMult}`);
		}
	});
	// Save the image with the corrections applied.
	renderer.vfb.saveImageSync("lightmix_vfb.png", {singleChannel: true, applyColorCorrections: true});
	// Render again, this time with the lights changed in the scene.
	setTimeout(afterCallback, 0);
});

// Load scene from a file asynchronously.
renderer.load("cornell_new.vrscene", function(err) {
	if (err) { throw err; } // Scene was not loaded.
	// Add the LightMix plugin. No need to keep the reference, because you can't do anything with this plugin.
	// It just has to exist in the scene.
	renderer.classes.RenderChannelLightMix();
	// Environment light select
	ls_env = renderer.classes.RenderChannelLightSelect("LSEnvironment");
	ls_env.light_select_mode = 10; // 10 is a special, undocumented value used for environment light
	ls_env.name = "Environment";
	// Self illumination light select
	ls_self = renderer.classes.RenderChannelLightSelect("LSSelfIllumination");
	ls_self.light_select_mode = 11; // 11 is a special, undocumented value used for self illumination light
	ls_self.name = "Self Illum.";
	// A full light light select
	ls_light = renderer.classes.RenderChannelLightSelect("LSCeilingLight");
	ls_light.light_select_mode = 4; // full light (direct + indirect)
	ls_light.name = "Ceiling Light";
	// Adding a light to a light select
	light_rect = renderer.plugins["VRayLightRectShape1"]
	light_rect.channels_full = [ ls_light ];
	// Start rendering.
	renderer.start(function(err) {
		if (err) { throw err; } // Couldn't start rendering.
		console.log("Choose Source: LightMix from the layers panel and change the color and intensity of the lights.\
");
		console.log("Please note, that those are multipliers, not overrides.\
");
		console.log("When you are done, stop the rendering (if it hasn't completed) from the VFB button");
		console.log("and press the \"To Scene\" button. This will call the callback function.\
");
		console.log("Note: The LC pass must end, before the Light Select render elements take effect.\
");
	});
});

function afterCallback() {
	renderer.start(function(err) {
		if (err) { throw err; } // Couldn't start rendering.
		console.log("\
Now, some of the changes are applied to the scene and reset in the LightMix layer.");
		console.log("The rendered image should look the same.");
		renderer.waitForRenderEnd(function() {
			// Save the new image.
			renderer.vfb.saveImageSync("lightmix_scene.png", {singleChannel: true, applyColorCorrections: true});
			// Close the renderer.
			renderer.close();
		});
	});
}
```
</details>

### Other callbacks

<details>
<summary>Python</summary>

```python
def onRenderLast(renderer, isRendering, instant):
    print('Starting rendering at:', instant)
    renderer.startSync()

def onRenderInteractive(renderer, isRendering, instant):
    print('Starting Interactive rendering at:', instant)
    oldRenderMode = renderer.renderMode
    renderer.renderMode = 'interactive'
    renderer.startSync()
    renderer.renderMode = oldRenderMode # resetting the renderMode after the rendering has started will not affect the current rendering process

def onShowVFBLog(renderer, instant):
    renderer.vfb.logMessage(vray.LOGLEVEL_INFO, 'VFB Log opened')

def onVFBClosed(renderer, instant):
    renderer.stop()

# called when the Render button or menu action is pressed. If not set, pressing Render will start rendering (like calling renderer.start())
renderer.setOnVFBRenderLast(onRenderLast) 
# called when the Start Interactive Render button or menu action is pressed. Requires showVfbButtonInteractiveStart to be True
renderer.setOnVFBRenderInteractive(onRenderInteractive) 
# called when the VFB Log tab is opened
renderer.setOnVFBShowMessagesWindow(onShowVFBLog)
# called when the VFB window is closed
renderer.setOnVFBClosed(onVFBClosed)
```
</details>

<details>
<summary>C++</summary>

```c++
#define VRAY_RUNTIME_LOAD_PRIMARY
#include "vraysdk.hpp"
#include "utils.h"
using namespace VRay;
using namespace std;

const char *BASE_PATH = getenv("VRAY_SDK");
string SCENE_PATH = (BASE_PATH ? string(BASE_PATH) : string(".")) + PATH_DELIMITER + "scenes";

void onRenderLast(VRayRenderer& renderer, bool isRendering, double instant, void* userData) {
	printf("Starting rendering at: %f\
", instant);
	renderer.startSync();
}
void onRenderInteractive(VRayRenderer& renderer, bool isRendering, double instant, void* userData) {
	printf("Starting Interactive rendering at: %f\
", instant);
	VRayRenderer::RenderMode oldRenderMode = renderer.getRenderMode();
	renderer.setRenderMode(VRayRenderer::RENDER_MODE_INTERACTIVE);
	renderer.startSync();
	renderer.setRenderMode(oldRenderMode); // resetting the renderMode after the rendering has started will not affect the current rendering process
}
void onShowVFBLog(VRayRenderer& renderer, double instant, void* userData) {
	renderer.vfb.logMessage(MessageInfo, "VFB Log opened");
}
void onVFBClosed(VRayRenderer& renderer, double instant, void* userData) {
	renderer.stop();
}

int main() {
	// Change process working directory to SCENE_PATH in order to be able to load relative scene resources.
	changeCurrentDir(SCENE_PATH.c_str());
	// Load V-Ray SDK library.
	VRayInit init(NULL, true);
	// The renderer is automatically closed at the end of the current scope.
	VRayRenderer renderer;
	// called when the Render button or menu action is pressed. If not set, pressing Render will start rendering (like calling renderer.start())
	renderer.setOnVFBRenderLast(onRenderLast);
	// called when the Start Interactive Render button or menu action is pressed. Requires showVfbButtonInteractiveStart to be true
	renderer.setOnVFBInteractiveStart(onRenderInteractive);
	// called when the VFB Log tab is opened
	renderer.setOnVFBShowMessagesWindow(onShowVFBLog);
	// called when the VFB window is closed
	renderer.setOnVFBClosed(onVFBClosed);
	// Load scene from a file.
	renderer.load("cornell_new.vrscene");
	// Start rendering.
	renderer.startSync();
	// Wait until rendering has finished.
	renderer.waitForRenderEnd();
	return 0;
}
```
</details>

<details>
<summary>C#.NET</summary>

```csharp
using System;
using System.IO;
using VRay;

namespace _other_vfb_callbacks
{
	class Program
	{
		static void Main(string[] args)
		{
			string SCENE_PATH = Path.Combine(Environment.GetEnvironmentVariable("VRAY_SDK"), "scenes");
			// Change process working directory to SCENE_PATH in order to be able to load relative scene resources.
			Directory.SetCurrentDirectory(SCENE_PATH);
			// Create an instance of VRayRenderer with default options. The renderer is automatically closed after the `using` block.
			using (VRayRenderer renderer = new VRayRenderer())
			{
				// called when the Render button or menu action is pressed. If not set, pressing Render will start rendering (like calling renderer.Start())
				renderer.VFBRenderLast += new EventHandler<RenderLastEventArgs>((source, e) =>
				{
					Console.WriteLine("Starting rendering at: {0}", e.Instant);
					renderer.StartSync();
				});
				// called when the Start Interactive Render button or menu action is pressed. Requires ShowVfbButtonInteractiveStart to be true
				renderer.VFBRenderInteractive += new EventHandler<RenderInteractiveEventArgs>((source, e) =>
				{
					Console.WriteLine("Starting Interactive rendering at: {0}", e.Instant);
					RenderMode oldRenderMode = renderer.RenderMode;
					renderer.RenderMode = RenderMode.INTERACTIVE;
					renderer.StartSync();
					renderer.RenderMode = oldRenderMode; // resetting the RenderMode after the rendering has started will not affect the current rendering process
				});
				// called when the VFB Log tab is opened
				renderer.VFBShowMessagesWindow += new EventHandler<VRayEventArgs>((source, e) =>
				{
					renderer.Vfb.LogMessage(LogLevelType.Info, "VFB Log opened");
				});
				// called when the VFB window is closed
				renderer.VFBClosed += new EventHandler<VRayEventArgs>((source, e) =>
				{
					renderer.Stop();
				});
				// Load scene from a file.
				renderer.Load("cornell_new.vrscene");
				// Start rendering.
				renderer.StartSync();
				// Wait until rendering has finished.
				renderer.WaitForRenderEnd();
			}
		}
	}
}
```
</details>

<details>
<summary>Node.js</summary>

```javascript
 // called when the Render button or menu action is pressed. If not set, pressing Render will start rendering (like calling renderer.start())
renderer.on("vfbRenderLast", function(isRendering, instant) {
	console.log("Starting rendering at: ", instant);
	renderer.startSync();
});
// called when the Start Interactive Render button or menu action is pressed. Requires showVfbButtonInteractiveStart to be true
renderer.on("vfbRenderInteractive", function(isRendering, instant) {
	console.log("Starting Interactive rendering at:", instant);
	var oldRenderMode = renderer.renderMode;
	renderer.renderMode = "interactive";
	renderer.startSync();
	renderer.renderMode = oldRenderMode; // resetting the renderMode after the rendering has started will not affect the current rendering process
});
// called when the VFB Log tab is opened
renderer.on("vfbShowMessagesWindow", function(instant) {
	renderer.vfb.logMessage(vray.LOGLEVEL_INFO, "VFB Log opened");
});
// called when the VFB window is closed
renderer.on("vfbClosed", function(instant) {
	renderer.stop();
	// Closes the renderer. This call is mandatory in order to free up the event loop.
	// The renderer object is unusable after closing since its resources are freed. 
	// It should be released for garbage collection.
	renderer.close();
});
```
</details>

## **RendererOptions**

---

- `enableFrameBuffer `- (default: true) Controls whether the VFB will be used by this renderer. Notice that this is different from the global `enableFrameBuffer` function that disables the V-Ray GUI for the whole life of the process.
- `showFrameBuffer `- (default: true) Controls whether the VFB is shown when rendering starts. It can still be shown later through the VFB API.
- `noRenderLicensePreCheck `- (default: false) - By default creating a V-Ray renderer engages an AppSDK license and also very briefly engages a render license and releases it in order to be able to return a license error early. You can disable this pre-check with this flag for example to reduce network communication.
- `useDefaultVfbTheme `- (default: true) If set to false the VFB theme is ignored and the parent application theme is inherited.
- `showVfbButtonInteractiveStart `-* *(default: false) - Show an additional Start Interactive Rendering button and menu action. When pressed, calls a user callback (does not start rendering by default).
- `previewRenderer `- (default: false) Optimize the renderer for small preview purposes. Should not be used for production.
- `allowInvalidCharactersInPluginNames `- (default: false) - Allow the use of invalid characters in plugin names.
- `dockFrameBuffer `- (default: false) - Dock the VFB window
- `hideToSceneButton `- (default: false) - Hide the Light Mix transfer `<To Scene>` button in VFB. If you don't plan on implementing that functionality, it's a good idea to hide the button (otherwise it will always be disabled).
- `useVfbLog `- (default: true) - Use the built-in VFB log
- `pluginLibraryPath `- This can be used optionally to define a non-default path for loading V-Ray [plugins](https://docs-chaos.atlassian.net/wiki/spaces/APPSDK/pages/132811190). Most users won't need to set this. It allows multiple files to be specified.
- `vfbDrawStyle `- This enum controls the style and colors of the VFB GUI. The available styles are those of the V-Ray Standalone product as well as V-Ray for 3dsMax and V-Ray for Maya.