©Anton Podvalny

Introduction


In this chapter, we'll discuss Gaussian Splats. 3D Gaussian Splatting is a method used to create a 3D scene from images or videos. It requires several pictures of an object, each taken from a different angle. With Gaussian Splatting, the images are blended to produce a detailed, three-dimensional representation of the object. Instead of depicting the scene as a collection of meshes, a Gaussian splat represents the scene as a type of point cloud, where each point is a 3D Gaussian.

Gaussian splats help you create a realistic environment for your scenes.

This feature is not yet available in V-Ray GPU. 


Gaussian Splat Usage


Raytracing a cloud of 3D Gaussians is accessible via the geometry source plugin called GeomGaussians.


Used as Extended Environment

One use of Gaussian splats is to represent an environment, typically generated from photos or videos of the scene.

There are advantages over the traditional environment maps, including proper parallax and view-dependent effects and the ability for Gaussian splats to occlude other objects in the scene.

For Gaussian splats to work as environments in V-Ray, the affect_matte_surfaces option should be enabled, and the casts_shadows option should usually be disabled.

See this example for more information.


On Other Matte Surfaces

To make the Gaussian Splats rendered as part of the background, i.e., visible on other matte objects even if they are behind them. This is achieved by enabling the affect_matte_surfaces option from the Gaussian splats parameters.

See this example for more information.


As Matte Objects

Gaussian splats can also function as holdout (matte) objects, i.e. appear correctly in reflections and refractions and occlude other objects in the scene but do not contribute to the RGB and alpha channels of the final image.

This can be achieved through the  VRayObjectProperties plugin. Assign a VRayObjectProperties to a Gaussian splats object, enable the matte_surface option, and set its alpha_contribution to -1.0. Make sure that no_GI_on_other_mattes is enabled.


Used as Individual Objects

Gaussian splats can also be used to represent smaller individual objects in the scene. In that case, the affect_matte_surfaces option typically is turned off, and the casts_shadows option is enabled. The latter is needed so that the Gaussian splats can cast proper shadows on other objects in the scene.

Note that the lighting and reflections are baked into the Gaussian splats object, and therefore these objects are not affected by the scene lighting.

See the examples for more information.


Parameters

The following parameters reside in the GeomGaussians plugin.


  • file – loads the Gaussian splats file. Currently, only .ply files are accepted.

  • flip_axis - when set to 1, performs a rotation of (-90) degrees around the X axis. When set to 2, performs a 90 degrees rotation around the Y axis and flips the Y axis.

0 – As Is
1 – Rotate YZ
2 – Rotate XZ + Flip Y

  • scale – scales the Gaussian splats up and down. See the example.

  • affect_camera – specifies whether the Gaussian splats should be visible to the camera. See the example.

  • affect_shadows – when enabled, Gaussian splats block shadows from lights. When disabled, the Gaussian splats become transparent to shadow and GI rays. It is recommended that this option be turned off when using the Gaussian splats as environment or individual objects. See the example.
  • affect_reflections – specifies whether the Gaussian splats should be visible in reflections. See the example.

  • affect_refractions – specifies whether the Gaussian splats should be visible in refractions. See the example.

  • affect_matte_surfaces – when enabled, Gaussian splats appear as part of the background on matte surfaces. It is recommended to enable this for Gaussian splats used as an environment and disable it for Gaussian splats used as individual objects. See the example.

  • rgb_color_space - specifies the color space of the data in the Gaussian splats file.

0 – Default
1 – sRGB
2 – ACEScg
3 – RAW

  • intensity – increases or decreases the Color multiplier for the Gaussian splat.

  • color – specifies a filter color for the splat. By default, the Color is white, which does not affect the splat. See the example.



Example: scale

This example shows Gaussian Splat used as an individual object - the pink flamingo floatable in this scene. It can be scaled as any other object in the scene, using the scale parameter.


scale = 0.5

scale = 1

scale = 1.5




Example: affect_camera

The Gaussian Splat object can be hidden from the camera, like any other geometry object in the scene, by using the affect_camera option.


On Before image
Off After image



Example: affect_reflections

The affect_reflections option controls if the Gaussian Splat object is reflected in other objects in the scene.


On Before image
Off After image



Example: affect_refractions

The affect_refractions option makes the Gaussian Splat object seen by other objects in the scene that exhibit refractive properties.


On Before image
Off After image



Example: affect_shadows

