3D models

On this page

It's easy to embed your 3D models in your website/app with Sirv Media Viewer. Upload your GLB or glTF files to your Sirv account.

The code is simple and the viewer is highly configurable (described below):

<script src="https://scripts.sirv.com/sirvjs/v3/sirv.js?modules=model"></script>
<div class="Sirv">
 <div data-src="https://demo.sirv.com/model.glb"></div>
</div>

Models can also be shown in a gallery with other media (images, videos or spins).

Embed that gallery with this code:

<script src="https://scripts.sirv.com/sirvjs/v3/sirv.js"></script>
<div class="Sirv">
 <div data-src="https://demo.sirv.com/demo/Switch/switch-front.jpg" data-type="zoom"></div>
 <div data-src="https://demo.sirv.com/demo/Switch/switch-separate.png" data-type="zoom"></div>
 <div data-src="https://demo.sirv.com/demo/Switch/nintendo_switch.glb"></div>
 <div data-src="https://demo.sirv.com/demo/Switch/switch-slide.jpg" data-type="zoom"></div>
 <div data-src="https://demo.sirv.com/demo/Switch/switch.mp4" data-options="autoplay:true"></div>
 <div data-src="https://demo.sirv.com/demo/Switch/switch-wide.jpg" data-type="zoom"></div>
 <div data-src="https://demo.sirv.com/demo/Switch/switch-oled.jpg" data-type="zoom"></div>
</div>

Or even simpler, embed it as a smart gallery like so:

<script src="https://scripts.sirv.com/sirvjs/v3/sirv.js"></script>
<div class="Sirv">
 <div data-src="https://demo.sirv.com/demo/Switch.view"></div> 
</div>

Options

Customize the experience of your 3D model with these options:

Parameter Default Options Description
zoom true true, false Enable/disable zoom
preload false true, false Load on page load (true) or when active (false)
thumbnail false image URL Apply a custom thumbnail
sensitivity 1 -100 to 100 Adjusts speed of theta & phi orbit interactions
shadow.intensity 0 0-100 Shadow opacity
shadow.softness 100 0-100 Shadow blurriness 0=hard, 100=soft
exposure 1 0-10000 Lighting exposure (0=black)
hint.finger true true, false Show/hide the visual interaction prompt
Autorotate
autorotate.enable false true, false Enable auto-rotation
autorotate.delay 0 Delay before auto-rotation begins (ms)
autorotate.speed 15 1-360 Speed of auto-rotation (degrees per second)
Animation
animation.autoplay false true, false If a model has animations, play them
animation.timeScale 1 -100 to 100 Adjust speed or play backwards
animation.crossfadeDuration 300 Duration of fade between animations (ms)
animation.name Text Choose which animation to play first
Augmented Reality (AR)
ar.enable true true, false Enable AR on supported devices
ar.zoom true true, false Scale model on pinch
ar.placement floor floor, wall Place object on floor or wall in AR
ar.xrEnvironment false true, false AR lighting estimation - has known issues
Environment
skybox.image URL of HDR file Set background to the scene
skybox.height 0m Numeric (m, cm or mm) Camera distance above ground (0m = disabled)
environmentImage false false or HDR URL Apply reflection on the object
Camera location
camera.orbit 0deg 75deg 105% deg, deg, % Change the opening angle of the model
camera.target auto auto auto Numeric (m, cm or mm) Set the location of the camera

How to apply options

You can change the options either inline or globally in a script.

Options applied inline:

<div class="Sirv">
 <div data-src="https://demo.sirv.com/model.glb" data-options="sensitivity:60; shadow.intensity:30"></div>
</div>

Options applied globally:

<script>
SirvOptions = {
 "viewer": {
  "model": {
   "sensitivity": 60,
   "shadow": {
    "intensity": 30
   }
  }
 }
}
</script>

Ensure that your page references the Sirv JS script:

<script src="https://scripts.sirv.com/sirvjs/v3/sirv.js"></script>

or a smaller version if your page doesn't have any other Sirv images, videos or spins:

<script src="https://scripts.sirv.com/sirvjs/v3/sirv.js?modules=model"></script>

Share URL

You can share your model URL as a viewable file by appending ?embed:

https://demo.sirv.com/model.glb?embed

Iframe embed

We recommend embedding models with a div but it is also possible to embed using an iframe. Append ?embed to the model URL and use typical iframe code, like so:

