# Visibility settings
Visibility can be computed for the scene or for a selected subset by using selection sets. This is done to determine which parts of the scene is actually visible. Scene cameras are added to the scene and the user can select which cameras should be used when calculating the visibility. If no cameras are selected, then a default set of cameras surrounding the scene will be used. The generated visibility weights can be used to guide the reduction, texcoord creation or used to simply remove all triangles that never are visible.
# Supported processors
- Reduction processor
- Remeshing processor
- Aggregation processor
# Camera example
This example shows how to use the Reduction processor with a visibility camera.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include <string>
#include <stdlib.h>
#include <filesystem>
#include <future>
#include "SimplygonLoader.h"
void RunReduction(Simplygon::ISimplygon* sg)
{
Simplygon::spSceneImporter sgSceneImporter = sg->CreateSceneImporter();
sgSceneImporter->SetImportFilePath( "../Assets/ObscuredTeapot/Teapot.obj" );
if(!sgSceneImporter->RunImport())
throw std::exception("Failed to load ObscuredTeapot/Teapot.obj.");
Simplygon::spScene sgScene = sgSceneImporter->GetScene();
// Create the reduction processor.
Simplygon::spReductionProcessor sgReductionProcessor = sg->CreateReductionProcessor();
sgReductionProcessor->SetScene( sgScene );
Simplygon::spReductionSettings sgReductionSettings = sgReductionProcessor->GetReductionSettings();
Simplygon::spVisibilitySettings sgVisibilitySettings = sgReductionProcessor->GetVisibilitySettings();
// Set reduction target to triangle ratio with a ratio of 50%.
sgReductionSettings->SetReductionTargets( Simplygon::EStopCondition::All, true, false, false, false );
sgReductionSettings->SetReductionTargetTriangleRatio( 0.5f );
// Add a camera to the scene. We'll use this later as a visibility camera.
Simplygon::spSelectionSetTable sgSceneSelectionSetTable = sgScene->GetSelectionSetTable();
Simplygon::spSelectionSet sgCameraSelectionSet = sg->CreateSelectionSet();
sgCameraSelectionSet->SetName("Camera");
Simplygon::spSceneCamera sgCameraSceneCamera = sg->CreateSceneCamera();
sgCameraSceneCamera->SetCustomSphereCameraPath(4, 90, 180, 90);
sgScene->GetRootNode()->AddChild(sgCameraSceneCamera);
sgCameraSelectionSet->AddItem(sgCameraSceneCamera->GetNodeGUID());
sgSceneSelectionSetTable->AddSelectionSet(sgCameraSelectionSet);
// Use the camera previously added.
sgVisibilitySettings->SetCameraSelectionSetName( "Camera" );
// Enabled GPU based visibility calculations.
sgVisibilitySettings->SetComputeVisibilityMode( Simplygon::EComputeVisibilityMode::DirectX );
// Disabled conservative mode.
sgVisibilitySettings->SetConservativeMode( false );
// Remove all non visible geometry.
sgVisibilitySettings->SetCullOccludedGeometry( true );
// Skip filling nonvisible regions.
sgVisibilitySettings->SetFillNonVisibleAreaThreshold( 0.0f );
// Don't remove non occluding triangles.
sgVisibilitySettings->SetRemoveTrianglesNotOccludingOtherTriangles( false );
// Remove all back facing triangles.
sgVisibilitySettings->SetUseBackfaceCulling( true );
// Don't use visibility weights.
sgVisibilitySettings->SetUseVisibilityWeightsInReducer( false );
// Start the reduction process.
sgReductionProcessor->RunProcessing();
Simplygon::spSceneExporter sgSceneExporter = sg->CreateSceneExporter();
sgSceneExporter->SetScene(sgScene);
sgSceneExporter->SetExportFilePath( "ReductionOutput.fbx" );
if(!sgSceneExporter->RunExport())
throw std::exception("Failed to save ReductionOutput.fbx.");
}
void main()
{
Simplygon::ISimplygon* sg = NULL;
Simplygon::EErrorCodes initval = Simplygon::Initialize( &sg );
if( initval != Simplygon::EErrorCodes::NoError )
{
return;
}
RunReduction(sg);
Simplygon::Deinitialize(sg);
}
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System;
using System.IO;
using System.Threading.Tasks;
public class Program
{
static void RunReduction(Simplygon.ISimplygon sg)
{
using (Simplygon.spSceneImporter sgSceneImporter = sg.CreateSceneImporter())
{
sgSceneImporter.SetImportFilePath( "../Assets/ObscuredTeapot/Teapot.obj" );
if(!sgSceneImporter.RunImport())
throw new System.Exception("Failed to load ObscuredTeapot/Teapot.obj.");
Simplygon.spScene sgScene = sgSceneImporter.GetScene();
// Create the reduction processor.
using (Simplygon.spReductionProcessor sgReductionProcessor = sg.CreateReductionProcessor())
{
sgReductionProcessor.SetScene( sgScene );
using (Simplygon.spReductionSettings sgReductionSettings = sgReductionProcessor.GetReductionSettings())
using (Simplygon.spVisibilitySettings sgVisibilitySettings = sgReductionProcessor.GetVisibilitySettings())
{
// Set reduction target to triangle ratio with a ratio of 50%.
sgReductionSettings.SetReductionTargets( Simplygon.EStopCondition.All, true, false, false, false );
sgReductionSettings.SetReductionTargetTriangleRatio( 0.5f );
// Add a camera to the scene. We'll use this later as a visibility camera.
using (Simplygon.spSelectionSetTable sgSceneSelectionSetTable = sgScene.GetSelectionSetTable())
using (Simplygon.spSelectionSet sgCameraSelectionSet = sg.CreateSelectionSet())
{
sgCameraSelectionSet.SetName("Camera");
using (Simplygon.spSceneCamera sgCameraSceneCamera = sg.CreateSceneCamera())
{
sgCameraSceneCamera.SetCustomSphereCameraPath(4, 90, 180, 90);
sgScene.GetRootNode().AddChild(sgCameraSceneCamera);
sgCameraSelectionSet.AddItem(sgCameraSceneCamera.GetNodeGUID());
}
sgSceneSelectionSetTable.AddSelectionSet(sgCameraSelectionSet);
}
// Use the camera previously added.
sgVisibilitySettings.SetCameraSelectionSetName( "Camera" );
// Enabled GPU based visibility calculations.
sgVisibilitySettings.SetComputeVisibilityMode( Simplygon.EComputeVisibilityMode.DirectX );
// Disabled conservative mode.
sgVisibilitySettings.SetConservativeMode( false );
// Remove all non visible geometry.
sgVisibilitySettings.SetCullOccludedGeometry( true );
// Skip filling nonvisible regions.
sgVisibilitySettings.SetFillNonVisibleAreaThreshold( 0.0f );
// Don't remove non occluding triangles.
sgVisibilitySettings.SetRemoveTrianglesNotOccludingOtherTriangles( false );
// Remove all back facing triangles.
sgVisibilitySettings.SetUseBackfaceCulling( true );
// Don't use visibility weights.
sgVisibilitySettings.SetUseVisibilityWeightsInReducer( false );
}
// Start the reduction process.
sgReductionProcessor.RunProcessing();
}
using (Simplygon.spSceneExporter sgSceneExporter = sg.CreateSceneExporter())
{
sgSceneExporter.SetScene(sgScene);
sgSceneExporter.SetExportFilePath( "ReductionOutput.fbx" );
if(!sgSceneExporter.RunExport())
throw new System.Exception("Failed to save ReductionOutput.fbx.");
}
}
}
static void Main(string[] args)
{
using (var sg = Simplygon.Loader.InitSimplygon(out var errorCode, out var errorMessage))
{
if (errorCode != Simplygon.EErrorCodes.NoError)
return;
RunReduction(sg);
}
}
}
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
import math
import os
import sys
import glob
import gc
import threading
from pathlib import Path
from simplygon import simplygon_loader
from simplygon import Simplygon
def RunReduction(sg: Simplygon.ISimplygon):
sgSceneImporter = sg.CreateSceneImporter()
sgSceneImporter.SetImportFilePath( '../Assets/ObscuredTeapot/Teapot.obj' )
if not sgSceneImporter.RunImport():
raise Exception('Failed to load ObscuredTeapot/Teapot.obj.')
sgScene = sgSceneImporter.GetScene()
# Create the reduction processor.
sgReductionProcessor = sg.CreateReductionProcessor()
sgReductionProcessor.SetScene( sgScene )
sgReductionSettings = sgReductionProcessor.GetReductionSettings()
sgVisibilitySettings = sgReductionProcessor.GetVisibilitySettings()
# Set reduction target to triangle ratio with a ratio of 50%.
sgReductionSettings.SetReductionTargets( Simplygon.EStopCondition_All, True, False, False, False )
sgReductionSettings.SetReductionTargetTriangleRatio( 0.5 )
# Add a camera to the scene. We'll use this later as a visibility camera.
sgSceneSelectionSetTable = sgScene.GetSelectionSetTable()
sgCameraSelectionSet = sg.CreateSelectionSet()
sgCameraSelectionSet.SetName('Camera')
sgCameraSceneCamera = sg.CreateSceneCamera()
sgCameraSceneCamera.SetCustomSphereCameraPath(4, 90, 180, 90)
sgScene.GetRootNode().AddChild(sgCameraSceneCamera)
sgCameraSelectionSet.AddItem(sgCameraSceneCamera.GetNodeGUID())
sgSceneSelectionSetTable.AddSelectionSet(sgCameraSelectionSet)
# Use the camera previously added.
sgVisibilitySettings.SetCameraSelectionSetName( "Camera" )
# Enabled GPU based visibility calculations.
sgVisibilitySettings.SetComputeVisibilityMode( Simplygon.EComputeVisibilityMode_DirectX )
# Disabled conservative mode.
sgVisibilitySettings.SetConservativeMode( False )
# Remove all non visible geometry.
sgVisibilitySettings.SetCullOccludedGeometry( True )
# Skip filling nonvisible regions.
sgVisibilitySettings.SetFillNonVisibleAreaThreshold( 0.0 )
# Don't remove non occluding triangles.
sgVisibilitySettings.SetRemoveTrianglesNotOccludingOtherTriangles( False )
# Remove all back facing triangles.
sgVisibilitySettings.SetUseBackfaceCulling( True )
# Don't use visibility weights.
sgVisibilitySettings.SetUseVisibilityWeightsInReducer( False )
# Start the reduction process.
sgReductionProcessor.RunProcessing()
sgSceneExporter = sg.CreateSceneExporter()
sgSceneExporter.SetScene(sgScene)
sgSceneExporter.SetExportFilePath( 'ReductionOutput.fbx' )
if not sgSceneExporter.RunExport():
raise Exception('Failed to save ReductionOutput.fbx.')
if __name__ == '__main__':
sg = simplygon_loader.init_simplygon()
if sg is not None:
RunReduction(sg)
sg = None
gc.collect()
# Occluder example
This example shows how to use the Reduction processor with a visibility occluder.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include <string>
#include <stdlib.h>
#include <filesystem>
#include <future>
#include "SimplygonLoader.h"
void RunReduction(Simplygon::ISimplygon* sg)
{
Simplygon::spSceneImporter sgSceneImporter = sg->CreateSceneImporter();
sgSceneImporter->SetImportFilePath( "../Assets/ObscuredTeapot/ObscuredTeapot.obj" );
if(!sgSceneImporter->RunImport())
throw std::exception("Failed to load ObscuredTeapot/ObscuredTeapot.obj.");
Simplygon::spScene sgScene = sgSceneImporter->GetScene();
// Create the reduction processor.
Simplygon::spReductionProcessor sgReductionProcessor = sg->CreateReductionProcessor();
sgReductionProcessor->SetScene( sgScene );
Simplygon::spReductionSettings sgReductionSettings = sgReductionProcessor->GetReductionSettings();
Simplygon::spVisibilitySettings sgVisibilitySettings = sgReductionProcessor->GetVisibilitySettings();
// Set reduction target to triangle ratio with a ratio of 50%.
sgReductionSettings->SetReductionTargets( Simplygon::EStopCondition::All, true, false, false, false );
sgReductionSettings->SetReductionTargetTriangleRatio( 0.5f );
// Add a selection set to the scene. We'll use this later as a occluder.
Simplygon::spSelectionSetTable sgSceneSelectionSetTable = sgScene->GetSelectionSetTable();
Simplygon::spSelectionSet sgOccluderSelectionSet = sg->CreateSelectionSet();
sgOccluderSelectionSet->SetName("Occluder");
Simplygon::spSceneNode sgRootBox002 = sgScene->GetNodeFromPath("Root/Box002");
if (!sgRootBox002.IsNull())
sgOccluderSelectionSet->AddItem(sgRootBox002->GetNodeGUID());
sgSceneSelectionSetTable->AddSelectionSet(sgOccluderSelectionSet);
// Use the occluder previously added.
sgVisibilitySettings->SetOccluderSelectionSetName( "Occluder" );
// Enabled GPU based visibility calculations.
sgVisibilitySettings->SetComputeVisibilityMode( Simplygon::EComputeVisibilityMode::DirectX );
// Disabled conservative mode.
sgVisibilitySettings->SetConservativeMode( false );
// Remove all non visible geometry.
sgVisibilitySettings->SetCullOccludedGeometry( true );
// Skip filling nonvisible regions.
sgVisibilitySettings->SetFillNonVisibleAreaThreshold( 0.0f );
// Don't remove non occluding triangles.
sgVisibilitySettings->SetRemoveTrianglesNotOccludingOtherTriangles( false );
// Remove all back facing triangles.
sgVisibilitySettings->SetUseBackfaceCulling( true );
// Don't use visibility weights.
sgVisibilitySettings->SetUseVisibilityWeightsInReducer( false );
// Start the reduction process.
sgReductionProcessor->RunProcessing();
Simplygon::spSceneExporter sgSceneExporter = sg->CreateSceneExporter();
sgSceneExporter->SetScene(sgScene);
sgSceneExporter->SetExportFilePath( "ReductionOutput.fbx" );
if(!sgSceneExporter->RunExport())
throw std::exception("Failed to save ReductionOutput.fbx.");
}
void main()
{
Simplygon::ISimplygon* sg = NULL;
Simplygon::EErrorCodes initval = Simplygon::Initialize( &sg );
if( initval != Simplygon::EErrorCodes::NoError )
{
return;
}
RunReduction(sg);
Simplygon::Deinitialize(sg);
}
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System;
using System.IO;
using System.Threading.Tasks;
public class Program
{
static void RunReduction(Simplygon.ISimplygon sg)
{
using (Simplygon.spSceneImporter sgSceneImporter = sg.CreateSceneImporter())
{
sgSceneImporter.SetImportFilePath( "../Assets/ObscuredTeapot/ObscuredTeapot.obj" );
if(!sgSceneImporter.RunImport())
throw new System.Exception("Failed to load ObscuredTeapot/ObscuredTeapot.obj.");
Simplygon.spScene sgScene = sgSceneImporter.GetScene();
// Create the reduction processor.
using (Simplygon.spReductionProcessor sgReductionProcessor = sg.CreateReductionProcessor())
{
sgReductionProcessor.SetScene( sgScene );
using (Simplygon.spReductionSettings sgReductionSettings = sgReductionProcessor.GetReductionSettings())
using (Simplygon.spVisibilitySettings sgVisibilitySettings = sgReductionProcessor.GetVisibilitySettings())
{
// Set reduction target to triangle ratio with a ratio of 50%.
sgReductionSettings.SetReductionTargets( Simplygon.EStopCondition.All, true, false, false, false );
sgReductionSettings.SetReductionTargetTriangleRatio( 0.5f );
// Add a selection set to the scene. We'll use this later as a occluder.
using (Simplygon.spSelectionSetTable sgSceneSelectionSetTable = sgScene.GetSelectionSetTable())
using (Simplygon.spSelectionSet sgOccluderSelectionSet = sg.CreateSelectionSet())
{
sgOccluderSelectionSet.SetName("Occluder");
Simplygon.spSceneNode sgRootBox002 = sgScene.GetNodeFromPath("Root/Box002");
if (!sgRootBox002.IsNull())
sgOccluderSelectionSet.AddItem(sgRootBox002.GetNodeGUID());
sgSceneSelectionSetTable.AddSelectionSet(sgOccluderSelectionSet);
}
// Use the occluder previously added.
sgVisibilitySettings.SetOccluderSelectionSetName( "Occluder" );
// Enabled GPU based visibility calculations.
sgVisibilitySettings.SetComputeVisibilityMode( Simplygon.EComputeVisibilityMode.DirectX );
// Disabled conservative mode.
sgVisibilitySettings.SetConservativeMode( false );
// Remove all non visible geometry.
sgVisibilitySettings.SetCullOccludedGeometry( true );
// Skip filling nonvisible regions.
sgVisibilitySettings.SetFillNonVisibleAreaThreshold( 0.0f );
// Don't remove non occluding triangles.
sgVisibilitySettings.SetRemoveTrianglesNotOccludingOtherTriangles( false );
// Remove all back facing triangles.
sgVisibilitySettings.SetUseBackfaceCulling( true );
// Don't use visibility weights.
sgVisibilitySettings.SetUseVisibilityWeightsInReducer( false );
}
// Start the reduction process.
sgReductionProcessor.RunProcessing();
}
using (Simplygon.spSceneExporter sgSceneExporter = sg.CreateSceneExporter())
{
sgSceneExporter.SetScene(sgScene);
sgSceneExporter.SetExportFilePath( "ReductionOutput.fbx" );
if(!sgSceneExporter.RunExport())
throw new System.Exception("Failed to save ReductionOutput.fbx.");
}
}
}
static void Main(string[] args)
{
using (var sg = Simplygon.Loader.InitSimplygon(out var errorCode, out var errorMessage))
{
if (errorCode != Simplygon.EErrorCodes.NoError)
return;
RunReduction(sg);
}
}
}
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
import math
import os
import sys
import glob
import gc
import threading
from pathlib import Path
from simplygon import simplygon_loader
from simplygon import Simplygon
def RunReduction(sg: Simplygon.ISimplygon):
sgSceneImporter = sg.CreateSceneImporter()
sgSceneImporter.SetImportFilePath( '../Assets/ObscuredTeapot/ObscuredTeapot.obj' )
if not sgSceneImporter.RunImport():
raise Exception('Failed to load ObscuredTeapot/ObscuredTeapot.obj.')
sgScene = sgSceneImporter.GetScene()
# Create the reduction processor.
sgReductionProcessor = sg.CreateReductionProcessor()
sgReductionProcessor.SetScene( sgScene )
sgReductionSettings = sgReductionProcessor.GetReductionSettings()
sgVisibilitySettings = sgReductionProcessor.GetVisibilitySettings()
# Set reduction target to triangle ratio with a ratio of 50%.
sgReductionSettings.SetReductionTargets( Simplygon.EStopCondition_All, True, False, False, False )
sgReductionSettings.SetReductionTargetTriangleRatio( 0.5 )
# Add a selection set to the scene. We'll use this later as a occluder.
sgSceneSelectionSetTable = sgScene.GetSelectionSetTable()
sgOccluderSelectionSet = sg.CreateSelectionSet()
sgOccluderSelectionSet.SetName("Occluder")
sgRootBox002 = sgScene.GetNodeFromPath('Root/Box002')
if sgRootBox002 is not None:
sgOccluderSelectionSet.AddItem(sgRootBox002.GetNodeGUID())
sgSceneSelectionSetTable.AddSelectionSet(sgOccluderSelectionSet)
# Use the occluder previously added.
sgVisibilitySettings.SetOccluderSelectionSetName( "Occluder" )
# Enabled GPU based visibility calculations.
sgVisibilitySettings.SetComputeVisibilityMode( Simplygon.EComputeVisibilityMode_DirectX )
# Disabled conservative mode.
sgVisibilitySettings.SetConservativeMode( False )
# Remove all non visible geometry.
sgVisibilitySettings.SetCullOccludedGeometry( True )
# Skip filling nonvisible regions.
sgVisibilitySettings.SetFillNonVisibleAreaThreshold( 0.0 )
# Don't remove non occluding triangles.
sgVisibilitySettings.SetRemoveTrianglesNotOccludingOtherTriangles( False )
# Remove all back facing triangles.
sgVisibilitySettings.SetUseBackfaceCulling( True )
# Don't use visibility weights.
sgVisibilitySettings.SetUseVisibilityWeightsInReducer( False )
# Start the reduction process.
sgReductionProcessor.RunProcessing()
sgSceneExporter = sg.CreateSceneExporter()
sgSceneExporter.SetScene(sgScene)
sgSceneExporter.SetExportFilePath( 'ReductionOutput.fbx' )
if not sgSceneExporter.RunExport():
raise Exception('Failed to save ReductionOutput.fbx.')
if __name__ == '__main__':
sg = simplygon_loader.init_simplygon()
if sg is not None:
RunReduction(sg)
sg = None
gc.collect()