Simple reduction - Scripting
In the following example we will continue expanding the script we wrote in Getting Started - Scripting to reduce the selected geometries using a ReductionPipeline with reduction ratio set to 50%.
A quick recap of what we did in 'Getting Started - Scripting' was a Unity C# script that exposes an entry point method as menu item accessible through the Unity menu. The entry point method checks if there is at least one selected item, and if so initializes Simplygon.
The script below is the starting point of this example and we've renamed the menu item to 'SimplygonReductionScript'.
using Simplygon;
using Simplygon.Unity.EditorPlugin;
using System.Linq;
using UnityEditor;
using UnityEngine;
public class SimpleReduction
{
[MenuItem("Simplygon/SimpleReductionScript")]
static void EntryPoint()
{
if (Selection.gameObjects.Length > 0)
{
using (ISimplygon simplygon = global::Simplygon.Loader.InitSimplygon
(out EErrorCodes simplygonErrorCode, out string simplygonErrorMessage))
{
// if Simplygon handle is valid
if (simplygonErrorCode == Simplygon.EErrorCodes.NoError)
{
// Call Simplygon here
}
// if invalid handle, output error message to the Unity console
else
{
Debug.LogError("Simplygon initializing failed!");
}
}
}
}
}
Now that we have Simplygon initialized we need to describe what kind of optimization we want to do. For this example we will do a simple reduction of 50% of the original triangle count. Simplygon API provides Pipelines which encapsulates processing settings and execution functionality. To avoid pure low level API calls we will utilize the ReductionPipeline, it has all the reduction settings we are interested in and is fairly easy to configure.
Let's create a ReductionPipeline and fetch the ReductionSettings. These are the API settings for the ReductionProcessor, for more details of what each setting do, please visit the ReductionProcessor documentation.
If we look at what settings are available in ReductionSettings we can see that there indeed is a ReductionTargetTriangleRatio setting, set it to 0.5f for a 50% reduction. There is also a SetReductionTarget method which purpose is to set the condition of when to stop the optimization, this method is combining multiple API calls into one. See EStopCondition and SetReductionTargets for more details. For now we'll set the stop condition to 'All' and enable 'UseTriangleRatio' (first flag), the remaining flags should be set to false.
using Simplygon;
using Simplygon.Unity.EditorPlugin;
using System.Linq;
using UnityEditor;
using UnityEngine;
public class SimpleReduction
{
[MenuItem("Simplygon/SimpleReductionScript")]
static void EntryPoint()
{
if (Selection.gameObjects.Length > 0)
{
using (ISimplygon simplygon = global::Simplygon.Loader.InitSimplygon
(out EErrorCodes simplygonErrorCode, out string simplygonErrorMessage))
{
// if Simplygon handle is valid
if (simplygonErrorCode == Simplygon.EErrorCodes.NoError)
{
// Create a reduction pipeline.
using var simplygonReductionPipeline = simplygon.CreateReductionPipeline();
// Set triangle ratio to 50% of original.
using var simplygonReductionSettings = simplygonReductionPipeline.GetReductionSettings();
simplygonReductionSettings.SetReductionTargets(EStopCondition.All, true, false, false, false);
simplygonReductionSettings.SetReductionTargetTriangleRatio(0.5f);
}
// if invalid handle, output error message to the Unity console
else
{
Debug.LogError("Simplygon initializing failed!");
}
}
}
}
}
To execute the Pipeline in Unity we'll use the SimplygonProcessing class. Simply call simplygonProcessing.Run with the Simplygon object as first argument, your pipeline as second argument, the selected game objects as third argument, an EPipelineRunMode as fourth argument, and finally a boolean specificying if you want the newly create LOD to be instantiated in the scene.
See EPipelineRunMode for more execution options.
using Simplygon;
using Simplygon.Unity.EditorPlugin;
using System.Linq;
using UnityEditor;
using UnityEngine;
public class SimpleReduction
{
[MenuItem("Simplygon/SimpleReductionScript")]
static void EntryPoint()
{
if (Selection.gameObjects.Length > 0)
{
using (ISimplygon simplygon = global::Simplygon.Loader.InitSimplygon
(out EErrorCodes simplygonErrorCode, out string simplygonErrorMessage))
{
// if Simplygon handle is valid
if (simplygonErrorCode == Simplygon.EErrorCodes.NoError)
{
// Create a reduction pipeline.
using var simplygonReductionPipeline = simplygon.CreateReductionPipeline();
// Set triangle ratio to 50% of original.
using var simplygonReductionSettings = simplygonReductionPipeline.GetReductionSettings();
simplygonReductionSettings.SetReductionTargets(EStopCondition.All, true, false, false, false);
simplygonReductionSettings.SetReductionTargetTriangleRatio(0.5f);
// Run Simplygon processing.
var simplygonProcessing = new SimplygonProcessing();
simplygonProcessing.Run(simplygonReductionPipeline, Selection.gameObjects.ToList(), EPipelineRunMode.RunInThisProcess, true);
}
// if invalid handle, output error message to the Unity console
else
{
Debug.LogError("Simplygon initializing failed!");
}
}
}
}
}
That is it, let's go back to Unity, import an asset, select the object(s) and run the script. In this example we will use this city block, a complex asset with many meshes, materials and textures,
Once the optimization has completed the result will get imported back to the scene. See the result in the image below, the original asset to the left, the optimized asset to the right.
If possible, try this example with various pipelines such as Aggregation and Remeshing, with and without material baking.