---
title: "Viewport frames"
url: /docs/en-us/ui/viewport-frames
last_updated: 2026-07-01T03:40:56Z
description: "ViewportFrames use a camera to render 3D objects into a 2D viewport."
---

# Viewport frames

A `Class.ViewportFrame` uses a camera to render 3D objects into a 2D viewport. Ideal use cases include:

- A minimap of your experience directly in the corner of a user's screen.
- 3D models of items in an inventory menu.
- Rotating objects that a character has equipped.

## Viewport configurations

3D objects that users view through a `Class.ViewportFrame` can either move with their camera, remain static, or rotate within the `Class.ViewportFrame`. This object can also include a `Class.Sky` child as a cubemap for reflections.

#### With Camera

If you want a 3D object to move with the camera:

1. Position your camera view within the experience so that the object you want to see within the frame is visible.
2. Add a new `Class.ViewportFrame` to the [screen](/docs/en-us/ui/on-screen-containers.md) and then make sure it's selected in the **Explorer**.
3. In the **Properties** window, assign the `Class.ViewportFrame.CurrentCamera|CurrentCamera` property to the camera:
  1. Select the `Class.ViewportFrame.CurrentCamera|CurrentCamera` property. Your cursor changes.
  2. In the **Explorer** window, click on the top-level `Class.Camera` object.
4. Parent the desired 3D object to the new `Class.ViewportFrame`. Note that if you still want to see the object within your experience, you must duplicate it in the `Class.Workspace` and then parent the **duplicate** object to the `Class.ViewportFrame`.

When you move your camera, the object will also move within the `Class.ViewportFrame`.

> **Warning:** When you want to update the view of your `Class.ViewportFrame`, be sure to update the camera, **not** the objects within the view.

#### Static

If you want the 3D object to remain static:

1. Position your camera view within the experience so that the object you want to see is in the exact position you want to see it within the frame.
2. In the **Explorer** window, duplicate the top-level `Class.Camera` object, then rename it to an identifiable name like `ViewportCam`.
3. Add a new `Class.ViewportFrame` to the [screen](/docs/en-us/ui/on-screen-containers.md) and then make sure it's selected in the **Explorer**.
4. In the **Properties** window, assign the frame's `Class.ViewportFrame.CurrentCamera|CurrentCamera` property to the **duplicated** camera:
  1. Select the `Class.ViewportFrame.CurrentCamera|CurrentCamera` property. Your cursor changes.
  2. In the **Explorer** window, click on the duplicated camera object.
5. Parent the desired 3D object to the new `Class.ViewportFrame`. Note that if you still want to see the object within your experience, you must duplicate it in the `Class.Workspace` and then parent the **duplicate** object to the `Class.ViewportFrame`.

#### Rotation

If you want a 3D object such as a `Class.BasePart` to rotate on its own within the frame:

1. Add a new `Class.ViewportFrame` to the [screen](/docs/en-us/ui/on-screen-containers.md).
2. In the **Explorer** window, drag the desired `Class.BasePart` into the new `Class.ViewportFrame`.
3. Insert a new `Class.LocalScript` into the `Class.ViewportFrame` and paste in the following code.```lua
local RunService = game:GetService("RunService")

local viewportFrame = script.Parent

-- Parameters to experiment with
local cameraDistance = 10
local cameraFieldOfView = 50
local objectPitchAngle = 40
local objectRotationSpeed = 50

-- Viewport camera initialization
local viewportCamera = Instance.new("Camera")
viewportCamera.FieldOfView = cameraFieldOfView
viewportFrame.CurrentCamera = viewportCamera
viewportCamera.Parent = viewportFrame

-- Viewport object initialization
local object = viewportFrame:FindFirstChildWhichIsA("BasePart")
if object then
	object.CFrame = CFrame.new(0, 0, 0) * CFrame.Angles(math.rad(objectPitchAngle), 0, 0)

	-- Update loop
	local t = 0
	RunService.PostSimulation:Connect(function(delta)
		t += delta
		viewportCamera.CFrame = CFrame.Angles(0, math.rad(t * objectRotationSpeed), 0) * CFrame.new(0, 0, cameraDistance)
	end)
else
	warn("3D object not found as child of viewport frame")
end
```

#### Skybox Reflections

`Class.ViewportFrame|ViewportFrames` can use a `Class.Sky` child as a cubemap for reflections, in which case only the `Class.Sky` object's six `Skybox[…]` properties are used. Assuming these properties are valid, lighting inside the `Class.ViewportFrame` acts similarly to when `Class.Lighting.EnvironmentSpecularScale` and `Class.Lighting.EnvironmentDiffuseScale` are both set to `1`.

To implement skybox cubemap reflections:

1. Insert a `Class.Sky` object as a direct child of the `Class.ViewportFrame`.
2. Set the `Class.Sky` object's six texture properties (`Class.Sky.SkyboxBk|SkyboxBk`, `Class.Sky.SkyboxDn|SkyboxDn`, `Class.Sky.SkyboxFt|SkyboxFt`, `Class.Sky.SkyboxLf|SkyboxLf`, `Class.Sky.SkyboxRt|SkyboxRt`, `Class.Sky.SkyboxUp|SkyboxUp`).
3. For `Class.Part|Parts` that should appear within the frame, set their `Class.BasePart.Reflectance|Reflectance` property greater than 0, or use a reflectant material like `Enum.Material.Glass|Glass` or `Enum.Material.Foil|Foil`. For `Class.MeshPart|MeshParts` that should appear within the frame, apply a `Class.SurfaceAppearance` with a properly-configured `Class.SurfaceAppearance.MetalnessMap|MetalnessMap`.

## Lighting and appearance

Lighting within a `Class.ViewportFrame` is controlled through three properties:

| Property | Description |
| --- | --- |
| `Class.ViewportFrame.Ambient\|Ambient` | Determines the overall lighting hue applied to the area within the viewport frame. Defaults to`Datatype.Color3.fromRGB(200, 200, 200)` (ghost grey). |
| `Class.ViewportFrame.LightDirection\|LightDirection` | A `Datatype.Vector3` representing the direction of the light source from position`(0, 0, 0)`. Defaults to`(-1, -1, -1)`. |
| `Class.ViewportFrame.LightColor\|LightColor` | Color of the directional light. Defaults to`Datatype.Color3.fromRGB(140, 140, 140)` (silver). |

Additionally, you can adjust the overall rendered appearance of the viewport throuugh the following properties:

| Property | Description |
| --- | --- |
| `Class.ViewportFrame.ImageColor3\|ImageColor3` | Changes the image color/tint without modification of the rendered object. The default colorization value is`Datatype.Color3.new(1, 1, 1)` (white) at which no color modification occurs. |
| `Class.ViewportFrame.ImageTransparency\|ImageTransparency` | Changes the image transparency without modification of the rendered object. A value of `0` (default) is completely opaque and a value of `1` is completely transparent (invisible). |