Develop
Develop
Select your platform

Mixed Reality Utility Kit – Manipulate Scene Visuals

Updated: Sep 18, 2025

Learning Objectives

  • UseEffectMesh to cut holes in scene geometry (doors, windows, ceilings).
  • Configure the DestructibleGlobalMeshSpawner for runtime fragmentation and destruction.
  • Apply the Selective Passthrough shader to hide or reveal real-world surfaces dynamically.
  • Implement a ceiling-reveal workflow via custom scripts or prefab spawners.
Manipulate Room Sample

Overview

Beyond placing content, MRUK lets you reshape and visualize the real-world scene itself. You can cut out parts of walls or ceilings, spawn destructible fragments, or use passthrough shaders to reveal portals into VR or AR.

Cutting Holes with EffectMesh

The EffectMesh prefab can cut out semantic labels like doors, windows and ceilings by excluding them from the generated mesh. In the inspector, under Cut Holes, select any labels you wish to remove, creating a hole in that real-world surface, such as CEILING or WINDOW_FRAME.
EffectMesh Cut Holes

Destructible Global Mesh

Spawn a runtime, breakable version of the entire Scene Mesh. Fragments can be independently destroyed or manipulated for dramatic effects.
  • Reserved Spaces: Specify non-fragmentable regions.
  • Segments Density: Control fragment count vs. performance.
  • Material: Assign custom materials per fragment.
Destructible Mesh
Each fragment is a separate GameObject with a DestructibleMeshComponent for debug controls in-Editor. Add DestructibleGlobalMeshSpawner to your SceneMesh; configure reserved volumes, segment density, and materials to get a fully breakable environment.

Selective Passthrough Shader

The Meta Core SDK’s Selective Passthrough shader and material makes a mesh invisible to reveal the real-world camera feed. Apply it to any EffectMesh or custom mesh to carve portals into the physical environment. Assign the Selective Passthrough material to Mesh Material on your EffectMesh and all generated surfaces become passthrough.
Selective Passthrough

Tutorial: Ceiling Sky Reveal

Ceiling Reveal Tutorial
In this step-by-step tutorial, you will learn how to slowly remove the ceiling to reveal a virtual sky behind it, which is a popular use cases in Mixed Reality. When moving parts of your room, it is best practice to not move the MRUK anchor itself but instead move the EffectMesh.
There are at least two common approaches:

Option A: Use MRUK and EffectMesh utility functions

  1. On the EffectMesh component, set Mesh Material to a material with the Selective Passthrough shader.
  2. Write a script that waits for the EffectMesh to create the ceiling object, locate the ceiling anchor and move it out of view at runtime:
using System.Collections;
using Meta.XR.MRUtilityKit;
using UnityEngine;

public class CeilingMover : MonoBehaviour
{
    [Tooltip("Speed at which the ceiling moves out")]
    [SerializeField] private float speed = 0.5f;

    [Tooltip("The EffectMesh spawning our ceiling")]
    [SerializeField] private EffectMesh ceilingEffectMesh;

    private void Start()
    {
        StartCoroutine(WaitForEffectMeshAndMove());
    }

    private IEnumerator WaitForEffectMeshAndMove()
    {
        // 1. grab the current room
        var room = MRUK.Instance.GetCurrentRoom();

        // 2. wait until the mesh is spawned
        while (room.CeilingAnchor &&
               !ceilingEffectMesh.EffectMeshObjects.ContainsKey(room.CeilingAnchor))
        {
            yield return null;
        }

        // 3. fetch the wrapper and its real mesh GameObject
        var wrapper = ceilingEffectMesh.EffectMeshObjects[room.CeilingAnchor];
        var meshGo = wrapper.effectMeshGO;
        if (!meshGo)
        {
            Debug.LogError("No effectMeshGO found on wrapper!");
            yield break;
        }

        // 4. detach from the anchor so we only move the mesh
        meshGo.transform.SetParent(null, /* worldPositionStays= */ true);

        // 5. compute how far to move: half-room + half-ceiling + margin
        var roomBounds  = room.GetRoomBounds();
        var meshBounds  = meshGo.GetComponentInChildren<Renderer>().bounds;
        const float MARGIN = 0.1f;
        var distance  = roomBounds.extents.x + meshBounds.extents.x + MARGIN;

        // 6. slide the mesh straight out in world-space
        var moved = 0f;
        var dir = Vector3.right;
        while (moved < distance)
        {
            var step = speed * Time.deltaTime;
            meshGo.transform.Translate(dir * step, Space.World);
            moved += step;
            yield return null;
        }
    }
}
  1. Attach this component to your scene and assign the EffectMesh component in your scene that is responsible for creating the ceiling mesh.
  2. Press play in your editor and see how the room gets created (appears black) and the ceiling moves out of the room’s bounds.

