3D models
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>
3D model in gallery
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.
- https://scripts.sirv.com/sirvjs/v3/graphics/icons/3d/black/icon.3d.8.svg
- https://scripts.sirv.com/sirvjs/v3/graphics/icons/3d/white/icon.3d.8.svg
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.