<iframe src="https://demo.sirv.com/model.glb?embed" width="100%" height="100%" frameborder="0" allowfullscreen></iframe>

Zoom

Your model will be zoomable on mouse scrollwheel or pinch on a touchscreen. Disable zoom by setting zoom to false.

<div class="Sirv">
 <div data-src="https://demo.sirv.com/model.glb" data-options="zoom:false"></div>
</div>

Preload

Your model will lazy-load, once it becomes visible in the viewport. This helps reduce bandwidth usage. For the fastest possible experience, you can make models load in advance by setting preload to true.

<div class="Sirv">
 <div data-src="https://demo.sirv.com/model.glb" data-options="preload:true"></div>
</div>

Thumbnail

You can specify a custom thumbnail that shows while the model is loading. Add the thumbnail option with the URL of your custom image.

<div class="Sirv">
 <div data-src="https://demo.sirv.com/model.glb" data-options="thumbnail:https://scripts.sirv.com/sirvjs/v3/graphics/icons/3d/black/icon.3d.5.svg"></div>
</div>

Sensitivity

You can change the speed at which your model moves when the user interacts. Make the model more or less sensitive by setting sensitivity to a value between -100 to 100.

<div class="Sirv">
 <div data-src="https://demo.sirv.com/model.glb" data-options="sensitivity:50"></div>
</div>

Shadow

You can show a shadow under your model by setting shadow.intensity to a value between 0 to 100 (where 0 is no shadow). You can adjust the spread of the shadow by setting shadow.softness to a value between 0 to 100.

<div class="Sirv">
 <div data-src="https://demo.sirv.com/model.glb" data-options="shadow.intensity:100; shadow.softness:20"></div>
</div>

Exposure

You can brighten or darken your model by setting exposure to a value between 0 to 100 (or higher), where 0 will be so dark it is black. Default is 1. The following example makes it darker, with a setting of 0.5:

<div class="Sirv">
 <div data-src="https://demo.sirv.com/model.glb" data-options="exposure:0.5"></div>
</div>

Autorotate

Automatically rotate your model by setting autorotate.enable to true.

Adjust the speed of rotation by setting autorotate.speed to a value between 1 and 360 (degrees per second). Change the direction by applying a negative value from -1 to -360.

After the user has interacted with the model, you can choose the time before auto-rotation restarts. Set autorotate.delay to a number in milliseconds.

The following example sets a speed of 6 degrees per second, with a 3 second restart delay:

<div class="Sirv">
 <div data-src="https://demo.sirv.com/model.glb" data-options="autorotate.enable:true; autorotate.speed:6; autorotate.delay:3000"></div>
</div>
<script>
var SirvOptions = {
 "viewer": {
  "model": {
   "autoplay": {
    "enable": true,
    "speed": "6",
    "delay": "3000"
   }
  }
 }
}
</script>

Hint

An animated finger shows on your model, dragging it slightly to suggest that it is interactive. You can disable this by setting hint.finger to false.

<div class="Sirv">
 <div data-src="https://demo.sirv.com/model.glb" data-options="hint.finger:false"></div>
</div>

The model will look like a static image, so it is often used in conjunction with autorotate:

<div class="Sirv">
 <div data-src="https://demo.sirv.com/model.glb" data-options="hint.finger:false; autorotate.enable:true"></div>
</div>

Animation

If your model has animations, you can play them by setting animation.autoplay to true.

Animations will loop, one after another. To play a particular animation, set its name with the animation.name option. You can change the animation speed of by setting animation.timeScale from 1 to 100 (or -100 to -100 to play it backwards). You can adjust length of the fade effect between animation by setting animation.crossfadeDuration in milliseconds.

The following sets a timescale of 2 and fade duration of 800ms:

<div class="Sirv">
 <div data-src="https://demo.sirv.com/model.glb" data-options="animation.autoplay:true; animation.timeScale:2; animation.crossfadeDuration:800"></div>
</div>
<script>
var SirvOptions = {
 "viewer": {
  "model": {
   "animation": {
    "autoplay": true,
    "timeScale": "2",
    "crossfadeDuration": "800"
   }
  }
 }
}
</script>

Augmented reality

Your model can be viewed in AR (Augmented Reality) on smartphones and other AR supported devices. This can be disabled by setting ar.enable to false.

Users can pinch your model to zoom in and out. This can be disabled by setting ar.zoom to false.

Your model will be placed on the floor of the users' room. Instead, you can place it on a wall by setting ar.placement to wall.

