Skip to main content

Extending with three.js

WebGi is built on three.js. The API makes it possible to access all the three.js and WebGL internals to build upon the default functionality while keeping consistent with all WebGi plugins.

We provide wrappers and helpers for most common requirements in photorealistic rendering to reduce boilerplate and keep a consistent codebase.

three.js classes, constants and types can be imported directly from webgi:

import { 
Object3D, Material,
Vector3, Vector2,
Texture,
sRGBEncoding
// ...
} from "webgi";

Importing Data

Importing models, materials, environment maps, images, presets, json data etc can be done through AssetImporter in AssetManagerPlugin. Different file types are supported by registering three.js Loaders with the AssetImporter. For most common file types, separate plugins already exists that can be added directly.

Getting the imported three.js data

For models, the Object3D is wrapped in a Object3DModel and can be accessed by calling .modelObject

const model = await viewer.load('file.glb')
const object3d = (model as IModel).modelObject;

// Now you can modify the object
object.position.set(3,0,0);
object.rotateX(1.0);
//...

// Finally call setDirty to notify the viewer and plugins that something has changed, for effects like framefade and setting the viewer to dirty.
object.setDirty?.()
// Or set dirty in the viewer or scene directly. These will have somewhat different effects in the pipeline.
viewer.scene.setDirty()
// or
viewer.setDirty()

For textures and maps, a ITexture object is returned.

const texture = await viewer.getManager()!.importer!.importSinglePath<ITexture>('./assets/images/image.png', {generateMipmaps: false})
// Set any texture properties
texture.mapping = EquirectangularReflectionMapping // For environment maps
texture.encoding = sRGBEncoding
// Use it somewhere
await viewer.setBackground(texture);
// Access the three.js texture
const threeTex = texture.textureObject // In most cases threeTex and texture will be the same.
// Use in three.js
const object = viewer.scene.findObjectsByName('Cube')[0].modelObject
object.material.map = threeTex;
object.material.alphaMap = threeTex;
// ...

For materials, a IMaterial object is returned.

const material = await viewer.getManager()!.importer!.importSinglePath<IMaterial<MeshStandardMaterial2>>('./assets/material/metal.pmat')
// Set any properties
material.color.set(0xff0000);
...
// Set it on a mesh
mesh.setMaterial(material)
// or copy properties to another material
mesh.material.copyProps(material)

// Access the three.js material
const threeMat = material.materialObject // In most cases threeMat and material will be the same.

Creating objects and materials.

The ViewerApp provides helpers to create objects, materials, cameras.

createObject3D create empty or process and add existing Object3D to the scene

const objModel: Object3DModel = await viewer.createObject3D() // wrapper for Object3D as root object in the scene.
const obj: Object3D = objModel.modelObject // The three.js object that can be used normally, like adding new objects
// add something to obj

// or
let obj: Object3D = new Object3D()
obj.position.set(5,0,0);
// ... // add children or other properties
obj = (await viewer.createObject3D(obj)).modelObject // Returned value may or may not be same as obj

createPhysicalMaterial - Create a new physical material from a template or another material. It returns the same material if a material is passed created by the material manager.

const obj = viewer.createPhysicalMaterial({
color: 0xff0000,
roughness: 0.5,
...
})

// or
let mat = new MeshStandardMaterial()
// ...
const iMat = viewer.createPhysicalMaterial(mat) // Returned value will be a new IMaterial object.

Check the API docs for MaterialManager for more advanced material management.

There is also viewer.createCamera to create a new camera. Multiple cameras are supported but in most cases only one camera is enough(and easier to manage) for the scene. Check the Camera control manual for camera management and animation.

Export and Serialisation

Serialisation for all scene objects is handled automatically, exporting a GLB file with AssetExporterPlugin saves the complete 3d data, all settings, and serialisable plugin states.

To serialise/deserialise javascript primitives, three.js math primitives, textures and materials use functions serializeObject and deserializeObject Check the Serialisation(TODO) Manual for more details.

To serialise 3D objects, use AssetExporterPlugin to export objects in GLTF format which can later be loaded with AssetImporter normally. Saving the objects and scene hierarchy in JSON is not supported to keep a single workflow for asset management and it may contain dependencies etc which are handled in the GLTF file format. Materials and textures can also be exported to file with this.

Custom Post processing passes

WebGi exposes GenericFilterPlugin and MultiFilterPlugin with all the boilerplate code to create custom passes/filters and register with the rendering pipeline.

More details coming soon.