Skip to content

Commit

Permalink
Merge pull request #549 from pixiv/mtoon-1.0
Browse files Browse the repository at this point in the history
Implementation of VRMC_materials_mtoon-1.0
  • Loading branch information
Yutaka "FMS_Cat" Obuchi authored Jul 13, 2021
2 parents 06892f3 + 8ac4b9c commit 0195c72
Show file tree
Hide file tree
Showing 25 changed files with 2,442 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
- node_modules
- packages/three-vrm/node_modules
- packages/three-vrm-core/node_modules
- packages/three-vrm-materials-mtoon/node_modules
- packages/three-vrm-springbone/node_modules
- packages/types-vrm-0.0/node_modules
- packages/types-vrmc-materials-mtoon-1.0/node_modules
Expand Down Expand Up @@ -52,6 +53,8 @@ jobs:
- packages/three-vrm/types
- packages/three-vrm-core/lib
- packages/three-vrm-core/types
- packages/three-vrm-materials-mtoon/lib
- packages/three-vrm-materials-mtoon/types
- packages/three-vrm-springbone/lib
- packages/three-vrm-springbone/types
- packages/types-vrm-0.0/types
Expand Down
5 changes: 5 additions & 0 deletions packages/three-vrm-materials-mtoon/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# @pixiv/three-vrm-materials-mtoon

MToon (toon material) module for @pixiv/three-vrm

You cannot use this yet! It's a candidate implementation for VRM 1.0
20 changes: 20 additions & 0 deletions packages/three-vrm-materials-mtoon/examples/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>

<html>
<head>
<meta charset="utf-8" />
<title>three-vrm-materials-mtoon examples</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
</head>

<body>
<h1>examples of <a href="https://github.com/pixiv/three-vrm/packages/three-vrm-materials-mtoon">@pixiv/three-vrm-materials-mtoon</a></h1>
<p>
<a href="loader-plugin.html">loader-plugin.html</a><br />
Import an MToon material from gltf
</p>
</body>
</html>
242 changes: 242 additions & 0 deletions packages/three-vrm-materials-mtoon/examples/loader-plugin.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
<!DOCTYPE html>

<html>
<head>
<meta charset="utf-8" />
<title>three-vrm example</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<style>
body {
margin: 0;
}
canvas {
display: block;
}
</style>
</head>

<body>
<script src="https://unpkg.com/[email protected]/build/three.js"></script>
<script src="https://unpkg.com/[email protected]/examples/js/loaders/GLTFLoader.js"></script>
<script src="https://unpkg.com/[email protected]/examples/js/controls/OrbitControls.js"></script>
<script src="../lib/three-vrm-materials-mtoon.js"></script>
<script>
// renderer
const renderer = new THREE.WebGLRenderer();
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setPixelRatio( window.devicePixelRatio );
document.body.appendChild( renderer.domElement );

// camera
const camera = new THREE.PerspectiveCamera( 30.0, window.innerWidth / window.innerHeight, 0.1, 20.0 );
camera.position.set( 0.0, 0.0, 10.0 );

// camera controls
const controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.screenSpacePanning = true;
controls.target.set( 0.0, 0.0, 0.0 );
controls.update();

// scene
const scene = new THREE.Scene();

// light
const light = new THREE.DirectionalLight( 0xffffff );
scene.add( light );

// gltf and vrm
let currentGltf = null;

const loader = new THREE.GLTFLoader();

loader.register( ( parser ) => {

const plugin = new THREE_VRM_MATERIALS_MTOON.MToonMaterialLoaderPlugin( parser );
return plugin;

} );

function load( url ) {

loader.crossOrigin = 'anonymous';
loader.load(

url,

( gltf ) => {

if ( currentGltf ) {

scene.remove( currentGltf.scene );
disposeScene( currentGltf.scene );

}

scene.add( gltf.scene );

console.log( gltf );

currentGltf = gltf;

},

( progress ) => console.log( 'Loading model...', 100.0 * ( progress.loaded / progress.total ), '%' ),

( error ) => console.error( error )

);

}

load( './models/cube.gltf' );

function disposeMaterial( material ) {

Object.values( material ).forEach( ( property ) => {

if ( property?.isTexture ) {

property.dispose();

}

} );

if ( material.uniforms ) {

Object.values( material.uniforms ).forEach( ( uniform ) => {

const value = uniform?.value;

if ( value?.isTexture ) {

value.dispose();

}

} );

}

material.dispose();

}

function disposeMesh( mesh ) {

const geometry = mesh.geometry;

if ( geometry ) {

geometry.dispose();

}

const skeleton = mesh.skeleton;

if ( skeleton ) {

skeleton.dispose();

}

const materialOrMaterials = mesh.material;

if ( Array.isArray( materialOrMaterials ) ) {

materialOrMaterials.forEach( ( material ) => {

disposeMaterial( material );

} );

} else {

disposeMaterial( materialOrMaterials );

}

}

function disposeScene( scene ) {

scene.traverse( ( object ) => {

if ( object.isMesh ) {

disposeMesh( object );

}

} );

}

// helpers
const gridHelper = new THREE.GridHelper( 10, 10 );
scene.add( gridHelper );

const axesHelper = new THREE.AxesHelper( 5 );
scene.add( axesHelper );

// animate
const clock = new THREE.Clock();
clock.start();

function animate() {

requestAnimationFrame( animate );

const delta = clock.getDelta();

const theta = clock.elapsedTime;
const cosTheta = Math.cos( theta );
const sinTheta = Math.sin( theta );
light.position.set( cosTheta, 2.0, sinTheta ).normalize();

if ( currentGltf != null ) {

const mtoonMaterials = currentGltf.userData.vrmMToonMaterials;

for ( const material of mtoonMaterials ) {

material.update( delta );

}

}

renderer.render( scene, camera );

}

animate();

// dnd handler
window.addEventListener( 'dragover', function( event ) {

event.preventDefault();

} );

window.addEventListener( 'drop', function( event ) {

event.preventDefault();

// read given file then convert it to blob url
const files = event.dataTransfer.files;
if ( !files ) { return; }
const file = files[0];
if ( !file ) { return; }
const blob = new Blob( [ file ], { type: "application/octet-stream" } );
const url = URL.createObjectURL( blob );
load( url );

} );
</script>
</body>
</html>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 0195c72

Please sign in to comment.