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.