Layer and mesh rendering modes
Updated: Oct 3, 2025
Spatial SDK optimizes panels for most use cases by default. For specific effects, you’ll need deeper configuration.
Layers provide superior visuals but come with tradeoffs. The comparison below shows a panel with and without layers. The effect is much more noticeable in your headset.
Example of a panel not using layers
Example of a panel using layers
When using layers, there are several different ways to blend the layer with the scene. In this example, the corners of the texture have an alpha value of 0, and there are several different ways to apply the alpha.
PanelShapeLayerBlendType.OPAQUE
In the OPAQUE mode, every pixel of the texture is treated as opaque, and every pixel will be rendered. The alpha value is ignored.
PanelShapeLayerBlendType.MASKED
With MASKED mode, the alpha value is treated as a cutout value. Each rendered sample is treated as either opaque, or it is not rendered based on the alpha value. In this case, the corners with alpha of zero are not rendered, but since each sample is either rendered or not, there will still be aliasing along the edges.
PanelShapeLayerBlendType.ALPHA_BLEND
In ALPHA_BLEND mode, the layer is blended with the background using the alpha as the weight. This can result in the highest quality transition from the opaque to transparent parts of the image. However, it comes with several drawbacks. In particular, this mode will not write to the depth buffer, so alpha blended geometry may appear in the wrong order.
One limitation of the layer API is that black lines may be seen along the edges. The scene is rendered with coarser pixels than the layers, and this mismatch can cause a black edge to appear in those misaligned areas. Feathering was introduced to Spatial SDK to fix these areas. It shrinks the cutout by about 1.5 pixels to remove the black line. The effect varies based on the blending mode.
PanelShapeLayerBlendType.OPAQUE
In the OPAQUE mode, the edges of the panel are shrunk slightly with a soft feathered edge. However, the alpha value of the texture is ignored, and all texels are treated as opaque, except for the feathering on the borders.
PanelShapeLayerBlendType.MASKED
Masked treats the image as masked, but analyzes the alpha of the texture to remove the black lines. Note that since there is no actual blending (each pixel is either rendered or not) there can still be some black lines visible around the edges.
PanelShapeLayerBlendType.ALPHA_BLEND
For the highest quality edges, use ALPHA_BLEND with feathering. In addition to feathering the edges, it will analyze the alpha of the interior of the texture and apply a smooth blend to the transition. This also provides increased quality for alpha blend edges.
Panels can use layers (recommended for crisp, high-quality visuals) or mesh (simpler but lower quality) rendering. This applies to both UI panels and readable media panels.
Using layers (recommended)
Layers provide superior visual quality and are the default rendering mode. Enable layers by setting renderMode to PanelRenderMode.Layer() in your panel render options:
// UI panels with layers
UIPanelSettings(
rendering = UIPanelRenderOptions(
renderMode = PanelRenderMode.Layer() // Default - enables layers
)
)
For simpler panels where visual quality is less critical, use mesh rendering instead of layers:
// UI panels with mesh rendering
UIPanelSettings(
rendering = UIPanelRenderOptions(
renderMode = PanelRenderMode.Mesh() // Use mesh instead of layers
)
)
Note: Mesh rendering is not recommended for panels with text or complex UI. They will appear low-resolution compared to layers.
Known issue:ReadableMediaPanelRenderOptions with
PanelRenderMode.Mesh() incorrectly creates a compositor layer. See
Known issues for details and workarounds.
VideoSurfacePanelRegistration: Uses direct-to-surface rendering, only available with layersReadableVideoSurfacePanelRegistration: Supports both layer and mesh rendering modes as shown above
(Advanced) Using PanelConfigOptions for layer configuration
Advanced usage: This section is for developers who need direct control over layer configuration beyond what the Panel Settings APIs provide.
For legacy code or custom layer behavior, configure layers directly using PanelConfigOptions:
import com.meta.spatial.runtime.LayerConfig
PanelConfigOptions().apply {
// Enable layers
layerConfig = LayerConfig()
// Or disable layers (use mesh rendering)
layerConfig = null
// Advanced layer configuration with hole punching
layerConfig = LayerConfig(filters = LayerFilters.HIGHEST_QUALITY, zIndex = -1)
layerBlendType = PanelShapeLayerBlendType.ALPHA_BLEND
enableLayerFeatheredEdge = true
alphaMode = AlphaMode.HOLE_PUNCH
panelShader = SceneMaterial.HOLE_PUNCH_PANEL_SHADER
}
To avoid using layers, remove layerConfig from your configuration along with the panelShader and alphaMode changes.