Viewports
A Viewport can exist completely without a Session, as a Session can exist without a Viewport. The Viewport is responsible for rendering and rendering related settings. For example, camera and light management happens here. Additionally, a Viewport has many options, as rendering options can be enabled or disabled (shadows, ambient occlusion, etc.) and scene properties can be adjusted (groundplane, grid, etc.).
Cameras
One of the standard adaptions is to change some camera properties. We distinguish here between a Perspective Camera and an Orthographic Camera. In our next example we create a basic UI that let's you switch between cameras.
const perspectiveCamera = viewport.camera!;
const topCamera = viewport.createOrthographicCamera();
topCamera.direction = ORTHOGRAPHIC_CAMERA_DIRECTION.TOP;
const bottomCamera = viewport.createOrthographicCamera();
bottomCamera.direction = ORTHOGRAPHIC_CAMERA_DIRECTION.BOTTOM;
const leftCamera = viewport.createOrthographicCamera();
leftCamera.direction = ORTHOGRAPHIC_CAMERA_DIRECTION.LEFT;
const rightCamera = viewport.createOrthographicCamera();
rightCamera.direction = ORTHOGRAPHIC_CAMERA_DIRECTION.RIGHT;
const frontCamera = viewport.createOrthographicCamera();
frontCamera.direction = ORTHOGRAPHIC_CAMERA_DIRECTION.FRONT;
const backCamera = viewport.createOrthographicCamera();
backCamera.direction = ORTHOGRAPHIC_CAMERA_DIRECTION.BACK;
viewport.assignCamera(perspectiveCamera.id);
cameraSelect.onchange = () => {
switch (cameraSelect.value) {
case "top":
viewport.assignCamera(topCamera.id);
break;
case "bottom":
viewport.assignCamera(bottomCamera.id);
break;
case "left":
viewport.assignCamera(leftCamera.id);
break;
case "right":
viewport.assignCamera(rightCamera.id);
break;
case "front":
viewport.assignCamera(frontCamera.id);
break;
case "back":
viewport.assignCamera(backCamera.id);
break;
default:
viewport.assignCamera(perspectiveCamera.id);
}
viewport.update();
};
The camera also has many capabilities that can be used to roam through the scene.
// get the camera of the viewer
const camera = viewport.camera!;
await camera.animate(
[
{
position: camera.defaultPosition,
target: camera.defaultTarget
},
{
position: [100, 0, 0],
target: [0, 0, 0]
},
{
position: [0, 100, 0],
target: [0, 0, 0]
}
],
{ duration: 10000 }
);
await camera.zoomTo();
await camera.reset();
Camera Restrictions & Controls
You can restrict how users interact with the camera to create a more controlled viewing experience. This is useful for product configurators where you want to limit the viewing angles or prevent the user from zooming too far.
Enabling/Disabling Controls
const camera = viewport.camera!;
// Disable individual camera controls
camera.enableRotation = false; // prevent orbiting
camera.enableZoom = false; // prevent zooming
camera.enablePan = false; // prevent panning
Zoom Restrictions
Restrict how far the user can zoom in or out:
const camera = viewport.camera!;
// Set zoom limits (distance from target)
camera.zoomRestriction = {
minDistance: 50, // can't zoom in closer than 50 units
maxDistance: 500 // can't zoom out further than 500 units
};
Orbit (Rotation) Restrictions
Limit the orbit angles to prevent viewing the model from undesirable angles:
const camera = viewport.camera!;
// Restrict vertical orbit angle (in radians)
camera.rotationRestriction = {
minPolarAngle: Math.PI / 6, // prevent looking from too far below
maxPolarAngle: Math.PI / 2 // prevent looking from above
};
For the full list of camera properties and methods, see the IPerspectiveCameraApi and IOrthographicCameraApi API references.
Lights
For lights, we always handle a bunch of them at once, that's why we introduce Light Scenes. A Light Scene is a grouping of lights. The lights in a Light Scene can be freely manipulated. Therefore, we now create a new Light Scene and add a few lights to it.
// create a light scene, it will be assigned automatically
const lightScene = viewport.createLightScene()!;
// add a new ambient light, it will be added to the current light scene
const ambientLight = lightScene.addAmbientLight({ color: "#ff0000" });
// add a new directional light, it will be added to the current light scene
const directionalLight = lightScene.addDirectionalLight({
color: "#00ff00",
castShadow: true
});
Branding & Appearance
Branding options (logo, busy mode indicator, background color) are configured at viewport creation time via the branding property of createViewport(). These cannot be changed after the viewport is created.
Busy Mode / Loading Indicator
Control how the viewer indicates that a computation is in progress. The BUSY_MODE_DISPLAY enum has three values: SPINNER (default), BLUR, and NONE.
const viewport = await SDV.createViewport({
canvas: document.getElementById("canvas") as HTMLCanvasElement,
branding: {
busyModeDisplay: BUSY_MODE_DISPLAY.SPINNER // SPINNER | BLUR | NONE
}
});
Logo & Background
The ShapeDiver logo shown while the viewport is loading can be customized or removed (subject to your plan's terms). A background color is shown while the viewport is hidden.
const viewport = await SDV.createViewport({
canvas: document.getElementById("canvas") as HTMLCanvasElement,
branding: {
logo: null, // null = remove logo, or provide a URL string
backgroundColor: "#ffffff", // background while viewport is hidden
busyModeDisplay: BUSY_MODE_DISPLAY.SPINNER,
busyModeSpinner: "https://example.com/my-spinner.gif" // custom spinner URL
}
});
Background Color & Transparency
The 3D scene background color and transparency are controlled via runtime properties on the viewport:
// Transparent background (useful for overlaying on a web page)
viewport.clearColor = "#ffffff";
viewport.clearAlpha = 0;
// Hide grid and ground plane
viewport.gridVisibility = false;
viewport.groundPlaneVisibility = false;
Viewport Visibility
You can show or hide the viewport programmatically. Hiding stops rendering and shows the loading screen. This is useful with VISIBILITY_MODE.MANUAL where you control when the viewport first appears.
// Hide the viewport (stops rendering, shows loading screen)
viewport.show = false;
// Show the viewport again
viewport.show = true;
For all viewport properties, see the IViewportApi reference. For the full list of createViewport() options, see ViewportCreationDefinition.
Additional Examples
Additional example can be found on the viewer examples page in the viewport section.