You can improve the lighting estimation in WebXR mode by setting ar.xrEnvironment to true. This uses more device CPU. Lighting can sometimes look too dark, have sudden updates and shiny materials can look matt, so test this to see how well it works with your model.

Environment image & reflection

To display a background image behind your model, add the skybox.image parameter. You can use either HDR, JPEG or PNG images. HDR files contain the most information but are enormous files, so we recommend converting your HDR file to JPEG format using the gainmap-js conversion tool.

Background images can reduce the amount of light on the image so you might want to increase the exposure. This example shows a background JPEG and exposure of 7:

<div class="Sirv">
 <div data-src="https://demo.sirv.com/model.glb" data-options="skybox.image:https://demo.sirv.com/derelict_overpass_8k.jpg; exposure:7"></div>
</div>

You can also add skybox.height to change the height of the camera above the ground, applied in m, cm or mm (default is 0).

To show a reflection of the environment on the model, apply the environmentImage parameter. Specify the URL of the HDR or JPEG image from your Sirv account.

<div class="Sirv">
 <div data-src="https://demo.sirv.com/model.glb" data-options="environmentImage:https://demo.sirv.com/derelict_overpass_8k.jpg"></div>
</div>

Your skybox or environment images should have been created using the sRGB color profile - CMYK color spaces are not supported.

Camera orbit

You can choose the opening view of your model by applying camera.orbit. Three values can be adjusted: theta, phi and radius:

  • Theta rotates the camera around the model, in degrees.
  • Phi rotates the camera up/down the model, in degrees.
  • Radius moves the camera towards or away from the model, as a percentage.

Default values are 0deg, 75deg, 105%. Values can also be set in m (meters), cm (centimeters) or mm (millimeters) but degrees and % are usually recommended.

The following example shows the model rotated 45 degrees left, 60 degrees down and zoomed in to 55%:

<div class="Sirv">
 <div data-src="https://demo.sirv.com/model.glb" data-options="camera.orbit:45deg 60deg 55%"></div>
</div>

Camera target

You can also change the target position of where the camera orbits around, by applying camera.target. The target is normally the center of the model. Values are X, Y and Z, set with the units m, cm or mm. Values can be negative. Default values are auto, auto, auto.

The following example moves the camera 6.5m to the right, -1.2m up and 1.4m away:

<div class="Sirv">
 <div data-src="https://demo.sirv.com/model.glb" data-options="camera.target:6.5m -1.2m 1.4m"></div>
</div>

Extend vertical angle

Models can be dragged up to 150° and down to 150°. You can extend that so the user can drag all the way to look straight down or up onto your model.

To drag all the way up to 180° and down to 180°, add the following script to your page:

<script>
Sirv.on('model:ready', (e) => {
  const model = e.node.querySelector('model-viewer');
  model.setAttribute('min-camera-orbit', 'auto 0deg auto');
  model.setAttribute('max-camera-orbit', 'auto 180deg auto');
});
</script>

Thumbnail icon

The thumbnail icon can be changed to any design you wish. Sirv provides 16 icons, shown below on a grey background that you can control with CSS:

Icons exist in black or white, ordered from 1 to 8 e.g.

Alternatively, you can design your own square SVG icon (or PNG) and apply it with CSS, like so:

