Introduction
In this chapter we'll talk about geometry clipping. VRayClipper is a geometric primitive that can be used to clip away parts of the scene with a simple plane. It is a render-time effect and does not modify the actual scene geometry in any way.
Parameters
The plugin which we're interested in is called VRayClipper.
- enabled – turns the clipper effect on and off.
- affect_light – if enabled, the clipper will affect area light sources as well.
- only_camera_rays – the clipper will affect objects as they are directly seen by the camera, but they will appear unchanged to reflection/refraction/GI rays.
- clip_lights – enables or disables the clipping of lights geometry (for example a mesh light).
- use_obj_mtl – when enabled, the clipper will use the material of each clipped object to fill in the resulting holes. When this is off, the material applied to the clipper object itself will be used.
- set_material_id – when enabled, you can specify a face material ID for the clipper object. You can then use this ID inside a Multi/Sub-object material to specify a different filler material for different objects.
- material_id – the face material ID for the clipped surfaces when Set material ID is enabled.
invert_inside - determines how to use the mesh when Mesh mode is enabled:
- 0 - Intersection - clips away anything that is outside the specified mesh; only render objects and parts of objects inside the specified mesh;
- 1 - Subtraction - clips away anything inside the specified mesh; only render objects and parts of objects outside of the specified mesh.
exclusion_nodes – an include/exclude list that allows you to select which scene objects will be clipped.
- exclusion_mode - false to include the nodes listed, true to exclude the nodes listed.
- clip_mesh - Mesh plugin to use as a clipping mesh instead of the simple plane
Example
The following scenes are rendered by using this scene bundle.
Clipper Exclude
Clipper Mesh
Clipper
Clipper Plane
# 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 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) # Create an instance of VRayRenderer with default options. The renderer is automatically closed after the `with` block. with vray.VRayRenderer() as renderer: # Register a simple log callback. Always useful for debugging. def dumpMsg(renderer, message, level, instant): if level == vray.LOGLEVEL_ERROR: print("[ERROR]", message) elif level == vray.LOGLEVEL_WARNING: print("[Warning]", message) elif level == vray.LOGLEVEL_INFO: print("[info]", message) # Uncomment for testing, but you might want to ignore these in real code #else: print("[debug]", message) renderer.setOnLogMessage(dumpMsg) # Load scene from a file. renderer.load(os.path.join(SCENE_PATH, 'cornell_new.vrscene')) # Create a VRayClipper plugin clipper = renderer.classes.VRayClipper() # Don't assign a node to get mesh from; clip against a plane instead # Enable the clipper clipper.enabled = True # List of exclusion nodes exclusionNodes = [ renderer.plugins['Sphere0Shape1@node'], renderer.plugins['Sphere0Shape4@node'] ] clipper.exclusion_nodes = exclusionNodes # Exclude the nodes from the list; all other nodes will be clipped clipper.exclusion_mode = True # Perform subtraction clipper.invert_inside = 1 # Attach the blue material clipper.material = renderer.plugins['Blue_Mtl@mtlsingle'] # Assign a transform to the clipper plane clipper.transform = vray.Transform(vray.Matrix(vray.Vector(1, 0, 0), vray.Vector(0, 0.5, 0.87), vray.Vector(0, -0.87, 0.5)), vray.Vector(0, 20, 0)) # Start rendering. renderer.startSync() # Wait for rendering to end. renderer.waitForRenderEnd()
#define VRAY_RUNTIME_LOAD_PRIMARY #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"; 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); // Create an instance of VRayRenderer with default options. // The renderer is automatically closed at the end of the current scope. VRayRenderer renderer; // It's recommended to always have a console log renderer.setOnLogMessage(logMessage); // Load scene from a file. renderer.load("cornell_new.vrscene"); // Create a VRayClipper plugin VRayClipper clipper = renderer.newPlugin<VRayClipper>(); // Don't assign a node to get mesh from; clip against a plane instead // Enable the clipper clipper.set_enabled(true); // List of exclusion nodes ValueList exclusionNodes; exclusionNodes = { Value(renderer.getPlugin("Sphere0Shape1@node")), Value(renderer.getPlugin("Sphere0Shape4@node")) }; clipper.set_exclusion_nodes(exclusionNodes); // Exclude the nodes from the list; all other nodes will be clipped clipper.set_exclusion_mode(true); // Perform subtraction clipper.set_invert_inside(1); // Attach the blue material clipper.set_material(renderer.getPlugin("Blue_Mtl@mtlsingle")); // Assign a transform to the clipper plane clipper.set_transform(Transform(Matrix(Vector(1, 0, 0), Vector(0, 0.5, 0.87), Vector(0, -0.87, 0.5)), Vector(0, 20, 0))); // Start rendering. renderer.startSync(); // Wait for rendering to end. renderer.waitForRenderEnd(); return 0; }
using System; using System.IO; using System.Collections.Generic; using VRay; using VRay.Plugins; namespace _clipperPlane { 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()) { // Add a listener for any type of log message. renderer.LogMessage += new EventHandler<MessageEventArgs>((source, e) => { // You can remove the if for testing, but you might want to ignore Debug in real code if (e.LogLevel != LogLevelType.Debug) { Console.WriteLine(String.Format("[{0}] {1}", e.LogLevel.ToString(), e.Message)); } }); // Load scene from a file. renderer.Load("cornell_new.vrscene"); // Create a VRayClipper plugin VRayClipper clipper = renderer.NewPlugin<VRayClipper>(); // Don't assign a node to get mesh from; clip against a plane instead // Enable the clipper clipper.Enabled = true; // List of exclusion nodes List<object> exclusionNodes = new List<object> { renderer.GetPlugin("Sphere0Shape1@node"), renderer.GetPlugin("Sphere0Shape4@node") }; clipper.ExclusionNodes = exclusionNodes; // Exclude the nodes from the list; all other nodes will be clipped clipper.ExclusionMode = true; // Perform subtraction clipper.InvertInside = 1; // Attach the blue material clipper.Material = renderer.GetPlugin("Blue_Mtl@mtlsingle"); // Assign a transform to the clipper plane clipper.Transform = new Transform(new Matrix(new Vector(1, 0, 0), new Vector(0, 0.5, 0.87), new Vector(0, -0.87, 0.5)), new Vector(0, 20, 0)); // Start rendering. renderer.StartSync(); // Wait for rendering to end. renderer.WaitForRenderEnd(); } } } }
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 with default options. var renderer = vray.VRayRenderer(); // It's recommended to always have a console log callback renderer.on("logMessage", function(message, level, instant) { if (level == vray.LOGLEVEL_ERROR) console.log("[ERROR] ", message); else if (level == vray.LOGLEVEL_WARNING) console.log("[Warning] ", message); else if (level == vray.LOGLEVEL_INFO) console.log("[info] ", message); // Uncomment for testing, but you might want to ignore these in real code //else console.log("[debug] ", message); }); // Load scene from a file asynchronously. renderer.load("cornell_new.vrscene", function(err) { if (err) throw err; // Create a VRayClipper plugin var clipper = renderer.classes.VRayClipper(); // Don't assign a node to get mesh from; clip against a plane instead // Enable the clipper clipper.enabled = true; // List of exclusion nodes var exclusionNodes = vray.List( renderer.plugins["Sphere0Shape1@node"], renderer.plugins["Sphere0Shape4@node"] ); clipper.exclusion_nodes = exclusionNodes; // Exclude the nodes from the list; all other nodes will be clipped clipper.exclusion_mode = true; // Perform subtraction clipper.invert_inside = 1; // Attach the blue material clipper.material = renderer.plugins["Blue_Mtl@mtlsingle"]; // Assign a transform to the clipper plane clipper.transform = vray.Transform(vray.Matrix(vray.Vector(1, 0, 0), vray.Vector(0, 0.5, 0.87), vray.Vector(0, -0.87, 0.5)), vray.Vector(0, 20, 0)); // Start rendering. renderer.start(function(err) { if (err) throw err; // Wait for rendering to end. renderer.waitForRenderEnd(function() { renderer.close(); }); }); });
Result
Clipper Object
# 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 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) # Create an instance of VRayRenderer with default options. The renderer is automatically closed after the `with` block. with vray.VRayRenderer() as renderer: # Register a simple log callback. Always useful for debugging. def dumpMsg(renderer, message, level, instant): if level == vray.LOGLEVEL_ERROR: print("[ERROR]", message) elif level == vray.LOGLEVEL_WARNING: print("[Warning]", message) elif level == vray.LOGLEVEL_INFO: print("[info]", message) # Uncomment for testing, but you might want to ignore these in real code #else: print("[debug]", message) renderer.setOnLogMessage(dumpMsg) # Load scene from a file. renderer.load(os.path.join(SCENE_PATH, 'cornell_new.vrscene')) clipMesh = renderer.plugins['Sphere0Shape2@node'] updatedTransform = clipMesh.transform # Modify the copy of the clipMesh transform. updatedTransform = updatedTransform.replaceOffset(updatedTransform.offset + vray.Vector(0, -20, 0)) # Update the transform value in clipMesh (applying the changes above). clipMesh.transform = updatedTransform # Create a VRayClipper plugin clipper = renderer.classes.VRayClipper() # Assign a node to get mesh from clipper.clip_mesh = clipMesh # Enable the clipper clipper.enabled = True # List of exclusion nodes exclusionNodes = [ renderer.plugins['FloorShape@node'] ] clipper.exclusion_nodes = exclusionNodes # Include the nodes from the list clipper.exclusion_mode = False # Perform subtraction clipper.invert_inside = 1 # Attach the blue material clipper.material = renderer.plugins['Blue_Mtl@mtlsingle'] # Start rendering. renderer.startSync() # Wait for rendering to end. renderer.waitForRenderEnd()
#define VRAY_RUNTIME_LOAD_PRIMARY #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"; 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); // Create an instance of VRayRenderer with default options. // The renderer is automatically closed at the end of the current scope. VRayRenderer renderer; // It's recommended to always have a console log renderer.setOnLogMessage(logMessage); // Load scene from a file. renderer.load("cornell_new.vrscene"); Node clipMesh = renderer.getPlugin<Node>("Sphere0Shape2@node"); Transform updatedTransform = clipMesh.get_transform(); // Modify the copy of the clipMesh transform. updatedTransform.offset += Vector(0, -20, 0); // Update the transform value in clipMesh (applying the changes above). clipMesh.set_transform(updatedTransform); // Create a VRayClipper plugin VRayClipper clipper = renderer.newPlugin<VRayClipper>(); // Assign a node to get mesh from clipper.set_clip_mesh(clipMesh); // Enable the clipper clipper.set_enabled(true); // List of exclusion nodes ValueList exclusionNodes; exclusionNodes = { Value(renderer.getPlugin("FloorShape@node")) }; clipper.set_exclusion_nodes(exclusionNodes); // Include the nodes from the list clipper.set_exclusion_mode(false); // Perform subtraction clipper.set_invert_inside(1); // Attach the blue material clipper.set_material(renderer.getPlugin("Blue_Mtl@mtlsingle")); // Start rendering. renderer.startSync(); // Wait for rendering to end. renderer.waitForRenderEnd(); return 0; }
using System; using System.IO; using System.Collections.Generic; using VRay; using VRay.Plugins; namespace _clipperMesh { 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()) { // Add a listener for any type of log message. renderer.LogMessage += new EventHandler<MessageEventArgs>((source, e) => { // You can remove the if for testing, but you might want to ignore Debug in real code if (e.LogLevel != LogLevelType.Debug) { Console.WriteLine(String.Format("[{0}] {1}", e.LogLevel.ToString(), e.Message)); } }); // Load scene from a file. renderer.Load("cornell_new.vrscene"); Node clipMesh = renderer.GetPlugin<Node>("Sphere0Shape2@node"); Transform updatedTransform = clipMesh.Transform; // Modify the copy of the clipMesh transform. updatedTransform = updatedTransform.ReplaceOffset(updatedTransform.Offset + new Vector(0, -20, 0)); // Update the transform value in clipMesh (applying the changes above). clipMesh.Transform = updatedTransform; // Create a VRayClipper plugin VRayClipper clipper = renderer.NewPlugin<VRayClipper>(); // Assign a node to get mesh from clipper.ClipMesh = clipMesh; // Enable the clipper clipper.Enabled = true; // List of exclusion nodes List<object> exclusionNodes = new List<object> { renderer.GetPlugin("FloorShape@node") }; clipper.ExclusionNodes = exclusionNodes; // Include the nodes from the list clipper.ExclusionMode = false; // Perform subtraction clipper.InvertInside = 1; // Attach the blue material clipper.Material = renderer.GetPlugin("Blue_Mtl@mtlsingle"); // Start rendering. renderer.StartSync(); // Wait for rendering to end. renderer.WaitForRenderEnd(); } } } }
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 with default options. var renderer = vray.VRayRenderer(); // It's recommended to always have a console log callback renderer.on("logMessage", function(message, level, instant) { if (level == vray.LOGLEVEL_ERROR) console.log("[ERROR] ", message); else if (level == vray.LOGLEVEL_WARNING) console.log("[Warning] ", message); else if (level == vray.LOGLEVEL_INFO) console.log("[info] ", message); // Uncomment for testing, but you might want to ignore these in real code //else console.log("[debug] ", message); }); // Load scene from a file asynchronously. renderer.load("cornell_new.vrscene", function(err) { if (err) throw err; var clipMesh = renderer.plugins["Sphere0Shape2@node"]; var updatedTransform = clipMesh.transform; // Modify the copy of the clipMesh transform. updatedTransform = updatedTransform.replaceOffset(updatedTransform.offset.add(vray.Vector(0, -20, 0))); // Update the transform value in clipMesh (applying the changes above). clipMesh.transform = updatedTransform; // Create a VRayClipper plugin var clipper = renderer.classes.VRayClipper(); // Assign a node to get mesh from clipper.clip_mesh = clipMesh; // Enable the clipper clipper.enabled = true; // List of exclusion nodes var exclusionNodes = vray.List( renderer.plugins["FloorShape@node"] ); clipper.exclusion_nodes = exclusionNodes; // Include the nodes from the list clipper.exclusion_mode = false; // Perform subtraction clipper.invert_inside = 1; // Attach the blue material clipper.material = renderer.plugins["Blue_Mtl@mtlsingle"]; // Start rendering. renderer.start(function(err) { if (err) throw err; // Wait for rendering to end. renderer.waitForRenderEnd(function() { renderer.close(); }); }); });
Result
Notes
- VRayClipper works best with "closed" objects. The results on open objects (without a corresponding back face) are not well defined.
- Currently the VRayClipper may produce artifacts if there are overlapping triangles in the scene, regardless of whether they are part of the same object or not.
- Note that Set material ID must be used for Multi/Sub-object, it will not act like Mtl ID in MultiMatteElement.