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" data-src="https://demo.sirv.com/model.glb"></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" data-src="https://demo.sirv.com/demo/Switch.view"></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

How to apply options

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

Options applied inline:

<div class="Sirv" data-src="https://demo.sirv.com/model.glb" data-options="sensitivity:60; shadow.intensity:30"></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" data-src="https://demo.sirv.com/model.glb" data-options="zoom:false"></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" data-src="https://demo.sirv.com/model.glb" data-options="preload:true"></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" 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>

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" data-src="https://demo.sirv.com/model.glb" data-options="sensitivity:50"></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" data-src="https://demo.sirv.com/model.glb" data-options="shadow.intensity:100; shadow.softness:20"></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. The following example makes it darker, with a setting of 0.5:

<div class="Sirv" data-src="https://demo.sirv.com/model.glb" data-options="exposure:0.5"></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" data-src="https://demo.sirv.com/model.glb" data-options="autorotate.enable:true; autorotate.speed:6; autorotate.delay:3000"></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" data-src="https://demo.sirv.com/model.glb" data-options="hint.finger:false"></div>

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

<div class="Sirv" data-src="https://demo.sirv.com/model.glb" data-options="hint.finger:false; autorotate.enable:true"></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" data-src="https://demo.sirv.com/model.glb" data-options="animation.autoplay:true; animation.timeScale:2; animation.crossfadeDuration:800"></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.

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>

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.

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:

<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. Add inside any zoom, spin, etc.

pointing it to the USDZ model via the data-src attribute:

<div data-src="https://customclosets.sirv.com/ViaClosets/Images/N%201.jpg" data-type="zoom">
  <smv-ios-ar-button data-src="https://alex.sirv.com/support/306902/ViaClosets/360s/26/NW/Item%20No%2026_N.usdz"></smv-ios-ar-button>
</div>

Support

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

RobotExpressive by Tomás Laulhé, licensed under CC0.

Was this article helpful?

Get help from a Sirv expert

help ukraine help ukraine Powered by Ukrainian determination and British ingenuity

How can you support Ukraine