<style>
.smv-thumbnails .smv-selector[data-type="model"]:before {
  background-image: url(https://youraccount.sirv.com/path/to/your/icon.svg);
}
</style>

The background color of the icon can be changed with:

<style>
.smv-thumbnails .smv-selector[data-type="model"]:before {
  background-color: rgba(128, 128, 128, 0.56);
}
</style>

Change color of materials

If your product has configurable colors (swatches), you can change the material colors in your GLB by applying some JavaScript to your page.

To change a color, identify the number of the material you want to change. Materials are numbered from [1] upwards. If your model has 3 materials, they will be named model.materials[1], model.materials[2] and model.materials[3].

The following example will change model.materials[3] to the hex color #abf0c4:

document.querySelector(".Sirv model-viewer").model.materials[3].pbrMetallicRoughness.setBaseColorFactor('#abf0c4');

GLB vs glTF files

We recommend uploading your files in GLB format, instead of glTF. GLB files contain everything the model requires in a single file (textures, shaders and animation data). glTF files can also be self-contained with binary data buffers in base64-encoded strings, but programs that generate glTF files usually refer to textures in separate files. If those separate files are not where the glTF expected them to be, your model will be shown "naked" and won't look correct.

USDZ files

USDZ files are AR files supported by iOS devices (iPhone and iPad). As they only work on Apple devices, ideally you should have a fallback model in GLB/glTF format.

Here is an example with a GLB and a USDZ file.

Follow these 3 steps to show your USDZ file in AR:

1. Add the following script to your page:

<script>
 const arQuickLookSupport = document.createElement("a").relList.supports("ar");
 const arSceneViewerSupport =
  /android/i.test(navigator.userAgent) &&
  !/firefox/i.test(navigator.userAgent) &&
  !/OculusBrowser/.test(navigator.userAgent);
 customElements.define(
  "smv-ios-ar-button",
  class extends HTMLElement {
   constructor() {
    super();
   }
   connectedCallback() {
    this.setup();
   }
   setup() {
    if (!arQuickLookSupport && arSceneViewerSupport) {
     return;
    }
    const src = (this.dataset.src || "").trim();
    if (!src) {
     return;
    }
    if (this.shadowRoot) {
     return;
    }
    const shadowRoot = this.shadowRoot || this.attachShadow({ mode: "open" });
    const style = document.createElement("style");
    style.textContent = `.smv-ios-ar-button {
       position: absolute;
       right: 16px;
       bottom: 16px;
       width: 44px;
       height: 44px;
       padding: 8px;
       border-radius: 50%;
       background-color: #fff;
       color: #000;
       box-shadow: 0 0 4px rgba(0, 0, 0, 0.15);
       box-sizing: border-box;
       cursor: pointer;
       z-index: 101;
     }`;
    shadowRoot.appendChild(style);
    const arButton = document.createElement("div");
    arButton.classList.add("smv-ios-ar-button");
    arButton.ariaLabel = "View in AR";
    arButton.insertAdjacentHTML(
     "beforeend",
     '<svg fill="none" viewBox="0 0 48 48"><path fill="#000" d="m17.938 3.5.5.866L24 1.155l5.562 3.211.5-.866L24 0l-6.062 3.5ZM9.778 9.366l-.5-.866L3.215 12v7h1v-6.423l5.563-3.211ZM4.215 29h-1v7l6.063 3.5.5-.866-5.563-3.211V29ZM18.438 43.634l-.5.866L24 48l6.062-3.5-.5-.866L24 46.845l-5.562-3.211ZM43.785 29h1v7l-6.063 3.5-.5-.866 5.563-3.211V29ZM38.722 8.5l-.5.866 5.563 3.211V19h1v-7l-6.063-3.5Z"></path><path fill="#000" d="M23.5.878h1v9.91L24 10.5l-.5.289V.879ZM12.308 30.173v.577l.5.289L4.04 36.1l-.5-.866 8.768-5.062ZM35.19 31.039l.5-.289v-.577l8.826 5.095-.5.866-8.825-5.095Z"></path><path fill="#000" fill-rule="evenodd" d="M12.3 17.25v13.5L24 37.5l11.7-6.75v-13.5L24 10.5l-11.7 6.75Zm1.95.375L24 23.25l9.75-5.625L24 12l-9.75 5.625ZM34.4 18.75l-9.75 5.625v11.25L34.4 30V18.75Zm-11.05 5.625L13.6 18.75V30l9.75 5.625v-11.25Z" clip-rule="evenodd"></path></svg>'
    );
    if (arQuickLookSupport) {
     arButton.addEventListener("click", () => {
      const arA = document.createElement("a");
      arA.style.display = "none";
      arA.setAttribute("href", src);
      arA.rel = "ar";
      arA.appendChild(document.createElement("img"));
      arA.click();
     });
    } else if (!arSceneViewerSupport) {
     // Fallback on desktop
     const template = document
      .getElementById("template-smv-ar-qrcode")
      .content.cloneNode(true);
     const qrModal = template.querySelector(".smv-ar-qrcode-modal");
     qrModal.style.display = "none";
     template
      .querySelector(".smv-ar-qrcode-modal__body img[role=link]")
      .setAttribute(
       "src",
       `https://api.qrserver.com/v1/create-qr-code/?data=${window.location}`
      );
     const closeModal = () => {
      qrModal.style.display = "none";
      document.removeEventListener("keydown", keyboardListener);
     };
     const openModal = () => {
      qrModal.style.display = "";
      document.addEventListener("keydown", keyboardListener);
     };
     const keyboardListener = (e) => {
      if (e.keyCode === 27) {
       closeModal();
      }
     };
     const closeBtn = template.querySelector(".smv-ar-qrcode-modal__close");
     closeBtn.addEventListener("click", () => {
      closeModal();
     });
     qrModal.addEventListener("click", (e) => {
      closeModal();
     });
     const qrModalContent = template.querySelector(
      ".smv-ar-qrcode-modal__content"
     );
     qrModalContent.addEventListener("click", (e) => {
      e.stopPropagation();
     });
     shadowRoot.appendChild(template);
     arButton.addEventListener("click", () => {
      openModal();
     });
    }
    shadowRoot.appendChild(arButton);
   }
  }
 );
</script>

2. Add this template to your page - it will configure the AR icon:

<template id="template-smv-ar-qrcode">
 <style>
  *, ::before, ::after {
   box-sizing: border-box;
  }

  .smv-ar-qrcode-modal {
   display: flex;
   flex-direction: column;
   align-items: center;
   justify-content: center;
   position: absolute;
   top:0;
   right: 0;
   bottom: 0;
   left: 0;
   background-color: rgba(0,0,0,.5);
   overflow: hidden;
   z-index: 100;
  }

  .smv-ar-qrcode-modal__content {
   display: flex;
   flex-direction: column;
   gap: 20px;
   position: relative;
   min-width: 0;
   min-height: 0;
   padding: 20px;
   border-radius: 4px;
   background-color: #fff;
  }

  .smv-ar-qrcode-modal__header {
   font-size: 15px;
   font-weight: bold;
   text-align: center;
  }
  .smv-ar-qrcode-modal__footer {
   text-align: right;
  }

  .smv-ar-qrcode-modal__btn-close {
   display: inline;
   font-size: 14px;
   color: #888;
   cursor: pointer;
  }

  .smv-ar-qrcode-modal__close {
   position: absolute;
   top: 0px;
   right: 0px;
   width: 28px;
   height: 28px;
   color: #a5a5a5;
   font: normal 24px/1 Arial, monospace;
   text-align: center;
   cursor: pointer;
   speak: none;
   -webkit-font-smoothing: antialiased;
  }

  .smv-ar-qrcode-modal__close:before {
   display: inline;
   position: static;
   color: inherit !important;
   font: inherit !important;
   content: '×';
   vertical-align: middle;
   -webkit-font-smoothing: inherit !important;
  }
 </style>
 <div class="smv-ar-qrcode-modal">
  <div class="smv-ar-qrcode-modal__content" role="dialog" aria-modal="true">
   <div class="smv-ar-qrcode-modal__close" role="button" aria-label="Close dialog" tabindex="0"></div>

   <div class="smv-ar-qrcode-modal__header">
    <slot name="header">Scan QR code to view in AR</slot>
   </div>
   <div class="smv-ar-qrcode-modal__body">
    <img role="link" alt="QR code link">
   </div>
  </div>
 </div>
</template>

3. Overlay the AR icon by adding <smv-ios-ar-button> inside the div of any model, image, spin or other asset. Point it to the USDZ model via the data-src attribute.

The following example will create a gallery of two zooming images and one GLB momdel. The AR icon will show on the GLB model - it could also be shown on the other gallery assets if desired:

<div class="Sirv">
  <div data-src="https://demo.sirv.com/demo/sirv-media-viewer/customclosets/A.png" data-type="zoom"></div>
  <div data-src="https://demo.sirv.com/demo/sirv-media-viewer/customclosets/B.png" data-type="zoom"></div>
  <div data-src="https://demo.sirv.com/demo/sirv-media-viewer/customclosets/5.glb" data-options="animation.autoplay:true; animation.timeScale:2">
    <smv-ios-ar-button data-src="https://demo.sirv.com/demo/sirv-media-viewer/customclosets/5.usdz"></smv-ios-ar-button>
  </div>
</div>

Troubleshooting and support

You can validate your GLB model by submitting it to the GLB editor. It will produce a report describing any issues in your GLB file.

If you need help configuring 3D models on your website/app, send a message to the Sirv support team and we'll reply within 24 hours.

Credit

Thanks to Tomás Laulhé for the RobotExpressive example model, licensed under CC0.

Was this article helpful?

Array

Get help from a Sirv expert

help ukraine help ukraine Powered by Ukrainian determination and British ingenuity

How can you support Ukraine