Option B: Use EffectMesh and override the AnchorPrefabSpawner

  1. Set Mesh Material on EffectMesh to Selective Passthrough and deselect CEILING in the Labels property.
  2. Create a custom spawner to size a prefab to the ceiling’s bounds by inheriting from the AnchorPrefabSpawner:
using Meta.XR.MRUtilityKit;
using UnityEngine;

public class CeilingPrefabSpawner : AnchorPrefabSpawner
{
    public override Vector2 CustomPrefabScaling(Vector2 localScale)
    {
        return new Vector2(localScale.x, localScale.y);
    }
}
  1. In your scene, add this spawner and under Prefabs to Spawn add a new list item. Select the CEILING label under Labels, and assign your ceiling prefab under Prefabs. For the Scaling property, select Custom, so our script can override it.
  2. Move or deactivate the spawned prefab at runtime to unveil the sky.

Tip: When to Use SceneLoaded Callbacks

MRUK provides two ways to react when your scene data is ready:
  • RegisterSceneLoadedCallback: Use this helper if you want your callback invoked immediately and on all future loads. It will fire instantly if the scene is already initialized.
  • SceneLoadedEvent.AddListener: Use this when you only need to listen from this point forward. If the scene has already loaded, your listener will not be called until the next load.
using Meta.XR.MRUtilityKit;
using UnityEngine;

private void Awake()
{
    MRUK.Instance.RegisterSceneLoadedCallback(OnSceneReady);
    MRUK.Instance.SceneLoadedEvent.AddListener(OnNextSceneReady);
}

// 1. Runs now (if loaded) and on every future load
private void OnSceneReady()
{
    Debug.Log("Scene is ready right now or was already ready!");
}

// 2. Runs only the next time the scene loads
private void OnNextSceneReady()
{
    Debug.Log("This runs only the next time the scene loads.");
    // If you want it only once, remove the listener:
    MRUK.Instance.SceneLoadedEvent.RemoveListener(OnNextSceneReady);
}
If you have dependencies between MonoBehaviours, for example a custom script which depends on Physics colliders spawned by EffectMesh, ensure that you register the callbacks in the same order you want to receive them. Unity allows you to change the Script Order Execution which can help ensure callbacks are registered in the desired order.

DestructibleMesh Sample
DestructibleMesh (Beta)
Demonstrates the DestructibleGlobalMeshSpawner component. A DestructibleMesh prefab segments and spawns the global mesh when a room is created, parenting it under the GLOBAL_MESH anchor. Each segment is a GameObject with a MeshFilter and MeshRenderer.
View sample
VirtualHome
Reconstructs an interior scene using furniture prefabs for each semantic label via AnchorPrefabSpawner. Furniture uses GridsliceResizer to preserve aspect ratios. EffectMesh generates floor and ceiling meshes with carpet and ceiling textures, using Metric UVs for 1 m texture repeats.
View sample
VirtualHome Sample

Explore more MRUK documentation topics to dive deeper into spatial queries, content placement, manipulation, sharing, and debugging.
Core Concepts
  • Overview Get an overview of MRUK’s key areas and features.
  • Getting Started Set up your project, install MRUK, and understand space setup with available Building Blocks.
  • Place Content without Scene Use Environment Raycasting to place 3D objects into physical space with minimal setup.
  • Manage Scene Data Work with MRUKRoom, EffectMesh, anchors, and semantic labels to reflect room structure.
Content & Interaction
Multiuser & Debugging
MRUK Samples & Tutorials
Mixed Reality Design Principles
Did you find this page helpful?