This example shows how the pink flamingo can produce shadows when the affect_shadows option is enabled, and doesn't block light when it's not.


On Before image
Off After image



Example: affect_matte_surfaces

In this example, the Gaussian Splat is used as an environment. The left building in the rendering that casts shadows over the plane, is a Cosmos asset (mesh).

When the affect_matte_surfaces option is enabled, the Gaussian Splat is considered as background and receives shadows from the casting object.


On Before image
Off After image



Example: color

The color shown on each render as a box is used as a filter for the original Gaussian Splat diffuse color.




Code Example


With the following API, an integrator could read the gaussian data from a file or GeomGaussians plugin, and a preview of the model could be generated using the bounding box, point cloud, or another method.

The .vrscene file used in this example can be found in your installation_directory/scenes/geom folder.

# 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(VRAY_SDK, 'scenes', 'geom')
# 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("gaussians_flowers.vrscene")

    # With the following API the gaussian data could be read and a preview of the model
    # could be generated using the bounding box, point cloud or another method
    previewBoundingBox, positions, colors = vray.GeomUtils.readGaussianData(renderer.plugins["flowers"])
    numPrimitives = len(positions)
    for i in range(numPrimitives):
        position = positions[i]
        color = colors[i]

    # Start rendering.
    renderer.startSync()

    # Wait for rendering to end.
    renderer.waitForRenderEnd()
#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" + PATH_DELIMITER + "geom";

int main(int argc, char* argv[]) {
	// 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("gaussians_flowers.vrscene");

	// With the following API the gaussian data could be read and a preview of the model
	// could be generated using the bounding box, point cloud or another method
	GaussianReadData readData;
	GeomUtils::readGaussianData(renderer.getPlugin("flowers"), readData);
	Box previewBoundingBox = readData.getPreviewBoundingBox();
	const unsigned numPrimitives = readData.getGaussianPrimitivesCount();
	for (unsigned i = 0; i < numPrimitives; i++) {
		Vector position = readData.getPosition(i);
		Color color = readData.getAverageColor(i);
	}

	// Start rendering.
	renderer.startSync();
	// Wait for rendering to end.
	renderer.waitForRenderEnd();
	return 0;
}
using System;
using System.IO;
using VRay;
using static VRay.Proxy;

class Program
{
    static void Main(string[] args)
    {
        string SCENE_PATH = Path.Combine(Environment.GetEnvironmentVariable("VRAY_SDK"), "scenes", "geom");
        // 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("gaussians_flowers.vrscene");

            // With the following API the generated scatter transforms and topology could be read
            // and applied to various forms (dots, bounding box, low-poly model, etc.) as a preview
            GeomUtils.GaussianReadData readData = GeomUtils.ReadGaussianData(renderer.GetPlugin("flowers"));
            Box previewBoundingBox = readData.GetPreviewBoundingBox();
            long numPrimitives = readData.GetGaussianPrimitivesCount();
            for (long i = 0; i < numPrimitives; i++)
            {
                Vector position = readData.GetPosition(i);
                Color color = readData.GetAverageColor(i);
            }

            // 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", "geom");
// 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("gaussians_flowers.vrscene", function(err) {
	if (err) throw err;

	// With the following API the gaussian data could be read and a preview of the model
	// could be generated using the bounding box, point cloud or another method
	var readData = vray.GeomUtils.readGaussianDataSync(renderer.plugins["flowers"]);
	var previewBoundingBox = readData.bbox;
	var numPrimitives = readData.positions.count;
	for (var i = 0; i < numPrimitives; i++) {
		var position = readData.positions.getVector(i);
		var color = readData.colors.getColor(i);
	}

	// Start rendering.
	renderer.start(function(err) {
		if (err) throw err;
		// Wait for rendering to end.
		renderer.waitForRenderEnd(function() {
			// Closes the renderer.
			// The renderer object is unusable after closing since its resources
			// are freed. It should be released for garbage collection.
			renderer.close();
		});
	});
});


Notes


  • Gaussian splats work in V-Ray by assuming they are composed over a black background. For proper rendering, the scene background should be black, and any dome lights used for illumination should be set to invisible.
  • While you can load multiple Gaussian splat files and they are rendered correctly with respect to one another depending on their position in space, intersecting Gaussian splats might produce undefined or wrong results. It is not recommended to intersect them, as they are designed for a single point cloud.
  • No labels
Was this helpful?