Tips for development with frameworks + WebGL libs:
1. Import three.js plugins in webpack.
2. Handle Canvas and Renderer as a WebApp view.
3. Remove Canvas and GL context appropriately.
4. Assets compressing.
Agenda
Slide 6
Slide 6 text
Import three.js plugins
in webpack
Slide 7
Slide 7 text
• OrbitControls
• EffectComposer and Passes
• CSS3DRenderer
• Loaders
and others.
Plugins for three.js
Slide 8
Slide 8 text
Plugins do not support
es6 module import/export
Problem
so far.
import * as THREE from 'three';
THREE.OrbitControls = require( 'imports-loader?THREE!
exports-loader?THREE.OrbitControls!../node_modules/
three/examples/js/controls/OrbitControls.js' );
// snip
const controls = new THREE.OrbitControls( camera );
Slide 11
Slide 11 text
import * as THREE from 'three';
THREE.OrbitControls = require( 'imports-loader?THREE!
exports-loader?THREE.OrbitControls!../node_modules/
three/examples/js/controls/OrbitControls.js' );
// snip
const controls = new THREE.OrbitControls( camera );
Slide 12
Slide 12 text
import * as THREE from 'three';
THREE.OrbitControls = require( 'imports-loader?THREE!
exports-loader?THREE.OrbitControls!../node_modules/
three/examples/js/controls/OrbitControls.js' );
// snip
const controls = new THREE.OrbitControls( camera );
Slide 13
Slide 13 text
import * as THREE from 'three';
THREE.OrbitControls = require( 'imports-loader?THREE!
exports-loader?THREE.OrbitControls!../node_modules/
three/examples/js/controls/OrbitControls.js' );
// snip
const controls = new THREE.OrbitControls( camera );
Slide 14
Slide 14 text
import * as THREE from 'three';
THREE.OrbitControls = require( 'imports-loader?THREE!
exports-loader?THREE.OrbitControls!../node_modules/
three/examples/js/controls/OrbitControls.js' );
// snip
const controls = new THREE.OrbitControls( camera );
Slide 15
Slide 15 text
import * as THREE from 'three';
THREE.OrbitControls = require( 'imports-loader?THREE!
exports-loader?THREE.OrbitControls!../node_modules/
three/examples/js/controls/OrbitControls.js' );
// snip
const controls = new THREE.OrbitControls( camera );
Slide 16
Slide 16 text
import * as THREE from 'three';
THREE.OrbitControls = require( 'imports-loader?THREE!
exports-loader?THREE.OrbitControls!../node_modules/
three/examples/js/controls/OrbitControls.js' );
// snip
const controls = new THREE.OrbitControls( camera );
Slide 17
Slide 17 text
demo
http://localhost:8080/
Slide 18
Slide 18 text
Warnings will be ignored in the production build.
http://localhost:8000/demo1-webpack/
Slide 19
Slide 19 text
Handle Canvas
as a WebApp view
Slide 20
Slide 20 text
Canvas element has to be handled
by the WebApp framework.
Problem
Slide 21
Slide 21 text
Use mounted canvas,
then bind Renderer in
mounted or
componentDidMount hock.
Solution
Slide 22
Slide 22 text
import * as THREE from 'three';
export default {
name: 'view-3d',
data () {
return {
width: 200,
height: 200
mount a canvas element
beforeDestroy() {
this.running = false;
while ( this.scene.children.length > 0 ) {
const object = this.scene.children[ this.scene.children.length - 1 ];
deepDispose( object );
this.scene.remove( object );
}
this.renderer.dispose();
this.renderer.forceContextLoss();
this.renderer.context = undefined;
this.renderer.domElement = undefined;
// until next garbage collection
this.$el.width = 1;
this.$el.height = 1;
},
Children of scene consist of
• Meshes
• Lights
• Object3d
Slide 33
Slide 33 text
function deepDispose( object3D ) {
object3D.traverse( object3D => dispose( object3D ) );
}
function dispose ( object3D ) {
if ( !! object3D.geometry ) {
object3D.geometry.dispose();
object3D.geometry = undefined;
}
if ( !! object3D.material && object3D.material instanceof Array ) {
object3D.material.forEach( material => disposeMaterial( material ) );
Slide 34
Slide 34 text
function deepDispose( object3D ) {
object3D.traverse( object3D => dispose( object3D ) );
}
function dispose ( object3D ) {
if ( !! object3D.geometry ) {
object3D.geometry.dispose();
object3D.geometry = undefined;
}
if ( !! object3D.material && object3D.material instanceof Array ) {
object3D.material.forEach( material => disposeMaterial( material ) );
Slide 35
Slide 35 text
function dispose ( object3D ) {
if ( !! object3D.geometry ) {
object3D.geometry.dispose();
object3D.geometry = undefined;
}
if ( !! object3D.material && object3D.material instanceof Array ) {
object3D.material.forEach( material => disposeMaterial( material ) );
} else if ( !! object3D.material ) {
disposeMaterial( material );
}
Slide 36
Slide 36 text
function disposeMaterial( material ) {
if ( !! material.map ) {
material.map.dispose();
material.map = undefined;
}
// do that for normalMap, specularMap and bumpMap too
material.dispose();
material = undefined;
}
Slide 37
Slide 37 text
Before unmount:
• Stop render loop.
• Dispose all geoms, materials and
textures recursively.
• Release renderer and context.
• Resize canvas to 1px * 1px.
const DRACO_PATH = './libs/';
const DRACO_TYPE = !! window.WebAssembly ? 'wasm' : 'js';
const dracoLoader = new THREE.DRACOLoader(
DRACO_PATH,
{ type: DRACO_TYPE }
);
dracoLoader.load( './model/rameses.drc', ( geometry ) => {
const material = new THREE.MeshStandardMaterial( {
map: texture
} );
const mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
The decoder will be loaded from external file.
You need set the path to it.
Slide 57
Slide 57 text
const DRACO_PATH = './libs/';
const DRACO_TYPE = !! window.WebAssembly ? 'wasm' : 'js';
const dracoLoader = new THREE.DRACOLoader(
DRACO_PATH,
{ type: DRACO_TYPE }
);
dracoLoader.load( './model/rameses.drc', ( geometry ) => {
const material = new THREE.MeshStandardMaterial( {
map: texture
} );
const mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
The recorder is available in both Wasm and JS.
Use preferred version.
Slide 58
Slide 58 text
const DRACO_PATH = './libs/';
const DRACO_TYPE = !! window.WebAssembly ? 'wasm' : 'js';
const dracoLoader = new THREE.DRACOLoader(
DRACO_PATH,
{ type: DRACO_TYPE }
);
dracoLoader.load( './model/rameses.drc', ( geometry ) => {
const material = new THREE.MeshStandardMaterial( {
map: texture
} );
const mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
Make a loader instance for three.js
Slide 59
Slide 59 text
const DRACO_PATH = './libs/';
const DRACO_TYPE = !! window.WebAssembly ? 'wasm' : 'js';
const dracoLoader = new THREE.DRACOLoader(
DRACO_PATH,
{ type: DRACO_TYPE }
);
dracoLoader.load( './model/rameses.drc', ( geometry ) => {
const material = new THREE.MeshStandardMaterial( {
map: texture
} );
const mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
} );
Load a drc file