©Anton Podvalny

Table of Contents

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.

 

 

  • No labels