Visibility sphere

Disclaimer: The code in this post is written on version 9.0.7700 of Simplygon. If you encounter this post at a later stage, some of the API calls might have changed. However, the core concepts should still remain valid.

Visibility culling - Visibility sphere

In Simplygon 8 you could optimize an asset using a custom visibility sphere. This is still possible in Simplygon 9 through the API, either as stand alone or directly in one of the integrations. To examplify this we will use this asset. As the asset never is going to be viewed from below we will use visibility culling to optimize the asset from all possible viewing angles scattered along the surface of the sphere shown in this asset.

Scripting in Maya

If we want to create this in Maya we can use a combination of the Simplygon command in Maya and the Python API. All we need to do is run this script:

# Copyright (c) Microsoft Corporation. 
# Licensed under the MIT license. 

from simplygon import simplygon_loader
from simplygon import Simplygon
import maya.cmds as cmds

intermediateFile = 'c:/tmp/_export.sb'

# Use the maya command to export the scene to Simplygon's API
def export_to_simplygon(sg):
    cmds.select(all=True)
    cmds.Simplygon(exp = intermediateFile , cte = True)
    scene = sg.CreateScene()
    scene.LoadFromFile(intermediateFile)
    return scene    

# Use the maya command to export the scene to Simplygon's API
def import_from_simplygon(scene):
    scene.SaveToFile(intermediateFile)
    cmds.Simplygon(imp = intermediateFile, lma=True)
    os.remove(intermediateFile)

# Add a vis sphere to the scene, set up selection sets and return the ID
def add_visibility_sphere(sg, scene, degrees):
    vis_sphere = sg.CreateSceneCamera()
		# This function assigns camera along a spherical surface.
    vis_sphere.SetCustomSphereCameraPath(5, 0, 0, degrees)
		# We need to add the camera to the scene and a selection set that processor will use to do the visibility calculations with.
    scene.GetRootNode().AddChild(vis_sphere)
    camera_set = sg.CreateSelectionSet()
    camera_set.AddItem(vis_sphere.GetNodeGUID())
    camera_set_id = scene.GetSelectionSetTable().AddSelectionSet(camera_set)
    return camera_set_id
    
# Sets up the pipeline and runs the procesing
def run_visibility_culling(sg, scene, camera_set_id):
    reduction_pipeline = sg.CreateReductionPipeline()
    # We don't want to reduce the object at all, so we're setting reduction ratio to 1
    reduction_settings = reduction_pipeline.GetReductionSettings()
    reduction_settings.SetReductionTargetTriangleRatio(1.0)
    # Set up the visiblity settings so that the 
    visibility_settings = reduction_pipeline.GetVisibilitySettings()
    visibility_settings.SetCullOccludedGeometry(True)
    visibility_settings.SetCameraSelectionSetID(camera_set_id)
    reduction_pipeline.RunScene(scene, Simplygon.EPipelineRunMode_RunInThisProcess)    
    
# Init example
sg = simplygon_loader.init_simplygon()
# Export the scene from Maya and load it into the Simplygon API
scene = export_to_simplygon(sg)
# Now we want to add the visibility sphere to the scene
camera_set_id = add_visibility_sphere(sg, scene, 180)
# Run the process on the scene    
run_visibility_culling(sg, scene, camera_set_id)
# Import the processed scene back into Maya
import_from_simplygon(scene)
del sg

Running the script on our example assets removes 2k of the 33k polys in the original asset. Depending on how the asset is built there could of course be a lot more polygons that could be removed without affecting the visual fidelity at all. Here is the end result after the process:

Running the script standalone

If you want to run the script outside of our integrations, you can just replace the import and export function with plain file importing. You can find the documentation for the file import/exporting here.

When to use this method?

This method is suitable when you want clean up an object after creation before you create a LOD chain, to remove any polygons that just aren't needed for the visuals. It should be used with caution on rigged meshes though. In those cases you might have polygons that aren't visible in the bind pose, but the animations might expose them.

⇐ Back to blog post list