-
Notifications
You must be signed in to change notification settings - Fork 116
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #549 from pixiv/mtoon-1.0
Implementation of VRMC_materials_mtoon-1.0
- Loading branch information
Showing
25 changed files
with
2,442 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
242
packages/three-vrm-materials-mtoon/examples/loader-plugin.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
Oops, something went wrong.