@polygon-streaming/web-player-threejs
v2.9.2
Published
Polygon Streaming Web Player for Three.js
Readme
Polygon Streaming Web Player for Three.js
Usage
Install the package with:
npm install -S @polygon-streaming/web-player-threejsYou will also need to install Three.js:
npm install -S threeYou will need to generate a XRG file from your 3D model which you can do in the console.
Import StreamController from the package:
import * as THREE from 'three';
import { StreamController } from '@polygon-streaming/web-player-threejs';Setup Three.js:
const renderer = new THREE.WebGLRenderer();
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 4, 10);
const cameraTarget = new THREE.Vector3(0, 2, 0);
camera.lookAt(cameraTarget);Instanciate the stream controller:
const streamController = new StreamController(camera, renderer, scene, cameraTarget, {
cameraType: 'nonPlayer',
triangleBudget: 5000000,
mobileTriangleBudget: 3000000
});Add a streaming model, passing it a model URL and a Group to act as a model parent. You can get the model URL by going to the models section of the console and clicking on the three dots next to your model and selecting "Copy asset ID"
const modelParent = new THREE.Group();
modelParent.position.set(0, 1, 0);
scene.add(modelParent);
streamController.addModel('<Model URL>', modelParent, {
qualityPriority: 1
});Call the stream controller's update method in the animation loop:
function animate() {
controls.update();
renderer.render(scene, camera);
streamController.update();
}
renderer.setAnimationLoop(animate);To Play an Embedded or VRM Animation
streamController.playAnimation(modelParent, 'animationName', 0.2);The second argument can be the name of the animation or if you don't know the name an index e.g. 0 for the first animation. The third argument is the transition duration and is optional, it will default to one second. This method should be called after the initial model data has loaded. VRM animations needs to be provided in the streaming model options. Below is an example of passing in two VRM animations. See the vrmAnimations parameter in the Streamable Model Parameters section for more information.
streamController.addModel('/model.xrg', modelParent, {
vrmAnimations: [
{
name: 'idle',
asset: '/Idle.vrma',
default: true
},
{
name: 'yawn',
asset: '/Yawn.vrma',
loop: false
}
]
});To Animate a VRM Expression
streamController.animateVrmExpression(modelParent, 'expressionName', {
times: [0, 0.1, 0.2],
values: [0, 1, 0]
});The second argument is the expression name and has to exist in the VRM file that the XRG was generated from. The third argument is the animation keyframes.
To Set the VRM Look At Target
The following code will cause the eyes of the model to follow the mouse cursor. setVrmLookAtTarget() needs to be called after the initial model data has loaded like in the EVENT_MODEL_LOAD event handler.
import { StreamController, EVENT_MODEL_LOAD } from '@polygon-streaming/web-player-threejs';
const vrmLookAtTarget = new THREE.Object3D();
camera.add(vrmLookAtTarget);
window.addEventListener('mousemove', (event) => {
vrmLookAtTarget.position.x = 10.0 * ((event.clientX - 0.5 * window.innerWidth) / window.innerHeight);
vrmLookAtTarget.position.y = -10.0 * ((event.clientY - 0.5 * window.innerHeight) / window.innerHeight);
});
streamController.addEventListener(EVENT_MODEL_LOAD, function(event) {
if (event.isVrm && vrmLookAtTarget != null) {
streamController.setVrmLookAtTarget(modelParent, vrmLookAtTarget);
}
});Files Required at the Web Root
Polygon Streaming expects the service worker that is used to cache model data to be available at the web root e.g. /service-worker.js. Models use KTX2 textures so you will need to make the basis transcoder files available at the web root e.g. /lib/basis_transcoder.js and /lib/basis_transcoder.wasm. If you use Vite to bundle your application you can handle both of these requirements with the following config.
vite.confg.js:
import { resolve } from 'path';
import { defineConfig } from 'vite';
import { viteStaticCopy } from 'vite-plugin-static-copy';
import { normalizePath } from 'vite';
export default defineConfig({
plugins: [
viteStaticCopy({
targets: [
{
src: normalizePath(resolve(__dirname, './node_modules/@polygon-streaming/web-player-threejs/dist/service-worker.js')),
dest: ''
},
{
src: normalizePath(resolve(__dirname, './node_modules/three/examples/jsm/libs/basis/basis_transcoder.*')),
dest: 'lib'
}
]
})
],
server: {
open: '/',
port: 8080
}
});Stream Controller Parameters
- camera (Required): The camera used in the scene.
- renderer (Required): The WebGL renderer used in the scene.
- scene (Required): The scene object.
- cameraTarget (Required): The camera target which is a Vector3. If you are using orbit controls it would be controls.target.
- options (Optional): All options are optional. The options are:
- cameraType: 'nonPlayer' | 'player', default: 'nonPlayer'
- nonPlayer: A camera that is not attached to a player e.g. a camera that orbits an object.
- player: A camera that is attached to a player.
- triangleBudget: number, default: 5000000. The maximum amount of triangles that you want to be in the scene at any single point.
- mobileTriangleBudget: number, default: 3000000. The triangle budget used on a mobile device. If it is set to 0 it will use the non-mobile triangle budget.
- minimumDistance: number, default: 0.01. The smallest possible distance to the camera.
- distanceFactor: number, default: 1.1. Preference for nearby objects over objects further away. Values above one mean a preference for nearby objects. Values below one mean a preference for objects further away. One is neutral.
- maximumQuality: number, default: 15000. Stops improving geometry that exceeds the maximum quality. This can be used to stop far away objects from showing more detail which can be wasteful. Setting it to 0 means there is no maximum quality.
- closeUpDistance: number, default: 3. The distance where it starts using close-up distance factor. Set it to 0 to not use close-up distance factor.
- closeUpDistanceFactor: number, default: 5. The distance factor used when close-up to an object. Should be higher than the standard distance factor.
- iOSMemoryLimit: number, default 0. The maximum amount of memory in MB that meshes and textures can consume on iOS devices to avoid the page crashing. Use 0 to let Polygon Streaming determine the limit or -1 for no limit.
- showLoadingModel: boolean, default: true. Whether to show the animated loading model when loading streaming models.
- loadingModelUrl: string, default: null. URL of a custom animated loading GLB file that overrides the default one.
- cameraType: 'nonPlayer' | 'player', default: 'nonPlayer'
Streamable Model Parameters
- URL (Required): URL of the XRG model. If it doesn't end with .xrg it will append model.xrg to the URL.
- model parent (Required): The scene object that the streaming model will be attached to.
- options (Optional): All options are optional. The options are:
- qualityPriority: number, default: 1. How much to prioritize the quality of this model relative to the quality of other models in the scene. This parameter does nothing if this is the only model in the scene.
- initialTrianglePercent: number, default: 0.1. Percentage of triangle budget to initialize the model with.
- castShadows: boolean, default: true. Whether the model should cast shadows.
- receiveShadows: boolean, default: true. Whether the model should receive shadows.
- forceDoubleSided: boolean, default: false. Render the model double sided regardless of the setting in the model file.
- useAlpha: boolean, default: true. Whether to render semi-transparency in materials. You might turn this off to increase performance but all your materials will render opaque.
- playAnimationAutomatically: boolean, default: true. Whether to play the embedded or VRM animation automatically.
- animation: string or number, default: null. The name or index of the embedded animation to play. An index value of 0 is the first animation. If no value is supplied it will play the first animation. For VRM animations it will play the default animation. If no animation is set as default it will use this option.
- vrmAnimations: array, default: null. An array of VRM animation data.
- name: string. The name of the animation. This is used in the playAnimation method.
- asset: URL. The URL of the VRMA animation file.
- loop: boolean, default: true. You would set this to false if you want the animation to play once i.e. for an action. Non-looping animations will go back to the default animation when they finish.
- default: boolean, default: false. The default animation is the animation that plays after a non-looping animation. This is usually the idle animation. The default animation will always loop.
- environmentMap: texture, default: null. A cube map environment texture.
- hashCode: string, default: ''. Hash code to validate streaming model.
