123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- <!DOCTYPE HTML>
- <html lang="en">
- <head>
- <title>three.js webgl - deferred rendering [morphing + skinning]</title>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
- <link type="text/css" rel="stylesheet" href="main.css">
- </head>
- <body>
- <div id="container"></div>
- <script type="module">
- import * as THREE from '../build/three.module.js';
- import Stats from './jsm/libs/stats.module.js';
- import { GUI } from './jsm/libs/dat.gui.module.js';
- import { GLTFLoader } from './jsm/loaders/GLTFLoader.js';
- import { WebGLDeferredRenderer } from './jsm/renderers/WebGLDeferredRenderer.js';
- var WIDTH = window.innerWidth;
- var HEIGHT = window.innerHeight;
- var windowHalfX = WIDTH / 2;
- var windowHalfY = HEIGHT / 2;
- var mouseX = 0, mouseY = 0;
- var NEAR = 1.0, FAR = 350.0;
- var VIEW_ANGLE = 45;
- var renderer, camera, scene, stats, clock, mixer;
- var numLights = 40;
- var lights = [];
- var transparentObjects = [];
- var ready = false;
- init();
- animate();
- function init() {
- renderer = new WebGLDeferredRenderer();
- renderer.setSize( WIDTH, HEIGHT );
- camera = new THREE.PerspectiveCamera( VIEW_ANGLE, WIDTH / HEIGHT, NEAR, FAR );
- camera.position.z = 150;
- scene = new THREE.Scene();
- stats = new Stats();
- var container = document.getElementById( 'container' );
- container.appendChild( renderer.domElement );
- container.appendChild( stats.domElement );
- initModel();
- initRoom();
- initLights();
- initGui();
- document.addEventListener( 'mousemove', onDocumentMouseMove, false );
- window.addEventListener( 'resize', onWindowResize, false );
- clock = new THREE.Clock();
- }
- function initModel() {
- var loader = new GLTFLoader();
- loader.load( 'models/gltf/RobotExpressive/RobotExpressive.glb', function ( gltf ) {
- var model = gltf.scene;
- model.position.y -= 30;
- model.scale.multiplyScalar( 10 );
- model.traverse( function ( o ) {
- if ( ! o.isMesh ) return;
- o.material.emissive = o.material.color.clone().multiplyScalar( 0.3 );
- } );
- mixer = new THREE.AnimationMixer( model );
- var dance = gltf.animations.find( function ( clip ) {
- return clip.name === 'Dance';
- } );
- var action = mixer.clipAction( dance );
- action.play();
- scene.add( model );
- ready = true;
- } );
- }
- function initLights() {
- var distance = 20;
- var c = new THREE.Vector3();
- var geometry = new THREE.SphereBufferGeometry( 1, 1, 1 );
- for ( var i = 0; i < numLights; i ++ ) {
- var light = new THREE.PointLight( 0xffffff, 2.0, distance );
- c.set( Math.random(), Math.random(), Math.random() ).normalize();
- light.color.setRGB( c.x, c.y, c.z );
- scene.add( light );
- lights.push( light );
- var material = new THREE.MeshBasicMaterial( { color: light.color } );
- var emitter = new THREE.Mesh( geometry, material );
- light.add( emitter );
- }
- var directionalLight = new THREE.DirectionalLight( 0x101010 );
- directionalLight.position.set( - 1, 1, 1 ).normalize();
- scene.add( directionalLight );
- var spotLight = new THREE.SpotLight( 0x404040 );
- spotLight.position.set( 0, 50, 0 );
- scene.add( spotLight );
- }
- function initRoom() {
- var size = 100;
- var geometry = new THREE.PlaneBufferGeometry( size, size );
- var material = new THREE.MeshPhongMaterial( { color: 0x222222, specular: 0x222222, shininess: 75 } );
- var transparentMaterial = new THREE.MeshPhongMaterial( { color: 0x222222, emissive: 0x88888888, specular: 0x222222, shininess: 75, opacity: 0.3, transparent: true } );
- var room = new THREE.Object3D();
- room.position.y = size / 2 - 30;
- // top
- var mesh = new THREE.Mesh( geometry, material );
- mesh.rotation.x = Math.PI / 2;
- mesh.position.y = size / 2;
- room.add( mesh );
- // bottom
- mesh = new THREE.Mesh( geometry, material );
- mesh.rotation.x = - Math.PI / 2;
- mesh.position.y = - size / 2;
- room.add( mesh );
- // left
- mesh = new THREE.Mesh( geometry, material );
- mesh.position.x = - size / 2;
- mesh.rotation.y = Math.PI / 2;
- room.add( mesh );
- // right
- mesh = new THREE.Mesh( geometry, material );
- mesh.position.x = size / 2;
- mesh.rotation.y = - Math.PI / 2;
- room.add( mesh );
- // back
- mesh = new THREE.Mesh( geometry, material );
- mesh.position.z = - size / 2;
- room.add( mesh );
- // front, to check if transparency works
- mesh = new THREE.Mesh( geometry, transparentMaterial );
- mesh.position.z = size / 2;
- mesh.scale.multiplyScalar( 0.33 );
- mesh.visible = false;
- transparentObjects.push( mesh );
- room.add( mesh );
- // back2, to check if transparency works
- mesh = new THREE.Mesh( geometry, transparentMaterial );
- mesh.position.z = - size / 4;
- mesh.scale.multiplyScalar( 0.75 );
- mesh.visible = false;
- transparentObjects.push( mesh );
- room.add( mesh );
- scene.add( room );
- }
- function initGui() {
- var gui = new GUI( { width: 280 } );
- var api = {
- 'mode': 0,
- 'transparent_objects': false
- };
- var folder = gui.addFolder( 'menu' );
- folder.add( api, 'mode', {
- 'classic': 0,
- 'light pre-pass': 1,
- 'forward': 2
- } ).onChange( function () {
- switch ( parseInt( api.mode ) ) {
- case 0:
- renderer.forwardRendering = false;
- renderer.enableLightPrePass( false );
- break;
- case 1:
- renderer.forwardRendering = false;
- renderer.enableLightPrePass( true );
- break;
- case 2:
- renderer.forwardRendering = true;
- break;
- default:
- break;
- }
- } );
- folder.add( api, 'transparent_objects' ).onChange( function () {
- for ( var i = 0, il = transparentObjects.length; i < il; i ++ ) {
- transparentObjects[ i ].visible = api[ 'transparent_objects' ];
- }
- } );
- folder.open();
- }
- function onDocumentMouseMove( event ) {
- mouseX = ( event.clientX - windowHalfX ) / 10.0;
- mouseY = ( event.clientY - windowHalfY ) / 10.0;
- }
- function onWindowResize() {
- WIDTH = window.innerWidth;
- HEIGHT = window.innerHeight;
- windowHalfX = WIDTH / 2;
- windowHalfY = HEIGHT / 2;
- renderer.setSize( WIDTH, HEIGHT );
- camera.aspect = WIDTH / HEIGHT;
- camera.updateProjectionMatrix();
- }
- function animate() {
- requestAnimationFrame( animate );
- if ( ready ) {
- update();
- render();
- }
- stats.update();
- }
- function update() {
- var delta = clock.getDelta();
- var time = Date.now() * 0.0005;
- mixer.update( delta / 2.0 );
- for ( var i = 0, il = lights.length; i < il; i ++ ) {
- var light = lights[ i ];
- var x = Math.sin( time + i * 7.0 ) * 45;
- var y = Math.cos( time + i * 5.0 ) * 45 + 20;
- var z = Math.cos( time + i * 3.0 ) * 45;
- light.position.set( x, y, z );
- }
- }
- function render() {
- camera.position.x += ( - mouseX - camera.position.x ) * .05;
- camera.position.y += ( - mouseY - camera.position.y ) * .05;
- camera.lookAt( scene.position );
- renderer.render( scene, camera );
- }
- </script>
- </body>
- </html>
|