├── .gitignore ├── README.md ├── exercice ├── custom.html ├── custom │ ├── geometries.js │ ├── glsl │ │ ├── ground_frag.glsl │ │ ├── ground_vert.glsl │ │ ├── skydome_frag.glsl │ │ └── skydome_vert.glsl │ ├── lights.js │ ├── main.js │ ├── materials.js │ ├── models │ │ ├── deer.js │ │ ├── environment.js │ │ ├── grass.js │ │ ├── ground.js │ │ └── rocks.js │ ├── post_processing.js │ ├── shaders.js │ └── textures.js ├── finished │ ├── geometries.js │ ├── glsl │ │ ├── ground_frag.glsl │ │ ├── ground_vert.glsl │ │ ├── skydome_frag.glsl │ │ └── skydome_vert.glsl │ ├── lights.js │ ├── main.js │ ├── materials.js │ ├── models │ │ ├── deer.js │ │ ├── environment.js │ │ ├── grass.js │ │ ├── ground.js │ │ └── rocks.js │ ├── post_processing.js │ ├── shaders.js │ └── textures.js ├── index.html └── res │ ├── deer.jpg │ ├── deer.obj │ ├── environment.png │ ├── grass.jpg │ ├── grass.obj │ ├── ground_0.jpg │ ├── ground_1.jpg │ ├── noise.png │ ├── rock.obj │ ├── rock_diffuse.jpg │ ├── rock_normal.jpg │ └── scene.json ├── intro ├── base │ ├── base.js │ └── index.html └── slides │ ├── Callouts_Internet_LOL.png │ ├── Callouts_Internet_OMG.png │ ├── Callouts_Internet_RAD.png │ ├── Callouts_Positive_Hot.png │ ├── Callouts_Positive_WOW.png │ ├── base.png │ ├── cover.jpg │ ├── fragment_operations.jpg │ ├── intro_0_stats.png │ ├── intro_stats_1.png │ ├── intro_stats_2.png │ ├── intro_stats_3.png │ ├── intro_stats_4.png │ ├── shaders.png │ ├── stats.psd │ ├── tp.psd │ └── webgl_graphics_pipeline.jpg ├── libre ├── exercices.txt ├── flamand.js └── fox.js └── three.js ├── build └── three.js └── examples └── js ├── controls └── OrbitControls.js ├── loaders └── OBJLoader.js ├── postprocessing ├── EffectComposer.js ├── MaskPass.js ├── RenderPass.js ├── ShaderPass.js └── UnrealBloomPass.js └── shaders ├── ConvolutionShader.js ├── CopyShader.js ├── FXAAShader.js ├── LuminosityHighPassShader.js ├── RGBShiftShader.js ├── SSAOShader.js └── VignetteShader.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/* 2 | /res/grass/ 3 | /res/dino/ 4 | /res/animals/ 5 | /res/ 6 | /libre/ 7 | /lines.html 8 | /_three.js/ 9 | /save/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # epic_workshop 2 | 3 | ![result](intro/slides/cover.jpg) 4 | 5 | il y a un slide deck ici pour l'intro et un peu de contexte: https://slides.com/nicolasbarradeau/three-mon-ami/ 6 | 7 | pré-requis: 8 | 9 | * télécharger ou cloner ce repo 10 | * installer [chrome shader editor extension](https://chrome.google.com/webstore/detail/shader-editor/ggeaidddejpbakgafapihjbgdlbbbpob) 11 | * un serveur local ([xampp](https://www.apachefriends.org/fr/index.html) ou autre) 12 | 13 | j'ai extrait certains fichiers de THREE pour éviter de télécharger tout le repo (725Mo au 09/12/16) 14 | vous pouvez toutefois l'installer à la racine du dossier cloné si vous souhaitez explorer l'API [THREE.js](https://github.com/mrdoob/three.js/) 15 | 16 | ### origine des ressources 17 | 18 | maillages: 19 | 20 | * deer http://www.turbosquid.com/FullPreview/Index.cfm/ID/243576 (aka "bichon") 21 | * grass http://www.turbosquid.com/FullPreview/Index.cfm/ID/703699 22 | * rock http://www.turbosquid.com/FullPreview/Index.cfm/ID/733996 23 | 24 | lumières: 25 | j'ai repris quasiment tel quel les lumières de cet exemple 26 | https://threejs.org/examples/webgl_lights_hemisphere.html 27 | 28 | environment: 29 | le map d'environnement vient de 30 | http://www.mettle.com/mettle-skybox-sneek-peek-free-sample/ 31 | 32 | pour placer les objets, j'ai utilisé l'éditeur de scène de THREE 33 | https://threejs.org/editor/ 34 | -------------------------------------------------------------------------------- /exercice/custom.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | scene 6 | 7 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /exercice/custom/geometries.js: -------------------------------------------------------------------------------- 1 | var geometries = function( exports ){ 2 | 3 | var loader, queue, name, onComplete; 4 | 5 | exports.load = function( urls, callback ){ 6 | 7 | loader = new THREE.OBJLoader(); 8 | onComplete = callback; 9 | queue = urls || []; 10 | loadNext(); 11 | 12 | }; 13 | 14 | function loadNext(){ 15 | 16 | if( queue.length == 0 ){ 17 | 18 | if( onComplete )onComplete(exports); 19 | return; 20 | 21 | } 22 | 23 | var url = queue.shift(); 24 | 25 | var bits = url.split( '/' ); 26 | name = bits[ bits.length - 1 ].split('.')[0]; 27 | 28 | loader.load( url, onLoaded ); 29 | 30 | } 31 | 32 | function onLoaded( group ){ 33 | 34 | exports[ name ] = group.children[0].geometry; 35 | loadNext(); 36 | 37 | } 38 | 39 | return exports; 40 | 41 | }( {} ); -------------------------------------------------------------------------------- /exercice/custom/glsl/ground_frag.glsl: -------------------------------------------------------------------------------- 1 | 2 | uniform sampler2D ground_0; 3 | uniform sampler2D ground_1; 4 | uniform sampler2D noise; 5 | 6 | uniform float repeat; 7 | uniform float time; 8 | 9 | varying vec2 vUv; 10 | 11 | void main(){ 12 | 13 | vec2 tuv = vUv * repeat; 14 | vec4 col0 = texture2D( ground_0, tuv ); 15 | vec4 col1 = texture2D( ground_1, tuv ); 16 | vec4 grad = clamp( texture2D( noise, tuv ) * .5 + time, vec4(0.),vec4(1.) ); 17 | vec4 color = mix( col0, col1, grad ); 18 | 19 | gl_FragColor = color; 20 | } 21 | -------------------------------------------------------------------------------- /exercice/custom/glsl/ground_vert.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | void main(){ 3 | 4 | vUv = uv; 5 | gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1. ); 6 | 7 | } -------------------------------------------------------------------------------- /exercice/custom/glsl/skydome_frag.glsl: -------------------------------------------------------------------------------- 1 | 2 | uniform vec3 topColor; 3 | uniform vec3 bottomColor; 4 | uniform float offset; 5 | uniform float exponent; 6 | 7 | varying vec3 vWorldPosition; 8 | 9 | void main() { 10 | 11 | float h = normalize( vWorldPosition + offset ).y; 12 | gl_FragColor = vec4( mix( bottomColor, topColor, max( pow( max( h , 0.0), exponent ), 0.0 ) ), 1.0 ); 13 | 14 | } -------------------------------------------------------------------------------- /exercice/custom/glsl/skydome_vert.glsl: -------------------------------------------------------------------------------- 1 | 2 | varying vec3 vWorldPosition; 3 | 4 | void main() { 5 | 6 | vec4 worldPosition = modelMatrix * vec4( position, 1.0 ); 7 | vWorldPosition = worldPosition.xyz; 8 | 9 | gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); 10 | 11 | } -------------------------------------------------------------------------------- /exercice/custom/lights.js: -------------------------------------------------------------------------------- 1 | var lights = function(exports){ 2 | 3 | exports.init = function( scene, onComplete ){ 4 | 5 | shaderLoader.load( [ 6 | 7 | "finished/glsl/skydome_vert.glsl", 8 | "finished/glsl/skydome_frag.glsl" 9 | 10 | ], 11 | function(){ 12 | 13 | createSky( scene ); 14 | createLight( scene ); 15 | 16 | if( onComplete )onComplete(); 17 | } ); 18 | }; 19 | 20 | function createSky( scene ){ 21 | 22 | //dome de lumière 23 | var hemiLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, 0.9 ); 24 | hemiLight.color.setHSL( 0.6, 1, 0.6 ); 25 | hemiLight.groundColor.setHSL( 0.095, 1, 0.75 ); 26 | hemiLight.position.set( 0, 500, 0 ); 27 | scene.add( hemiLight ); 28 | 29 | // arrire plan dégradé 30 | var uniforms = { 31 | topColor: { value:hemiLight.color }, 32 | bottomColor: { value: new THREE.Color( 0xffffff ) }, 33 | offset: { value: 1000 }, 34 | exponent: { value: 0.6 } 35 | }; 36 | 37 | var skyGeo = new THREE.SphereGeometry( 4000, 32, 15 ); 38 | var skyMat = new THREE.ShaderMaterial( { 39 | uniforms: uniforms, 40 | vertexShader: shaderLoader.skydome_vert, 41 | fragmentShader: shaderLoader.skydome_frag, 42 | side: THREE.BackSide } ); 43 | 44 | var sky = new THREE.Mesh( skyGeo, skyMat ); 45 | scene.add( sky ); 46 | 47 | } 48 | function createLight( scene ){ 49 | 50 | var dirLight = new THREE.DirectionalLight( 0xffffff, 1 ); 51 | dirLight.color.setHSL( 0.1, 1, 0.95 ); 52 | dirLight.position.set( -1, 1.75, 1 ); 53 | dirLight.position.multiplyScalar( 50 ); 54 | 55 | //ajoute des ombres à cette lumière 56 | 57 | dirLight.castShadow = true; 58 | dirLight.shadow.mapSize.width = 2048; 59 | dirLight.shadow.mapSize.height = 2048; 60 | 61 | var d = 50; 62 | dirLight.shadow.camera.left = -d; 63 | dirLight.shadow.camera.right = d; 64 | dirLight.shadow.camera.top = d; 65 | dirLight.shadow.camera.bottom = -d; 66 | 67 | dirLight.shadow.camera.far = 3500; 68 | dirLight.shadow.bias = 0.00001; 69 | 70 | scene.add( dirLight ); 71 | 72 | } 73 | 74 | return exports; 75 | 76 | }( {} ); 77 | -------------------------------------------------------------------------------- /exercice/custom/main.js: -------------------------------------------------------------------------------- 1 | 2 | var PI = Math.PI; 3 | var PI2 = PI * 2; 4 | var RAD = PI / 180; 5 | function lerp ( t, a, b ){ return a + t * ( b - a ); } 6 | function norm( t, a, b ){return ( t - a ) / ( b - a );} 7 | function map( t, a0, b0, a1, b1 ){ return lerp( norm( t, a0, b0 ), a1, b1 );} 8 | 9 | var w, h, scene, camera, controls, renderer; 10 | var ground, grass, rocks, deer, environment; 11 | 12 | function init(){ 13 | 14 | w = window.innerWidth; 15 | h = window.innerHeight; 16 | 17 | scene = new THREE.Scene(); 18 | camera = new THREE.PerspectiveCamera( 60, 16 / 9, 1, 10000 ); 19 | camera.position.set( -40, 10, 25 ); 20 | 21 | renderer = new THREE.WebGLRenderer(); 22 | document.body.appendChild( renderer.domElement ); 23 | 24 | controls = new THREE.OrbitControls( camera, renderer.domElement ); 25 | 26 | window.addEventListener( "resize", resize ); 27 | resize(); 28 | 29 | //charge les objets 30 | console.log( "load geometries" ); 31 | var urls = [ 32 | 'res/deer.obj', 33 | 'res/grass.obj', 34 | 'res/rock.obj' 35 | ]; 36 | geometries.load( urls, initTextures ); 37 | 38 | } 39 | 40 | function initTextures(){ 41 | 42 | //charge les textures 43 | console.log( "load textures" ); 44 | var urls = [ 45 | 'res/deer.jpg', 46 | 'res/environment.png', 47 | 'res/grass.jpg', 48 | 'res/ground_0.jpg', 49 | 'res/rock_diffuse.jpg', 50 | 'res/rock_normal.jpg' 51 | ]; 52 | textures.load( urls, initLights ); 53 | } 54 | 55 | function initLights(){ 56 | 57 | //charge et crée les lumières 58 | console.log( "init lights" ); 59 | // lights.init( scene, createObjects ); 60 | createObjects(); 61 | 62 | } 63 | 64 | function createObjects(){ 65 | //les géométries et les textures sont chargées 66 | //on peut créer des matériaux et des meshes 67 | console.log( "create objects" ); 68 | var config = [ 69 | { 70 | name:"deer", 71 | params:{ map:textures.deer} 72 | }, 73 | { 74 | name:"environment", 75 | params:{ map:textures.environment } 76 | }, 77 | { 78 | name:"grass", 79 | params:{ map:textures.grass } 80 | }, 81 | { 82 | name:"ground", 83 | params:{ map:textures.ground_0} 84 | }, 85 | { 86 | name:"rock", 87 | params:{ 88 | map:textures.rock_diffuse, 89 | normalMap: textures.rock_normal 90 | } 91 | } 92 | ]; 93 | 94 | //initialise les matériaux qui seront utillisé par les objets 95 | materials.init( config ); 96 | 97 | //crée le bichon 98 | deer.init( scene ); 99 | 100 | //crée l'arrière plan 101 | environment.init( scene ); 102 | 103 | //crée le terrain 104 | ground.init( scene ); 105 | 106 | //ajooute les cailloux 107 | rocks.init( scene ); 108 | 109 | //ajoute la végétation 110 | grass.init( scene, ground, rocks ); 111 | 112 | //lance une boucle de mise à jour 113 | update(); 114 | 115 | } 116 | 117 | function update(){ 118 | 119 | requestAnimationFrame( update ); 120 | controls.update(); 121 | renderer.render( scene, camera ); 122 | 123 | } 124 | 125 | function resize(){ 126 | 127 | w = window.innerWidth; 128 | h = window.innerHeight; 129 | renderer.setSize(w,h); 130 | camera.aspect = w / h; 131 | camera.updateProjectionMatrix(); 132 | 133 | } 134 | 135 | window.onload = function(){ 136 | init(); 137 | }; -------------------------------------------------------------------------------- /exercice/custom/materials.js: -------------------------------------------------------------------------------- 1 | var materials = function( exports ){ 2 | 3 | 4 | /** 5 | * crée une série de mateiaux à partir d'un tableau d'objets de configuration 6 | * @param config 7 | */ 8 | exports.init = function( configurations ){ 9 | 10 | configurations.forEach( function( config ){ 11 | exports.add(config); 12 | }); 13 | 14 | }; 15 | 16 | exports.add = function( config ){ 17 | 18 | config.params.color = 0xFFFFFF; 19 | var mat = new THREE.MeshBasicMaterial(config.params); 20 | // mat.roughness = .75; 21 | // mat.metalness = .05; 22 | exports[ config.name ] = mat; 23 | 24 | }; 25 | 26 | return exports; 27 | 28 | }({}); -------------------------------------------------------------------------------- /exercice/custom/models/deer.js: -------------------------------------------------------------------------------- 1 | var deer = function( exports ) { 2 | 3 | exports.init = function( scene ){ 4 | 5 | var mesh = new THREE.Mesh( geometries.deer, materials.deer ); 6 | scene.add( mesh ); 7 | 8 | }; 9 | 10 | return exports; 11 | 12 | }({}); -------------------------------------------------------------------------------- /exercice/custom/models/environment.js: -------------------------------------------------------------------------------- 1 | var environment = function( exports ){ 2 | 3 | var mesh, material; 4 | exports.init = function( scene ){ 5 | 6 | material = materials.environment; 7 | mesh = new THREE.Mesh( new THREE.SphereBufferGeometry( 1,128,64 ), material ); 8 | scene.add( mesh ); 9 | 10 | }; 11 | return exports; 12 | 13 | }({}); -------------------------------------------------------------------------------- /exercice/custom/models/grass.js: -------------------------------------------------------------------------------- 1 | var grass = function( exports ) { 2 | 3 | 4 | var group, material; 5 | exports.init = function( scene, ground, rocks ){ 6 | 7 | group = new THREE.Object3D(); 8 | exports.group = group; 9 | scene.add( group ); 10 | 11 | var mesh = new THREE.Mesh( geometries.grass, materials.grass ); 12 | group.add( mesh ); 13 | 14 | }; 15 | 16 | return exports; 17 | 18 | }({}); -------------------------------------------------------------------------------- /exercice/custom/models/ground.js: -------------------------------------------------------------------------------- 1 | var ground = function( exports ) { 2 | 3 | var mesh, material; 4 | exports.init = function( scene, radius, height ) { 5 | 6 | exports.radius = radius = radius || 50; 7 | exports.height = height = height || .25; 8 | 9 | mesh = new THREE.Mesh(new THREE.IcosahedronBufferGeometry(radius, 6), materials.ground ); 10 | 11 | scene.add(mesh); 12 | 13 | exports.mesh = mesh; 14 | }; 15 | return exports; 16 | 17 | }({}); -------------------------------------------------------------------------------- /exercice/custom/models/rocks.js: -------------------------------------------------------------------------------- 1 | 2 | var rocks = function (exports) { 3 | 4 | var group; 5 | exports.init = function( scene ){ 6 | 7 | //conteneur pour les futurs objets 8 | group = new THREE.Object3D(); 9 | exports.group = group; 10 | scene.add( group ); 11 | 12 | var mesh = new THREE.Mesh( geometries.rock, materials.rock ); 13 | group.add( mesh ); 14 | 15 | }; 16 | 17 | return exports; 18 | }({}); 19 | -------------------------------------------------------------------------------- /exercice/custom/post_processing.js: -------------------------------------------------------------------------------- 1 | var post_processing = function( exports ){ 2 | 3 | var composer, rt, renderPass, bloom, shift, vignette, ssao, fxaa, startTime; 4 | 5 | exports.init = function( renderer, scene, camera, w, h ){ 6 | 7 | //on crée des "passes" ; des couches d'effets 8 | 9 | //cette passe dessine simplement la scène dans une texture 10 | renderPass = new THREE.RenderPass( scene, camera ); 11 | 12 | //applique un anti alias 13 | fxaa = new THREE.ShaderPass(THREE.FXAAShader); 14 | fxaa.uniforms.resolution.value.set( 1 / w, 1 / h ); 15 | 16 | //assombrit les coins de l'écran 17 | vignette = new THREE.ShaderPass( THREE.VignetteShader ); 18 | // vignette.uniforms.offset.value = 1; 19 | // vignette.uniforms.darkness.value = 2; 20 | 21 | //cette passe disperse les canaux de couleur 22 | shift = new THREE.ShaderPass( THREE.RGBShiftShader ); 23 | // shift.uniforms.amount.value = 0.0015; 24 | // shift.uniforms.angle.value = 0; 25 | 26 | //renforce les ombres 27 | ssao = new THREE.ShaderPass( THREE.SSAOShader ); 28 | // ssao.uniforms.cameraNear.value = 10; 29 | // ssao.uniforms.cameraFar.value = 100; 30 | // ssao.uniforms.onlyAO.value = 0; 31 | // ssao.uniforms.aoClamp.value = .5; 32 | // ssao.uniforms.lumInfluence.value = .5; 33 | 34 | //blOOOOOOOOm... 35 | bloom = new THREE.UnrealBloomPass(new THREE.Vector2(w,h), 3.5, 0.4, 0.85);//1.0, 9, 0.5, 512); 36 | 37 | //stocke les passes dans un certain ordre 38 | var passes = [ 39 | renderPass, 40 | // shift, 41 | // ssao, 42 | // bloom, 43 | vignette, 44 | fxaa, 45 | ]; 46 | 47 | //on affichera le résultat de la pile d'effets 48 | passes[ passes.length - 1 ].renderToScreen = true; 49 | 50 | //on crée un composer qui va exécuter toutes les passes à la suite et afficher le résultat 51 | //rt = new THREE.WebGLRenderTarget( THREE.Math.nextPowerOfTwo(w), THREE.Math.nextPowerOfTwo(h) ); 52 | composer = new THREE.EffectComposer( renderer );//, rt ); 53 | 54 | //on ajoute les passes de rendu 55 | passes.forEach( function( pass ){ 56 | composer.addPass( pass ); 57 | } ); 58 | 59 | startTime = Date.now(); 60 | 61 | }; 62 | 63 | exports.setSize = function( w,h ){ 64 | composer.setSize(w,h); 65 | fxaa.uniforms.resolution.value.set(1/w, 1/h); 66 | }; 67 | 68 | exports.render = function(){ 69 | 70 | //bloom.strength = 4 * ( Math.sin( Date.now() * 0.001 ) * .5 + .5 ); 71 | //bloom.radius = ( Math.cos( Date.now() * 0.001 ) * .5 + .5 ); 72 | 73 | // https://www.shadertoy.com/view/lsf3WH 74 | // shift.uniforms.angle.value += RAD; 75 | // shift.uniforms.amount.value = ( Math.sin( shift.uniforms.angle.value ) * .5 + .5 ) * .1; 76 | 77 | composer.render(0.05); 78 | }; 79 | 80 | return exports; 81 | }({}); -------------------------------------------------------------------------------- /exercice/custom/shaders.js: -------------------------------------------------------------------------------- 1 | var shaderLoader = function( exports ){ 2 | 3 | var loader, queue, name, onComplete; 4 | 5 | exports.load = function( urls, callback ){ 6 | 7 | loader = new XMLHttpRequest(); 8 | loader.onload = onLoaded; 9 | onComplete = callback; 10 | queue = urls || []; 11 | loadNext(); 12 | 13 | }; 14 | 15 | function loadNext(){ 16 | 17 | if( queue.length == 0 ){ 18 | if( onComplete )onComplete( exports ); 19 | return; 20 | } 21 | 22 | var url = queue.shift(); 23 | var bits = url.split( '/' ); 24 | name = bits[ bits.length - 1 ].split('.')[0]; 25 | 26 | loader.open( "GET", url ); 27 | loader.send(); 28 | 29 | } 30 | 31 | function onLoaded( e ){ 32 | exports[ name ] = e.target.responseText; 33 | loadNext(); 34 | } 35 | 36 | return exports; 37 | 38 | }( {} ); -------------------------------------------------------------------------------- /exercice/custom/textures.js: -------------------------------------------------------------------------------- 1 | var textures = function( exports ){ 2 | 3 | var loader, queue, name, onComplete; 4 | 5 | exports.load = function( urls, callback ){ 6 | 7 | loader = new THREE.TextureLoader(); 8 | onComplete = callback; 9 | queue = urls || []; 10 | loadNext(); 11 | 12 | }; 13 | 14 | function loadNext(){ 15 | 16 | if( queue.length == 0 ){ 17 | 18 | if( onComplete )onComplete( exports ); 19 | return; 20 | 21 | } 22 | 23 | var url = queue.shift(); 24 | 25 | var bits = url.split( '/' ); 26 | name = bits[ bits.length - 1 ].split('.')[0]; 27 | 28 | loader.load( url, onLoaded ); 29 | 30 | } 31 | 32 | function onLoaded( texture ){ 33 | 34 | exports[ name ] = texture; 35 | loadNext(); 36 | 37 | } 38 | 39 | return exports; 40 | 41 | }( {} ); -------------------------------------------------------------------------------- /exercice/finished/geometries.js: -------------------------------------------------------------------------------- 1 | var geometries = function( exports ){ 2 | 3 | var loader, queue, name, onComplete; 4 | 5 | exports.load = function( urls, callback ){ 6 | 7 | loader = new THREE.OBJLoader(); 8 | onComplete = callback; 9 | queue = urls || []; 10 | loadNext(); 11 | 12 | }; 13 | 14 | function loadNext(){ 15 | 16 | if( queue.length == 0 ){ 17 | 18 | if( onComplete )onComplete(exports); 19 | return; 20 | 21 | } 22 | 23 | var url = queue.shift(); 24 | 25 | var bits = url.split( '/' ); 26 | name = bits[ bits.length - 1 ].split('.')[0]; 27 | 28 | loader.load( url, onLoaded ); 29 | 30 | } 31 | 32 | function onLoaded( group ){ 33 | 34 | exports[ name ] = group.children[0].geometry; 35 | loadNext(); 36 | 37 | } 38 | 39 | return exports; 40 | 41 | }( {} ); -------------------------------------------------------------------------------- /exercice/finished/glsl/ground_frag.glsl: -------------------------------------------------------------------------------- 1 | 2 | uniform sampler2D ground_0; 3 | uniform sampler2D ground_1; 4 | uniform sampler2D noise; 5 | 6 | uniform float repeat; 7 | uniform float time; 8 | 9 | varying vec2 vUv; 10 | 11 | void main(){ 12 | 13 | vec2 tuv = vUv * repeat; 14 | vec4 col0 = texture2D( ground_0, tuv ); 15 | vec4 col1 = texture2D( ground_1, tuv ); 16 | vec4 grad = clamp( texture2D( noise, tuv ) * .5 + time, vec4(0.),vec4(1.) ); 17 | vec4 color = mix( col0, col1, grad ); 18 | 19 | gl_FragColor = color; 20 | } 21 | -------------------------------------------------------------------------------- /exercice/finished/glsl/ground_vert.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | void main(){ 3 | 4 | vUv = uv; 5 | gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1. ); 6 | 7 | } -------------------------------------------------------------------------------- /exercice/finished/glsl/skydome_frag.glsl: -------------------------------------------------------------------------------- 1 | 2 | uniform vec3 topColor; 3 | uniform vec3 bottomColor; 4 | uniform float offset; 5 | uniform float exponent; 6 | 7 | varying vec3 vWorldPosition; 8 | 9 | void main() { 10 | 11 | float h = normalize( vWorldPosition + offset ).y; 12 | gl_FragColor = vec4( mix( bottomColor, topColor, max( pow( max( h , 0.0), exponent ), 0.0 ) ), 1.0 ); 13 | 14 | } -------------------------------------------------------------------------------- /exercice/finished/glsl/skydome_vert.glsl: -------------------------------------------------------------------------------- 1 | 2 | varying vec3 vWorldPosition; 3 | 4 | void main() { 5 | 6 | vec4 worldPosition = modelMatrix * vec4( position, 1.0 ); 7 | vWorldPosition = worldPosition.xyz; 8 | 9 | gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); 10 | 11 | } -------------------------------------------------------------------------------- /exercice/finished/lights.js: -------------------------------------------------------------------------------- 1 | var lights = function(exports){ 2 | 3 | exports.init = function( scene, onComplete ){ 4 | 5 | shaderLoader.load( [ 6 | "finished/glsl/skydome_vert.glsl", 7 | "finished/glsl/skydome_frag.glsl" 8 | ], 9 | function(){ 10 | createSky( scene ); 11 | if( onComplete )onComplete(); 12 | } ); 13 | 14 | createLight( scene ); 15 | 16 | }; 17 | 18 | function createSky( scene ){ 19 | 20 | //dome de lumière 21 | var hemiLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, 0.9 ); 22 | hemiLight.color.setHSL( 0.6, 1, 0.6 ); 23 | hemiLight.groundColor.setHSL( 0.095, 1, 0.75 ); 24 | hemiLight.position.set( 0, 500, 0 ); 25 | scene.add( hemiLight ); 26 | 27 | // arrire plan dégradé 28 | var uniforms = { 29 | topColor: { value:hemiLight.color }, 30 | bottomColor: { value: new THREE.Color( 0xffffff ) }, 31 | offset: { value: 1000 }, 32 | exponent: { value: 0.6 } 33 | }; 34 | 35 | var skyGeo = new THREE.SphereGeometry( 4000, 32, 15 ); 36 | var skyMat = new THREE.ShaderMaterial( { 37 | uniforms: uniforms, 38 | vertexShader: shaderLoader.skydome_vert, 39 | fragmentShader: shaderLoader.skydome_frag, 40 | side: THREE.BackSide } ); 41 | 42 | var sky = new THREE.Mesh( skyGeo, skyMat ); 43 | scene.add( sky ); 44 | 45 | } 46 | function createLight( scene ){ 47 | 48 | var dirLight = new THREE.DirectionalLight( 0xffffff, 1 ); 49 | dirLight.color.setHSL( 0.1, 1, 0.95 ); 50 | dirLight.position.set( -1, 1.75, 1 ); 51 | dirLight.position.multiplyScalar( 50 ); 52 | 53 | //ajoute des ombres à cette lumière 54 | 55 | dirLight.castShadow = true; 56 | dirLight.shadow.mapSize.width = 2048; 57 | dirLight.shadow.mapSize.height = 2048; 58 | 59 | var d = 50; 60 | dirLight.shadow.camera.left = -d; 61 | dirLight.shadow.camera.right = d; 62 | dirLight.shadow.camera.top = d; 63 | dirLight.shadow.camera.bottom = -d; 64 | 65 | dirLight.shadow.camera.far = 3500; 66 | dirLight.shadow.bias = 0.00001; 67 | 68 | scene.add( dirLight ); 69 | 70 | } 71 | 72 | return exports; 73 | 74 | }( {} ); 75 | -------------------------------------------------------------------------------- /exercice/finished/main.js: -------------------------------------------------------------------------------- 1 | var PI = Math.PI; 2 | var PI2 = PI * 2; 3 | var RAD = PI / 180; 4 | function lerp ( t, a, b ){ return a + t * ( b - a ); } 5 | function norm( t, a, b ){return ( t - a ) / ( b - a );} 6 | function map( t, a0, b0, a1, b1 ){ return lerp( norm( t, a0, b0 ), a1, b1 );} 7 | 8 | var w, h, scene, camera, controls, renderer; 9 | var ground, grass, rocks, deer, environment; 10 | 11 | function init(){ 12 | 13 | w = window.innerWidth; 14 | h = window.innerHeight; 15 | 16 | scene = new THREE.Scene(); 17 | camera = new THREE.PerspectiveCamera( 60, 16 / 9, 1, 10000 ); 18 | camera.position.set( -40, 10, 25 ); 19 | 20 | renderer = new THREE.WebGLRenderer(); 21 | renderer.shadowMap.enabled = true; 22 | renderer.shadowMap.type = THREE.PCFSoftShadowMap; 23 | document.body.appendChild( renderer.domElement ); 24 | 25 | // postprocessing 26 | post_processing.init( renderer, scene, camera ); 27 | 28 | controls = new THREE.OrbitControls( camera, renderer.domElement ); 29 | controls.minDistance = 35; 30 | controls.maxDistance = 100; 31 | controls.minPolarAngle = RAD * 10; 32 | controls.maxPolarAngle = RAD * 90; 33 | controls.target.y = 10; 34 | 35 | window.addEventListener( "resize", resize ); 36 | resize(); 37 | 38 | //charge les objets 39 | console.log( "load geometries" ); 40 | var urls = [ 41 | 'res/deer.obj', 42 | 'res/grass.obj', 43 | 'res/rock.obj' 44 | ]; 45 | geometries.load( urls, initTextures ); 46 | 47 | } 48 | 49 | function initTextures(){ 50 | 51 | //charge les textures 52 | console.log( "load textures" ); 53 | var urls = [ 54 | 'res/deer.jpg', 55 | 'res/environment.png', 56 | 'res/grass.jpg', 57 | 'res/ground_0.jpg', 58 | 'res/rock_diffuse.jpg', 59 | 'res/rock_normal.jpg' 60 | ]; 61 | textures.load( urls, initLights ); 62 | } 63 | 64 | function initLights(){ 65 | 66 | //charge et crée les lumières 67 | console.log( "init lights" ); 68 | lights.init( scene, createObjects ); 69 | 70 | } 71 | 72 | function createObjects(){ 73 | 74 | //les géométries et les textures sont chargées 75 | //on peut créer des matériaux et des meshes 76 | console.log( "create objects" ); 77 | var config = [ 78 | { 79 | name:"deer", 80 | params:{ map:textures.deer} 81 | }, 82 | { 83 | name:"environment", 84 | params:{ map:textures.environment } 85 | }, 86 | { 87 | name:"grass", 88 | params:{ map:textures.grass } 89 | }, 90 | { 91 | name:"ground", 92 | params:{ map:textures.ground_0} 93 | }, 94 | { 95 | name:"rock", 96 | params:{ 97 | map:textures.rock_diffuse, 98 | normalMap: textures.rock_normal 99 | } 100 | } 101 | ]; 102 | 103 | //ajoute un brouillard de distance 104 | scene.fog = new THREE.Fog( 0xffffff, 1, 5000 ); 105 | 106 | //initialise les matériaux qui seront utillisé par les objets 107 | materials.init( config ); 108 | 109 | //crée le bichon 110 | deer.init( scene ); 111 | 112 | //crée l'arrière plan 113 | environment.init( scene ); 114 | 115 | //crée le terrain 116 | ground.init( scene ); 117 | 118 | //ajooute les cailloux 119 | rocks.init( scene ); 120 | 121 | //ajoute la végétation 122 | grass.init( scene, ground, rocks ); 123 | 124 | //lance une boucle de mise à jour 125 | update(); 126 | 127 | } 128 | 129 | function update(){ 130 | 131 | requestAnimationFrame( update ); 132 | 133 | controls.update(); 134 | 135 | // renderer.render( scene, camera ); 136 | 137 | post_processing.render(); 138 | 139 | } 140 | 141 | function resize(){ 142 | 143 | w = window.innerWidth; 144 | h = window.innerHeight; 145 | 146 | renderer.setSize(w,h); 147 | 148 | post_processing.setSize(w,h); 149 | 150 | camera.aspect = w / h; 151 | camera.updateProjectionMatrix(); 152 | 153 | } 154 | 155 | window.onload = function(){ 156 | init(); 157 | }; -------------------------------------------------------------------------------- /exercice/finished/materials.js: -------------------------------------------------------------------------------- 1 | var materials = function( exports ){ 2 | 3 | 4 | /** 5 | * crée une série de mateiaux à partir d'un tableau d'objets de configuration 6 | * @param config 7 | */ 8 | exports.init = function( configurations ){ 9 | 10 | configurations.forEach( function( config ){ 11 | exports.add(config); 12 | }); 13 | 14 | }; 15 | 16 | exports.add = function( config ){ 17 | 18 | config.params.color = 0xFFFFFF; 19 | var mat = new THREE.MeshStandardMaterial(config.params); 20 | mat.roughness = .75; 21 | mat.metalness = .05; 22 | exports[ config.name ] = mat; 23 | 24 | }; 25 | 26 | return exports; 27 | 28 | }({}); -------------------------------------------------------------------------------- /exercice/finished/models/deer.js: -------------------------------------------------------------------------------- 1 | var deer = function( exports ) { 2 | 3 | 4 | var group, material; 5 | exports.init = function( scene ){ 6 | 7 | 8 | 9 | var mesh = new THREE.Mesh( geometries.deer, materials.deer ); 10 | 11 | // materials.deer.side = THREE.BackSide; 12 | // /* 13 | var vertices = mesh.geometry.getAttribute( "position" ).array; 14 | var buffer = new Uint16Array( vertices.length / 3 ); 15 | for( var i = 0; i < vertices.length; i+= 3 ){ 16 | 17 | buffer[i] = i; 18 | buffer[i+1] = i + 2; 19 | buffer[i+2] = i + 1; 20 | 21 | } 22 | var indices = new THREE.BufferAttribute( buffer,1 ); 23 | geometries.deer.setIndex( indices ); 24 | 25 | //*/ 26 | mesh.castShadow = true; 27 | mesh.receiveShadow = true; 28 | scene.add( mesh ); 29 | 30 | }; 31 | 32 | return exports; 33 | 34 | }({}); -------------------------------------------------------------------------------- /exercice/finished/models/environment.js: -------------------------------------------------------------------------------- 1 | var environment = function( exports ){ 2 | 3 | var mesh, material; 4 | exports.init = function( scene ){ 5 | 6 | material = materials.environment; 7 | mesh = new THREE.Mesh( new THREE.SphereBufferGeometry( 1,128,64 ), material ); 8 | material.blending = THREE.AdditiveBlending; 9 | material.transparent = true; 10 | 11 | mesh.scale.multiplyScalar( -1000 ); 12 | scene.add( mesh ); 13 | exports.start(); 14 | 15 | }; 16 | 17 | //animation 18 | var raf; 19 | exports.stop = function(){ cancelAnimationFrame(raf); }; 20 | exports.start = function(){ exports.stop(); update(); }; 21 | function update(){ 22 | raf = requestAnimationFrame(update); 23 | material.opacity = .35;// + .25 * Math.sin( Date.now() * 0.001 ); 24 | mesh.rotation.x -= RAD * .01; 25 | mesh.rotation.y -= RAD * .01; 26 | 27 | } 28 | 29 | 30 | return exports; 31 | 32 | }({}); -------------------------------------------------------------------------------- /exercice/finished/models/grass.js: -------------------------------------------------------------------------------- 1 | var grass = function( exports ) { 2 | 3 | 4 | var group, material; 5 | exports.init = function( scene, ground, rocks ){ 6 | 7 | group = new THREE.Object3D(); 8 | exports.group = group; 9 | scene.add( group ); 10 | 11 | /* 12 | var mesh = new THREE.Mesh( geometries.grass, materials.grass ); 13 | 14 | //recentre le mesh des plantes 15 | var geom = geometries.grass; 16 | geom.computeBoundingBox(); 17 | 18 | //center est me centre de la bounding box 19 | var bbox = geom.boundingBox; 20 | var center = bbox.min.add( bbox.max.clone().sub( bbox.min ).multiplyScalar( .5 ) ); 21 | 22 | //si on soustrait le centre de la bounding box, ça recentre le mesh 23 | mesh.position.sub( center ); 24 | 25 | //et on le décale en hauteur pour qu'il soit posé sur le sol 26 | mesh.position.y += ( bbox.max.y - bbox.min.y ); 27 | group.add( mesh ); 28 | //*/ 29 | 30 | centerGeometry( geometries.grass, .1 ); 31 | 32 | var scale = new THREE.Vector2( .35,1.1 ); 33 | distributeObjects( ground, 200, scale ); 34 | 35 | 36 | }; 37 | 38 | 39 | function centerGeometry( geom, scale ){ 40 | 41 | //recentre le mesh des plantes 42 | geom.computeBoundingBox(); 43 | var bbox = geom.boundingBox; 44 | 45 | //center est lme centre de la bounding box 46 | var center = bbox.min.add( bbox.max.clone().sub( bbox.min ).multiplyScalar( .5 ) ); 47 | var height = ( bbox.max.y - bbox.min.y ); 48 | 49 | //itère sur chaque entrée des vertices 50 | var attr = geom.getAttribute( "position" ); 51 | 52 | for( var i =0; i < attr.array.length; i += 3 ){ 53 | 54 | //repositionne 55 | attr.array[ i ] -= center.x; 56 | 57 | attr.array[ i + 1 ] -= center.y; 58 | attr.array[ i + 1 ] += height; 59 | 60 | attr.array[ i + 2 ] -= center.z; 61 | 62 | //re scale 63 | attr.array[i] *= scale; 64 | attr.array[i+1] *= scale; 65 | attr.array[i+2] *= scale; 66 | 67 | } 68 | 69 | } 70 | 71 | function distributeObjects( ground, count, scale ){ 72 | 73 | var center = new THREE.Vector3(0,ground.radius * ground.height,0); 74 | var earthCenter = new THREE.Vector3(0,-ground.radius * 10,0); 75 | 76 | for( var i = 0; i < count; i++ ){ 77 | 78 | var mesh = new THREE.Mesh( geometries.grass, materials.grass ); 79 | mesh.castShadow = true; 80 | mesh.receiveShadow = true; 81 | 82 | var lat = ( Math.sqrt( Math.random() ) )* Math.PI / 2; 83 | var lon = Math.random() * Math.PI * 2; 84 | 85 | mesh.position.set( Math.sin( lat ) * Math.sin( lon ), 86 | Math.cos( lat ) * ground.height, 87 | Math.sin( lat ) * Math.cos( lon ) ).multiplyScalar( ground.radius ).sub( center ); 88 | 89 | mesh.lookAt( earthCenter ); 90 | mesh.rotateX( - Math.PI / 2 ); 91 | mesh.scale.multiplyScalar( lerp( Math.random(), scale.x, scale.y ) ); 92 | group.add( mesh ); 93 | 94 | } 95 | } 96 | 97 | 98 | //animation 99 | var raf; 100 | exports.stop = function(){ cancelAnimationFrame(raf); }; 101 | exports.start = function(){ exports.stop(); update(); }; 102 | function update(){ 103 | raf = requestAnimationFrame(update); 104 | material.uniforms.time.value = Math.sin( Date.now() * 0.001 ); 105 | } 106 | 107 | return exports; 108 | 109 | }({}); -------------------------------------------------------------------------------- /exercice/finished/models/ground.js: -------------------------------------------------------------------------------- 1 | var ground = function( exports ) { 2 | 3 | var mesh, material; 4 | exports.init = function( scene, radius, height ){ 5 | 6 | exports.radius = radius = radius || 50; 7 | exports.height = height = height || .25; 8 | 9 | textures.ground_0.wrapS = textures.ground_0.wrapT = THREE.RepeatWrapping; 10 | textures.ground_0.repeat.multiplyScalar( 6 ); 11 | 12 | // mesh = new THREE.Mesh(new THREE.SphereBufferGeometry(radius, 32, 32, 0, PI, 0, PI), materials.ground ); 13 | mesh = new THREE.Mesh(new THREE.IcosahedronBufferGeometry(radius, 6), materials.ground); 14 | 15 | mesh.receiveShadow = true; 16 | mesh.rotateX( -PI / 2 ); 17 | mesh.scale.z = height; 18 | mesh.position.y = -radius * height; 19 | exports.mesh = mesh; 20 | 21 | scene.add( mesh ); 22 | 23 | /* 24 | // on va avoir besoin de manipuler des textures sur la vertex shader 25 | // ce qui n'est pas toujours supporté. il faut donc vérifier si cette 26 | // opération est possible 27 | //https://github.com/KhronosGroup/WebGL/blob/90ceaac0c4546b1aad634a6a5c4d2dfae9f4d124/conformance-suites/1.0.0/extra/webgl-info.html 28 | var gl = renderer.getContext(); 29 | if( gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS) == 0 ) { 30 | throw new Error( "vertex shader cannot read textures" ); 31 | } 32 | 33 | shaderLoader.load([ 34 | "finished/glsl/ground_vert.glsl", 35 | "finished/glsl/ground_frag.glsl" 36 | ], function () { 37 | 38 | textures.load( [ 39 | 'res/ground_0.jpg', 40 | 'res/ground_1.jpg', 41 | 'res/noise.png' 42 | ], onTexturesLoaded ); 43 | 44 | }); 45 | //*/ 46 | 47 | }; 48 | 49 | function onTexturesLoaded() { 50 | 51 | textures.ground_0.wrapS = textures.ground_0.wrapT = THREE.RepeatWrapping; 52 | textures.ground_1.wrapS = textures.ground_1.wrapT = THREE.RepeatWrapping; 53 | textures.noise.wrapS = textures.noise.wrapT = THREE.RepeatWrapping; 54 | 55 | material = new THREE.ShaderMaterial({ 56 | uniforms: { 57 | ground_0: {type: "t", value: textures.ground_0}, 58 | ground_1: {type: "t", value: textures.ground_1}, 59 | noise: {type: "t", value: textures.noise}, 60 | repeat: {type: 'f', value: 10}, 61 | time: {type: 'f', value: 0 } 62 | }, 63 | vertexShader: shaderLoader.ground_vert, 64 | fragmentShader: shaderLoader.ground_frag, 65 | }); 66 | 67 | mesh.material = material; 68 | } 69 | 70 | //animation 71 | var raf; 72 | exports.stop = function(){ cancelAnimationFrame(raf); }; 73 | exports.start = function(){ exports.stop(); update(); }; 74 | function update(){ 75 | raf = requestAnimationFrame(update); 76 | material.uniforms.time.value = Math.sin( Date.now() * 0.001 ); 77 | } 78 | 79 | return exports; 80 | 81 | }({}); -------------------------------------------------------------------------------- /exercice/finished/models/rocks.js: -------------------------------------------------------------------------------- 1 | 2 | var rocks = function (exports) { 3 | 4 | var group; 5 | exports.init = function( scene ){ 6 | 7 | //conteneur pour les futurs objets 8 | group = new THREE.Object3D(); 9 | exports.group = group; 10 | scene.add( group ); 11 | 12 | //charge une scène faite avec https://threejs.org/editor/ 13 | var xhr = new XMLHttpRequest(); 14 | xhr.onload = distributeObjects; 15 | xhr.open( "GET", "res/scene.json" ); 16 | xhr.send(); 17 | 18 | }; 19 | 20 | function createRock( matrix ){ 21 | 22 | var mesh = new THREE.Mesh( geometries.rock, materials.rock ); 23 | mesh.castShadow = true; 24 | mesh.receiveShadow = true; 25 | 26 | mesh.matrixAutoUpdate = false; 27 | mesh.updateMatrix = false; 28 | 29 | var m = new THREE.Matrix4(); 30 | m.fromArray(matrix); 31 | mesh.matrix = m; 32 | group.add( mesh ); 33 | 34 | } 35 | 36 | function distributeObjects( e ){ 37 | 38 | var json = JSON.parse( e.target.responseText ); 39 | json.object.children.forEach( function(item ){ 40 | if( item.name.toLowerCase().indexOf( "sphere") == -1 ){ 41 | createRock( item.matrix ); 42 | } 43 | }); 44 | 45 | } 46 | 47 | return exports; 48 | }({}); 49 | -------------------------------------------------------------------------------- /exercice/finished/post_processing.js: -------------------------------------------------------------------------------- 1 | var post_processing = function( exports ){ 2 | 3 | var composer, rt, renderPass, bloom, shift, vignette, ssao, fxaa, startTime; 4 | 5 | exports.init = function( renderer, scene, camera, w, h ){ 6 | 7 | //on crée des "passes" ; des couches d'effets 8 | 9 | //cette passe dessine simplement la scène dans une texture 10 | renderPass = new THREE.RenderPass( scene, camera ); 11 | 12 | //applique un anti alias 13 | fxaa = new THREE.ShaderPass(THREE.FXAAShader); 14 | fxaa.uniforms.resolution.value.set( 1 / w, 1 / h ); 15 | 16 | //assombrit les coins de l'écran 17 | vignette = new THREE.ShaderPass( THREE.VignetteShader ); 18 | // vignette.uniforms.offset.value = 1; 19 | // vignette.uniforms.darkness.value = 2; 20 | 21 | //cette passe disperse les canaux de couleur 22 | shift = new THREE.ShaderPass( THREE.RGBShiftShader ); 23 | // shift.uniforms.amount.value = 0.0015; 24 | // shift.uniforms.angle.value = 0; 25 | 26 | //renforce les ombres 27 | ssao = new THREE.ShaderPass( THREE.SSAOShader ); 28 | // ssao.uniforms.cameraNear.value = 10; 29 | // ssao.uniforms.cameraFar.value = 100; 30 | // ssao.uniforms.onlyAO.value = 0; 31 | // ssao.uniforms.aoClamp.value = .5; 32 | // ssao.uniforms.lumInfluence.value = .5; 33 | 34 | //blOOOOOOOOm... 35 | bloom = new THREE.UnrealBloomPass(new THREE.Vector2(w,h), 3.5, 0.4, 0.85);//1.0, 9, 0.5, 512); 36 | 37 | //stocke les passes dans un certain ordre 38 | var passes = [ 39 | renderPass, 40 | // shift, 41 | // ssao, 42 | // bloom, 43 | vignette, 44 | fxaa, 45 | ]; 46 | 47 | //on affichera le résultat de la pile d'effets 48 | passes[ passes.length - 1 ].renderToScreen = true; 49 | 50 | //on crée un composer qui va exécuter toutes les passes à la suite et afficher le résultat 51 | //rt = new THREE.WebGLRenderTarget( THREE.Math.nextPowerOfTwo(w), THREE.Math.nextPowerOfTwo(h) ); 52 | composer = new THREE.EffectComposer( renderer );//, rt ); 53 | 54 | //on ajoute les passes de rendu 55 | passes.forEach( function( pass ){ 56 | composer.addPass( pass ); 57 | } ); 58 | 59 | startTime = Date.now(); 60 | 61 | }; 62 | 63 | exports.setSize = function( w,h ){ 64 | composer.setSize(w,h); 65 | fxaa.uniforms.resolution.value.set(1/w, 1/h); 66 | }; 67 | 68 | exports.render = function(){ 69 | 70 | //bloom.strength = 4 * ( Math.sin( Date.now() * 0.001 ) * .5 + .5 ); 71 | //bloom.radius = ( Math.cos( Date.now() * 0.001 ) * .5 + .5 ); 72 | 73 | // https://www.shadertoy.com/view/lsf3WH 74 | // shift.uniforms.angle.value += RAD; 75 | // shift.uniforms.amount.value = ( Math.sin( shift.uniforms.angle.value ) * .5 + .5 ) * .1; 76 | 77 | composer.render(0.05); 78 | }; 79 | 80 | return exports; 81 | }({}); -------------------------------------------------------------------------------- /exercice/finished/shaders.js: -------------------------------------------------------------------------------- 1 | var shaderLoader = function( exports ){ 2 | 3 | var loader, queue, name, onComplete; 4 | 5 | exports.load = function( urls, callback ){ 6 | 7 | loader = new XMLHttpRequest(); 8 | loader.onload = onLoaded; 9 | onComplete = callback; 10 | queue = urls || []; 11 | loadNext(); 12 | 13 | }; 14 | 15 | function loadNext(){ 16 | 17 | if( queue.length == 0 ){ 18 | if( onComplete )onComplete( exports ); 19 | return; 20 | } 21 | 22 | var url = queue.shift(); 23 | var bits = url.split( '/' ); 24 | name = bits[ bits.length - 1 ].split('.')[0]; 25 | 26 | loader.open( "GET", url ); 27 | loader.send(); 28 | 29 | } 30 | 31 | function onLoaded( e ){ 32 | exports[ name ] = e.target.responseText; 33 | loadNext(); 34 | } 35 | 36 | return exports; 37 | 38 | }( {} ); -------------------------------------------------------------------------------- /exercice/finished/textures.js: -------------------------------------------------------------------------------- 1 | var textures = function( exports ){ 2 | 3 | var loader, queue, name, onComplete; 4 | 5 | exports.load = function( urls, callback ){ 6 | 7 | loader = new THREE.TextureLoader(); 8 | onComplete = callback; 9 | queue = urls || []; 10 | loadNext(); 11 | 12 | }; 13 | 14 | function loadNext(){ 15 | 16 | if( queue.length == 0 ){ 17 | 18 | if( onComplete )onComplete( exports ); 19 | return; 20 | 21 | } 22 | 23 | var url = queue.shift(); 24 | 25 | var bits = url.split( '/' ); 26 | name = bits[ bits.length - 1 ].split('.')[0]; 27 | 28 | loader.load( url, onLoaded ); 29 | 30 | } 31 | 32 | function onLoaded( texture ){ 33 | 34 | exports[ name ] = texture; 35 | loadNext(); 36 | 37 | } 38 | 39 | return exports; 40 | 41 | }( {} ); -------------------------------------------------------------------------------- /exercice/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | scene 6 | 7 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /exercice/res/deer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/exercice/res/deer.jpg -------------------------------------------------------------------------------- /exercice/res/environment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/exercice/res/environment.png -------------------------------------------------------------------------------- /exercice/res/grass.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/exercice/res/grass.jpg -------------------------------------------------------------------------------- /exercice/res/ground_0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/exercice/res/ground_0.jpg -------------------------------------------------------------------------------- /exercice/res/ground_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/exercice/res/ground_1.jpg -------------------------------------------------------------------------------- /exercice/res/noise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/exercice/res/noise.png -------------------------------------------------------------------------------- /exercice/res/rock.obj: -------------------------------------------------------------------------------- 1 | # 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware 2 | # File Created: 27.01.2008 22:46:39 3 | 4 | mtllib obj.mtl 5 | 6 | # 7 | # object low 8 | # 9 | 10 | v 11.9605 19.6000 -14.6399 11 | v 13.3723 19.4294 -13.2740 12 | v 13.1943 15.4253 -13.1341 13 | v 11.9775 15.4286 -14.4489 14 | v 10.1640 19.2194 -15.1416 15 | v 10.0121 15.2443 -15.1343 16 | v 12.0653 23.1398 -14.7877 17 | v 13.5861 23.0513 -13.2507 18 | v 9.9538 23.4217 -15.1716 19 | v 13.0044 8.4346 -12.6437 20 | v 14.2004 8.3799 -10.7352 21 | v 14.0351 5.9212 -10.6708 22 | v 12.9533 6.3944 -12.3605 23 | v 11.5954 7.9590 -13.8085 24 | v 11.5311 4.8191 -13.1338 25 | v 13.2942 3.5936 -11.0509 26 | v 13.2507 11.9218 -12.9755 27 | v 14.1627 11.9179 -10.7263 28 | v 11.7315 11.6916 -14.4682 29 | v 14.1382 15.5258 -10.8460 30 | v 14.0466 19.4574 -10.8237 31 | v 13.8163 23.2800 -10.8938 32 | v 12.7699 27.2012 -12.9177 33 | v 13.8216 27.3810 -10.5463 34 | v 11.5405 27.5166 -14.1783 35 | v 12.1294 31.3513 -12.5458 36 | v 13.2223 31.2369 -10.5402 37 | v 11.2971 31.2371 -14.0336 38 | v 12.1059 36.7494 -12.7311 39 | v 12.8838 36.6256 -10.2947 40 | v 11.2944 37.0065 -14.4656 41 | v 12.0074 40.4067 -12.4326 42 | v 12.4643 40.5792 -10.1008 43 | v 11.6214 41.2831 -13.1597 44 | v 12.0826 42.2637 -10.2310 45 | v 14.8940 8.4197 -7.5966 46 | v 14.1562 6.0248 -7.6384 47 | v 13.5751 3.7577 -7.5411 48 | v 14.9013 12.0757 -7.7600 49 | v 14.8526 15.7971 -7.6259 50 | v 14.7980 19.5156 -7.7928 51 | v 14.5132 23.4241 -7.4964 52 | v 14.6359 27.3885 -7.7102 53 | v 14.7234 31.3271 -7.3530 54 | v 14.0347 36.3975 -7.2222 55 | v 13.1754 40.8559 -6.9430 56 | v 12.7462 42.6890 -6.8814 57 | v 15.1338 9.0396 -4.2587 58 | v 14.2661 6.5573 -4.0620 59 | v 13.5012 4.1311 -3.8745 60 | v 15.4702 12.2551 -4.1223 61 | v 15.8237 15.7840 -4.3277 62 | v 16.0247 19.8830 -4.1494 63 | v 15.4565 23.4802 -4.3241 64 | v 15.0990 27.4921 -4.0544 65 | v 15.5274 31.3367 -4.0427 66 | v 15.2241 36.5158 -3.7247 67 | v 14.3220 41.1058 -3.6179 68 | v 14.2711 43.3666 -3.6210 69 | v 13.0869 44.8938 -3.5140 70 | v 11.7312 44.0176 -6.5395 71 | v 15.7922 12.6541 -0.7259 72 | v 15.3900 9.5104 -0.4533 73 | v 14.4474 7.0734 -0.4404 74 | v 16.3381 15.8339 -0.5451 75 | v 16.3251 19.5260 -0.8656 76 | v 16.0089 23.4119 -0.6934 77 | v 14.8657 26.8694 -0.9556 78 | v 15.9062 31.2662 -0.7697 79 | v 16.0997 36.6386 -0.6125 80 | v 14.9247 41.1611 -0.4491 81 | v 14.5348 43.3357 -0.6682 82 | v 13.3149 44.9972 -0.3338 83 | v 16.2296 13.0502 2.6353 84 | v 15.4155 10.1462 2.8077 85 | v 14.1356 7.9875 2.8120 86 | v 16.5024 16.0234 2.2412 87 | v 16.3125 19.5547 2.3058 88 | v 16.2388 22.8472 1.9442 89 | v 14.5649 26.5295 1.8496 90 | v 16.0466 30.7398 1.9498 91 | v 15.4335 30.6487 3.5887 92 | v 15.0556 25.9229 3.5475 93 | v 16.5119 36.4580 1.8243 94 | v 15.0548 40.9741 1.6891 95 | v 14.7681 43.1392 1.7427 96 | v 12.9815 45.0252 1.9002 97 | v 16.4037 16.2395 4.4757 98 | v 16.2201 13.6337 4.4489 99 | v 14.2722 15.7616 5.7202 100 | v 14.3300 11.7741 5.6178 101 | v 15.9272 19.4318 4.1214 102 | v 14.1250 19.5708 5.1376 103 | v 16.2755 22.9633 4.1675 104 | v 14.2531 22.9529 5.6152 105 | v 13.7684 25.8703 4.1821 106 | v 15.7778 36.6754 3.8350 107 | v 13.9025 36.8566 4.5114 108 | v 14.0539 30.7343 4.3642 109 | v 14.9270 40.5343 3.0039 110 | v 13.5665 41.9133 3.6338 111 | v 9.6948 11.5954 -14.6826 112 | v 9.2815 7.9466 -14.4682 113 | v 6.9375 11.5997 -14.9909 114 | v 6.5631 7.9091 -14.8910 115 | v 7.2556 15.1926 -15.4882 116 | v 7.3837 19.2755 -15.4851 117 | v 7.3782 23.0026 -15.5998 118 | v 9.8802 27.0980 -14.8901 119 | v 6.9502 27.5868 -14.5984 120 | v 9.4204 31.9132 -14.4815 121 | v 7.0584 30.8860 -14.3945 122 | v 9.5520 36.7575 -15.2750 123 | v 7.0251 37.1286 -15.7884 124 | v 9.1377 41.3014 -14.5593 125 | v 6.9300 40.9379 -14.5332 126 | v 11.1498 1.6961 -10.5368 127 | v 10.5963 2.2141 -12.5844 128 | v 8.8621 4.6596 -13.7792 129 | v 8.3559 1.6152 -13.2124 130 | v 8.8165 0.3754 -10.5079 131 | v 10.1600 42.9088 -12.1530 132 | v 10.5799 43.2176 -9.6657 133 | v 7.8239 43.0256 -12.4734 134 | v 8.1750 44.0433 -9.4141 135 | v 11.3652 2.0345 -7.2699 136 | v 9.3749 0.2311 -7.0425 137 | v 10.1457 44.6132 -6.1032 138 | v 11.5354 2.4831 -3.6495 139 | v 9.6144 0.8208 -3.4461 140 | v 11.2108 45.3363 -3.0685 141 | v 9.5346 45.4782 -2.6244 142 | v 8.1094 44.7626 -5.6169 143 | v 13.3189 4.7816 -0.1852 144 | v 11.7574 2.4460 -0.0037 145 | v 9.4528 1.4154 -0.0309 146 | v 11.9340 45.2683 -0.2926 147 | v 10.0104 45.2443 -0.1794 148 | v 12.5290 5.7389 3.3277 149 | v 10.7520 3.4963 3.5998 150 | v 11.8778 45.4271 1.3254 151 | v 10.4529 45.4424 1.8962 152 | v 10.4928 45.3190 2.9167 153 | v 13.4695 9.0665 4.8601 154 | v 11.5700 11.6904 6.2441 155 | v 11.2593 7.1500 5.3774 156 | v 11.6462 15.5192 5.5267 157 | v 11.6622 19.3928 5.4048 158 | v 11.5050 22.9694 5.8435 159 | v 11.3096 26.6970 4.0638 160 | v 11.2125 31.0312 4.2469 161 | v 11.2063 36.8064 4.9088 162 | v 10.9537 41.5028 4.1210 163 | v 12.4963 43.7451 3.2779 164 | v 10.5206 43.8055 3.9831 165 | v 5.9718 4.5443 -14.0908 166 | v 3.6138 8.2187 -14.7895 167 | v 3.1729 5.2015 -14.3496 168 | v 3.7685 11.6796 -15.4452 169 | v 3.9852 15.3790 -15.6430 170 | v 4.0576 19.1869 -15.6565 171 | v 3.9561 23.2517 -15.6456 172 | v 3.8141 27.0413 -15.0871 173 | v 3.4367 31.8913 -15.0570 174 | v 3.9558 36.5625 -15.5264 175 | v 4.1220 40.7572 -13.9272 176 | v 6.4667 42.3773 -13.8545 177 | v 4.1151 42.5066 -13.1853 178 | v 4.5527 43.4607 -12.0568 179 | v 4.6763 1.1055 -13.2657 180 | v 5.1771 -0.3802 -10.3653 181 | v 5.0350 43.9981 -9.7475 182 | v 5.6831 -0.5211 -6.5399 183 | v 7.4135 44.5334 -7.6304 184 | v 4.9427 44.8327 -8.0382 185 | v 6.2305 44.7473 -5.2766 186 | v 6.2699 0.5387 -3.1191 187 | v 6.8106 44.9582 -2.7866 188 | v 6.8400 1.1668 0.2975 189 | v 7.9883 45.1952 0.2801 190 | v 9.2580 1.7798 2.4197 191 | v 7.2121 3.1981 4.9462 192 | v 7.1555 1.8427 2.8775 193 | v 8.0085 45.1744 1.9101 194 | v 7.8971 44.9160 3.2552 195 | v 9.8586 5.3891 4.8565 196 | v 7.6711 8.2759 6.6377 197 | v 7.2361 5.4368 5.1043 198 | v 8.0598 11.6295 6.2858 199 | v 8.3806 15.2978 5.1134 200 | v 8.2465 19.5573 4.9478 201 | v 8.1503 23.3769 5.8549 202 | v 7.7556 26.7483 4.2856 203 | v 7.7634 31.3909 4.5969 204 | v 7.7332 36.5988 5.2791 205 | v 7.7060 41.0843 4.4588 206 | v 7.6104 43.3092 4.2234 207 | v 2.9309 2.8920 -13.9649 208 | v 0.3653 5.5158 -14.1418 209 | v 0.3956 2.9671 -13.6675 210 | v 0.9408 0.5418 -11.9403 211 | v 0.3040 8.4847 -14.7139 212 | v 0.3911 11.8621 -15.4033 213 | v 0.4386 15.3743 -15.6328 214 | v 0.6292 19.1084 -15.0559 215 | v 0.4798 23.1189 -15.2151 216 | v 0.3845 27.1086 -15.0250 217 | v 0.0086 30.9030 -15.6437 218 | v 0.4150 36.8875 -14.9229 219 | v 0.8392 40.7964 -13.4467 220 | v 0.8900 42.5809 -12.8486 221 | v 1.6787 0.0841 -9.4059 222 | v 1.3276 44.2909 -11.5789 223 | v 1.7202 44.6140 -9.6822 224 | v 2.0998 0.4194 -6.4194 225 | v 2.8463 44.9970 -7.7056 226 | v 3.3539 44.7974 -5.4753 227 | v 3.2134 2.3694 -3.2954 228 | v 4.7407 44.5448 -2.4024 229 | v 1.3999 44.5580 -5.1812 230 | v 1.8460 44.1748 -2.4279 231 | v 2.0308 2.7919 1.5279 232 | v 1.5596 3.5077 -0.8242 233 | v 4.2518 1.9431 0.3499 234 | v 5.0900 44.5978 -0.0156 235 | v 3.3713 43.6981 0.3916 236 | v 3.6872 3.3958 4.5477 237 | v 4.9671 1.9950 2.8040 238 | v 4.2856 43.8475 2.5426 239 | v 4.3907 42.5916 3.9743 240 | v 6.2300 44.9697 1.9555 241 | v 4.2410 8.5936 5.9292 242 | v 3.9371 5.7082 4.9432 243 | v 4.6508 11.6654 6.2703 244 | v 4.5906 15.1353 4.9578 245 | v 4.7033 19.6552 4.7982 246 | v 4.3891 23.5222 5.8395 247 | v 4.0837 27.5771 4.8189 248 | v 4.0121 31.4075 5.0135 249 | v 4.0410 36.3693 5.4840 250 | v 4.1327 40.3741 4.3698 251 | v -2.9797 8.5258 -14.6055 252 | v -3.0591 5.8465 -13.5591 253 | v -2.6602 3.6307 -12.7196 254 | v -2.9126 12.1206 -15.0489 255 | v -2.7994 15.5299 -15.1391 256 | v -2.4436 19.4429 -14.1931 257 | v -2.6463 23.2002 -14.9390 258 | v -2.8809 27.0064 -14.6417 259 | v -3.0649 31.2168 -15.1813 260 | v -2.8811 36.8609 -14.0903 261 | v -2.6701 40.6420 -12.8659 262 | v -2.2298 42.5105 -12.3890 263 | v -1.8789 43.4679 -10.8928 264 | v -2.1592 1.5386 -10.5772 265 | v -1.5599 1.0719 -8.9468 266 | v -0.8834 44.2652 -8.4287 267 | v -0.6938 1.8960 -6.6997 268 | v 0.6846 44.7233 -7.2850 269 | v -0.9536 44.2356 -5.3454 270 | v -0.9880 3.7116 -1.0178 271 | v -0.8036 3.3967 -4.3118 272 | v -0.1467 43.9137 -2.1875 273 | v -0.5893 3.3700 1.8561 274 | v 0.2401 43.6409 0.6121 275 | v 0.3850 6.7793 4.6880 276 | v 0.1053 4.6589 4.6127 277 | v 1.1770 43.4386 2.6787 278 | v 0.6855 41.6945 3.9010 279 | v 1.0461 11.5746 6.4313 280 | v 1.1307 8.7120 5.8899 281 | v 1.3170 15.0876 4.7865 282 | v 1.1322 19.8218 4.8972 283 | v 0.9910 23.8731 5.9443 284 | v -1.9712 23.8290 5.9106 285 | v -1.6926 19.5136 4.6451 286 | v 0.7030 27.6377 5.3595 287 | v 0.4152 31.6894 5.6925 288 | v 0.4614 36.1858 6.0266 289 | v 0.5843 39.5314 4.4726 290 | v -5.5745 12.7099 -14.2485 291 | v -6.2053 9.5707 -12.8092 292 | v -5.7673 7.5664 -11.4321 293 | v -5.2912 16.2934 -14.3248 294 | v -4.7572 19.8542 -13.1477 295 | v -7.2800 24.4705 -12.5968 296 | v -5.3331 23.4988 -14.4773 297 | v -6.2045 20.9024 -12.5887 298 | v -4.9788 27.7393 -13.5650 299 | v -5.9649 31.1234 -14.6413 300 | v -5.7786 36.7788 -13.7825 301 | v -5.1874 40.3585 -12.9462 302 | v -4.9960 42.1492 -11.7982 303 | v -4.2366 42.7671 -10.3285 304 | v -5.8699 6.8671 -8.1212 305 | v -4.7171 4.2398 -11.2229 306 | v -4.7661 3.1485 -8.5159 307 | v -3.6732 43.2869 -8.1690 308 | v -3.9570 3.6337 -5.0202 309 | v -3.0790 1.9715 -8.0912 310 | v -2.8691 2.2754 -6.5937 311 | v -5.2253 7.0617 -4.6837 312 | v -3.1603 43.6501 -5.1183 313 | v -4.8336 7.1724 -1.0643 314 | v -3.7831 4.7403 -1.0683 315 | v -2.5571 43.6169 -1.8485 316 | v -5.0970 42.0127 -4.9069 317 | v -4.1651 41.9112 -1.6406 318 | v -4.4396 7.1726 2.4058 319 | v -3.3381 4.8759 2.0358 320 | v -1.9143 43.2419 0.9435 321 | v -3.6389 41.2333 1.2094 322 | v -2.6419 7.8143 5.5126 323 | v -2.1382 5.7182 4.3805 324 | v -4.3983 23.7122 5.6576 325 | v -4.0408 19.5040 4.6078 326 | v -2.5109 40.9407 3.5204 327 | v -2.7154 38.7439 4.5902 328 | v -1.5004 42.6824 2.7199 329 | v -1.5132 11.5372 6.1746 330 | v -3.7814 11.4679 5.8453 331 | v -1.3676 8.8159 6.3040 332 | v -1.8086 14.4744 5.2891 333 | v -3.8951 14.5801 5.0041 334 | v -2.3778 27.9920 5.6470 335 | v -4.5347 27.6410 5.7571 336 | v -2.5050 31.4480 6.2122 337 | v -4.7241 31.5931 6.2914 338 | v -2.6310 35.8194 6.5403 339 | v -6.4459 15.8720 -10.9580 340 | v -6.3920 16.6420 -12.7716 341 | v -6.8145 13.6506 -12.8737 342 | v -7.2071 12.2536 -11.2094 343 | v -6.7738 21.0547 -10.5884 344 | v -8.0338 28.5303 -10.3643 345 | v -6.7067 26.5570 -12.6161 346 | v -7.7718 24.3639 -10.7109 347 | v -9.1699 31.7023 -10.7127 348 | v -8.2300 31.8746 -13.5811 349 | v -8.5063 36.4771 -10.4937 350 | v -7.8689 36.5993 -12.6245 351 | v -7.1341 40.5289 -10.7232 352 | v -6.8609 40.1811 -12.5736 353 | v -7.2453 12.4497 -7.9601 354 | v -6.1887 9.9073 -10.3174 355 | v -6.3997 10.1652 -7.8866 356 | v -6.1287 16.1713 -7.7881 357 | v -6.7395 21.0757 -7.8200 358 | v -8.1637 24.5724 -7.7313 359 | v -8.2748 28.0737 -7.6788 360 | v -9.0292 31.5281 -7.7472 361 | v -8.8669 36.3297 -7.2982 362 | v -6.7524 40.2374 -7.9021 363 | v -5.4765 41.9284 -7.9061 364 | v -6.0271 42.1483 -9.7698 365 | v -7.0520 12.5493 -4.3249 366 | v -5.9690 9.8505 -4.5037 367 | v -6.3173 15.7958 -4.3263 368 | v -6.5571 20.5930 -4.1787 369 | v -8.1644 23.8309 -4.2790 370 | v -8.3000 27.7290 -4.3736 371 | v -8.2971 31.0501 -4.3123 372 | v -8.9404 36.4452 -3.6409 373 | v -9.1493 36.5298 -5.8150 374 | v -6.2004 40.1248 -4.7585 375 | v -6.9351 12.2249 -0.6974 376 | v -5.7830 9.8613 -0.8010 377 | v -6.3249 15.8754 -0.6052 378 | v -6.4150 19.5568 -0.6509 379 | v -7.7946 23.7575 -0.6270 380 | v -7.3451 27.2419 -0.8742 381 | v -7.8474 30.8574 -0.8933 382 | v -8.3458 36.3264 -0.6269 383 | v -5.6227 39.6385 -1.4537 384 | v -6.7176 12.2394 2.4988 385 | v -5.6634 9.5415 2.2938 386 | v -6.6645 15.4550 2.3915 387 | v -6.5538 19.7235 2.3734 388 | v -7.2653 23.3702 2.4350 389 | v -6.6405 27.3583 2.2361 390 | v -7.0794 30.9770 2.3722 391 | v -7.7478 36.3162 2.2126 392 | v -4.6463 39.5187 1.2809 393 | v -5.6826 11.9677 5.1750 394 | v -5.3973 9.4437 4.8141 395 | v -5.5404 15.5014 4.7435 396 | v -5.6973 19.3433 4.6285 397 | v -6.5439 23.6419 4.8176 398 | v -6.1012 27.6494 4.5651 399 | v -6.2906 31.2108 4.6799 400 | v -6.4938 36.3500 4.8042 401 | v -7.3956 36.3355 4.0440 402 | v -4.5502 38.5280 3.1934 403 | v -4.9481 35.5540 6.5442 404 | # 394 vertices 405 | 406 | vn 0.4906 -0.0377 -0.8706 407 | vn 0.8520 -0.0418 -0.5219 408 | vn 0.8392 -0.0288 -0.5431 409 | vn 0.5472 -0.0245 -0.8366 410 | vn 0.2086 -0.0145 -0.9779 411 | vn 0.2123 -0.0506 -0.9759 412 | vn 0.4795 0.0498 -0.8761 413 | vn 0.8952 0.0899 -0.4365 414 | vn 0.1493 0.0629 -0.9868 415 | vn 0.7577 -0.1161 -0.6421 416 | vn 0.9379 -0.0736 -0.3391 417 | vn 0.9429 -0.1612 -0.2914 418 | vn 0.7286 -0.1588 -0.6662 419 | vn 0.4570 -0.1606 -0.8748 420 | vn 0.4735 -0.3108 -0.8242 421 | vn 0.7487 -0.5331 -0.3940 422 | vn 0.8261 -0.0463 -0.5616 423 | vn 0.9520 0.0010 -0.3062 424 | vn 0.4353 -0.1174 -0.8926 425 | vn 0.9560 0.0002 -0.2933 426 | vn 0.9716 0.0195 -0.2359 427 | vn 0.9793 0.0767 -0.1872 428 | vn 0.8452 0.1458 -0.5142 429 | vn 0.9379 0.0827 -0.3370 430 | vn 0.5492 0.1322 -0.8252 431 | vn 0.8775 0.0677 -0.4748 432 | vn 0.9023 0.0759 -0.4244 433 | vn 0.5972 0.0220 -0.8018 434 | vn 0.9265 0.0355 -0.3746 435 | vn 0.9427 0.0940 -0.3200 436 | vn 0.6840 0.0563 -0.7273 437 | vn 0.9463 0.1257 -0.2977 438 | vn 0.9585 0.1735 -0.2262 439 | vn 0.6920 0.4450 -0.5685 440 | vn 0.7778 0.5801 -0.2419 441 | vn 0.9797 -0.1597 -0.1208 442 | vn 0.9675 -0.2511 -0.0308 443 | vn 0.8370 -0.5470 0.0161 444 | vn 0.9827 -0.0089 -0.1852 445 | vn 0.9714 -0.0025 -0.2373 446 | vn 0.9617 0.0357 -0.2717 447 | vn 0.9653 0.0367 -0.2586 448 | vn 0.9702 0.0183 -0.2416 449 | vn 0.9501 0.0471 -0.3083 450 | vn 0.9388 0.1455 -0.3121 451 | vn 0.9356 0.2120 -0.2824 452 | vn 0.8183 0.4419 -0.3677 453 | vn 0.9777 -0.2045 -0.0476 454 | vn 0.9456 -0.3245 0.0220 455 | vn 0.8486 -0.5253 0.0631 456 | vn 0.9878 -0.0905 -0.1268 457 | vn 0.9751 -0.0756 -0.2084 458 | vn 0.9782 0.0580 -0.1992 459 | vn 0.9768 0.0928 -0.1929 460 | vn 0.9977 0.0263 -0.0631 461 | vn 0.9850 -0.0269 -0.1702 462 | vn 0.9516 0.1159 -0.2846 463 | vn 0.9485 0.1313 -0.2882 464 | vn 0.8946 0.3459 -0.2829 465 | vn 0.5159 0.8228 -0.2383 466 | vn 0.4634 0.7879 -0.4055 467 | vn 0.9844 -0.1560 -0.0819 468 | vn 0.9646 -0.2626 0.0247 469 | vn 0.9078 -0.4031 0.1157 470 | vn 0.9921 -0.0808 -0.0961 471 | vn 0.9969 0.0541 -0.0573 472 | vn 0.9835 0.1712 -0.0579 473 | vn 0.9937 0.0821 0.0759 474 | vn 0.9874 -0.1243 -0.0980 475 | vn 0.9749 0.0989 -0.1992 476 | vn 0.9729 0.2062 -0.1047 477 | vn 0.9118 0.4080 -0.0458 478 | vn 0.5556 0.8313 0.0139 479 | vn 0.9667 -0.2460 0.0710 480 | vn 0.8991 -0.3522 0.2601 481 | vn 0.7998 -0.4844 0.3544 482 | vn 0.9997 -0.0260 -0.0019 483 | vn 0.9936 0.0692 0.0887 484 | vn 0.9850 0.1723 -0.0091 485 | vn 0.9954 0.0350 -0.0894 486 | vn 0.9838 -0.1562 0.0881 487 | vn 0.7588 -0.0715 0.6474 488 | vn 0.8765 0.2078 0.4341 489 | vn 0.9911 0.0954 0.0925 490 | vn 0.9463 0.2793 0.1630 491 | vn 0.8661 0.4026 0.2962 492 | vn 0.5089 0.7831 0.3576 493 | vn 0.8468 0.0530 0.5293 494 | vn 0.8547 -0.2611 0.4486 495 | vn 0.2420 0.0980 0.9653 496 | vn 0.5511 -0.2273 0.8029 497 | vn 0.8092 0.0760 0.5827 498 | vn 0.3042 -0.0064 0.9526 499 | vn 0.8834 0.1581 0.4411 500 | vn 0.3337 0.1492 0.9308 501 | vn 0.2303 0.2499 0.9405 502 | vn 0.7170 0.1282 0.6852 503 | vn 0.2478 0.0872 0.9649 504 | vn 0.2267 -0.0472 0.9728 505 | vn 0.7897 0.3575 0.4985 506 | vn 0.4695 0.3042 0.8289 507 | vn 0.1284 -0.1238 -0.9840 508 | vn 0.2051 -0.1443 -0.9680 509 | vn 0.1181 -0.0856 -0.9893 510 | vn 0.0697 -0.1578 -0.9850 511 | vn 0.0848 -0.0729 -0.9937 512 | vn 0.0832 -0.0122 -0.9965 513 | vn 0.0882 0.0829 -0.9926 514 | vn 0.1329 0.1053 -0.9855 515 | vn 0.0506 0.1080 -0.9929 516 | vn 0.1197 -0.0869 -0.9890 517 | vn 0.0582 -0.0335 -0.9977 518 | vn 0.2801 0.0317 -0.9594 519 | vn 0.0395 0.0923 -0.9950 520 | vn 0.2216 0.4948 -0.8403 521 | vn -0.1110 0.3187 -0.9413 522 | vn 0.6082 -0.7623 -0.2212 523 | vn 0.5654 -0.5419 -0.6218 524 | vn 0.1928 -0.2331 -0.9531 525 | vn 0.2234 -0.5914 -0.7748 526 | vn 0.3152 -0.9144 -0.2538 527 | vn 0.3045 0.8192 -0.4860 528 | vn 0.3976 0.8850 -0.2423 529 | vn 0.1220 0.8865 -0.4463 530 | vn 0.1429 0.9475 -0.2859 531 | vn 0.6498 -0.7588 0.0446 532 | vn 0.4223 -0.9053 0.0454 533 | vn 0.1453 0.9502 -0.2757 534 | vn 0.6257 -0.7788 0.0442 535 | vn 0.4088 -0.9013 0.1431 536 | vn 0.1132 0.9852 -0.1285 537 | vn -0.0326 0.9975 -0.0631 538 | vn -0.0199 0.9896 -0.1427 539 | vn 0.8588 -0.4666 0.2115 540 | vn 0.6399 -0.7487 0.1732 541 | vn 0.2845 -0.9473 0.1471 542 | vn 0.1141 0.9931 -0.0271 543 | vn -0.0159 0.9999 0.0058 544 | vn 0.7136 -0.4691 0.5203 545 | vn 0.5130 -0.5653 0.6459 546 | vn 0.1802 0.9833 0.0254 547 | vn -0.0438 0.9984 0.0354 548 | vn 0.0995 0.8428 0.5289 549 | vn 0.6382 -0.4529 0.6226 550 | vn 0.1244 -0.0051 0.9922 551 | vn 0.3951 -0.4104 0.8219 552 | vn -0.0778 0.1434 0.9866 553 | vn -0.0133 -0.0464 0.9988 554 | vn 0.0348 0.1376 0.9899 555 | vn 0.0343 0.1781 0.9834 556 | vn 0.0335 -0.0644 0.9974 557 | vn 0.1238 0.0298 0.9919 558 | vn 0.1454 0.1556 0.9771 559 | vn 0.3856 0.4624 0.7984 560 | vn 0.1747 0.3656 0.9142 561 | vn 0.0572 -0.2264 -0.9724 562 | vn -0.0312 -0.1772 -0.9837 563 | vn -0.0041 -0.1728 -0.9849 564 | vn 0.0413 -0.1026 -0.9939 565 | vn 0.0115 -0.0195 -0.9997 566 | vn -0.0540 -0.0059 -0.9985 567 | vn -0.0360 0.0584 -0.9976 568 | vn 0.0689 0.0769 -0.9947 569 | vn 0.1209 -0.0063 -0.9926 570 | vn -0.1027 0.0920 -0.9904 571 | vn -0.1613 0.3573 -0.9200 572 | vn -0.0543 0.6588 -0.7504 573 | vn -0.0966 0.5831 -0.8066 574 | vn 0.0790 0.8936 -0.4418 575 | vn -0.0066 -0.6597 -0.7515 576 | vn -0.0183 -0.9708 -0.2391 577 | vn 0.0854 0.9391 -0.3330 578 | vn -0.0511 -0.9828 0.1777 579 | vn 0.0967 0.9835 -0.1527 580 | vn 0.0552 0.9749 -0.2157 581 | vn -0.0097 0.9997 -0.0245 582 | vn -0.1743 -0.9610 0.2146 583 | vn -0.1753 0.9835 -0.0453 584 | vn -0.0571 -0.9775 0.2032 585 | vn -0.1095 0.9940 0.0086 586 | vn 0.2438 -0.8670 0.4346 587 | vn 0.1229 -0.4955 0.8599 588 | vn 0.0438 -0.9028 0.4279 589 | vn -0.1392 0.9839 0.1122 590 | vn -0.1568 0.8132 0.5604 591 | vn 0.2195 -0.4452 0.8681 592 | vn -0.0057 -0.1935 0.9811 593 | vn 0.0643 -0.3082 0.9491 594 | vn -0.0363 0.1695 0.9849 595 | vn -0.0878 0.1805 0.9796 596 | vn -0.0758 -0.0852 0.9935 597 | vn 0.0067 0.1079 0.9941 598 | vn 0.0965 0.1763 0.9796 599 | vn 0.1048 -0.0935 0.9901 600 | vn 0.0820 0.0294 0.9962 601 | vn 0.0225 0.1499 0.9885 602 | vn -0.0537 0.3363 0.9402 603 | vn -0.0179 -0.3268 -0.9449 604 | vn -0.1475 -0.2222 -0.9638 605 | vn -0.2388 -0.4061 -0.8821 606 | vn -0.2101 -0.8605 -0.4642 607 | vn -0.0523 -0.1777 -0.9827 608 | vn -0.0738 -0.1245 -0.9895 609 | vn -0.0889 0.0589 -0.9943 610 | vn -0.1801 0.0195 -0.9834 611 | vn -0.1147 0.0091 -0.9934 612 | vn -0.0839 -0.0450 -0.9955 613 | vn -0.0353 -0.0001 -0.9994 614 | vn -0.1582 0.2129 -0.9642 615 | vn -0.1453 0.3366 -0.9304 616 | vn -0.1527 0.5060 -0.8489 617 | vn -0.2058 -0.9786 0.0064 618 | vn -0.0881 0.8720 -0.4815 619 | vn -0.0138 0.9832 -0.1820 620 | vn -0.3158 -0.8841 0.3443 621 | vn 0.0017 0.9967 -0.0806 622 | vn -0.0390 0.9952 0.0900 623 | vn -0.4069 -0.8666 0.2887 624 | vn -0.1338 0.9904 0.0333 625 | vn -0.1348 0.9837 0.1186 626 | vn -0.1226 0.9808 0.1517 627 | vn -0.2930 -0.9466 0.1345 628 | vn -0.3636 -0.9311 -0.0285 629 | vn -0.3550 -0.9273 0.1186 630 | vn -0.2925 0.9539 0.0674 631 | vn -0.2396 0.9562 0.1683 632 | vn -0.2103 -0.6216 0.7546 633 | vn -0.3090 -0.8915 0.3313 634 | vn -0.2952 0.8618 0.4124 635 | vn -0.1721 0.4712 0.8651 636 | vn -0.1974 0.8709 0.4500 637 | vn -0.0921 -0.1819 0.9790 638 | vn -0.1001 -0.2453 0.9643 639 | vn 0.0033 0.1140 0.9935 640 | vn -0.0407 0.2095 0.9770 641 | vn -0.0164 -0.1169 0.9930 642 | vn 0.0411 0.0161 0.9990 643 | vn 0.1441 0.0779 0.9865 644 | vn 0.1371 -0.0788 0.9874 645 | vn 0.0900 0.0777 0.9929 646 | vn -0.0378 0.2346 0.9714 647 | vn -0.3226 -0.2551 -0.9115 648 | vn -0.4801 -0.3517 -0.8036 649 | vn -0.4981 -0.5013 -0.7075 650 | vn -0.2004 -0.0770 -0.9767 651 | vn -0.2164 0.1112 -0.9699 652 | vn -0.3088 -0.0078 -0.9511 653 | vn -0.1713 -0.0257 -0.9849 654 | vn -0.2730 -0.0648 -0.9598 655 | vn -0.1537 0.0248 -0.9878 656 | vn -0.1561 0.2325 -0.9600 657 | vn -0.1364 0.3396 -0.9306 658 | vn -0.2121 0.6286 -0.7483 659 | vn -0.2892 0.8870 -0.3600 660 | vn -0.5346 -0.7870 -0.3079 661 | vn -0.3534 -0.9273 0.1231 662 | vn -0.2700 0.9587 -0.0898 663 | vn -0.2840 -0.8620 0.4198 664 | vn -0.2562 0.9644 0.0659 665 | vn -0.1858 0.9811 0.0532 666 | vn -0.2455 -0.9691 0.0254 667 | vn -0.2503 -0.8964 0.3658 668 | vn -0.1178 0.9842 0.1318 669 | vn -0.3080 -0.9328 0.1874 670 | vn -0.1175 0.9794 0.1640 671 | vn -0.0589 -0.3290 0.9425 672 | vn -0.2359 -0.5183 0.8220 673 | vn -0.1292 0.8549 0.5025 674 | vn -0.1381 0.4610 0.8766 675 | vn -0.0097 0.1459 0.9893 676 | vn 0.0288 -0.3262 0.9449 677 | vn 0.0284 0.1880 0.9818 678 | vn -0.0083 -0.1217 0.9925 679 | vn 0.0198 -0.0310 0.9993 680 | vn -0.0348 -0.0908 0.9953 681 | vn -0.0523 -0.0757 0.9958 682 | vn 0.1172 0.0363 0.9924 683 | vn 0.1668 -0.0869 0.9821 684 | vn 0.1208 0.1636 0.9791 685 | vn -0.0432 0.3508 0.9355 686 | vn -0.5935 -0.0816 -0.8007 687 | vn -0.7946 -0.3264 -0.5120 688 | vn -0.8830 -0.3303 -0.3334 689 | vn -0.5186 0.1474 -0.8422 690 | vn -0.3546 0.0363 -0.9343 691 | vn -0.8422 -0.0638 -0.5354 692 | vn -0.4811 -0.0691 -0.8739 693 | vn -0.7494 -0.0660 -0.6588 694 | vn -0.4616 -0.1596 -0.8726 695 | vn -0.3685 -0.1024 -0.9240 696 | vn -0.2979 0.1895 -0.9356 697 | vn -0.2218 0.4714 -0.8536 698 | vn -0.3975 0.7246 -0.5629 699 | vn -0.3486 0.9229 -0.1637 700 | vn -0.9687 -0.2444 0.0433 701 | vn -0.7507 -0.4934 -0.4394 702 | vn -0.8060 -0.5919 -0.0094 703 | vn -0.4727 0.8795 -0.0553 704 | vn -0.6333 -0.7016 0.3267 705 | vn -0.5239 -0.8455 0.1033 706 | vn -0.3610 -0.8494 0.3850 707 | vn -0.9385 -0.3108 0.1507 708 | vn -0.4644 0.8845 0.0441 709 | vn -0.9221 -0.3741 0.0991 710 | vn -0.6788 -0.7194 0.1470 711 | vn -0.4262 0.8865 0.1799 712 | vn -0.7453 0.6514 0.1422 713 | vn -0.7509 0.6086 0.2563 714 | vn -0.8239 -0.4967 0.2729 715 | vn -0.6568 -0.6936 0.2959 716 | vn -0.4286 0.8575 0.2846 717 | vn -0.7525 0.5693 0.3311 718 | vn -0.3448 -0.4596 0.8185 719 | vn -0.4076 -0.5539 0.7260 720 | vn -0.1981 -0.1008 0.9750 721 | vn -0.0104 -0.1031 0.9946 722 | vn -0.4743 0.5615 0.6781 723 | vn -0.1774 0.4935 0.8515 724 | vn -0.3673 0.7164 0.5932 725 | vn -0.1266 0.1518 0.9803 726 | vn -0.2419 0.0289 0.9699 727 | vn -0.1744 -0.2616 0.9493 728 | vn -0.0268 0.1930 0.9808 729 | vn -0.1207 0.1574 0.9801 730 | vn 0.0764 -0.0553 0.9955 731 | vn -0.2721 -0.0616 0.9603 732 | vn 0.1090 -0.1116 0.9878 733 | vn -0.3569 -0.1000 0.9288 734 | vn 0.0359 0.2346 0.9714 735 | vn -0.9971 0.0705 0.0292 736 | vn -0.9358 0.0522 -0.3485 737 | vn -0.9060 -0.0000 -0.4233 738 | vn -0.9881 -0.0797 -0.1317 739 | vn -0.9767 -0.1773 -0.1208 740 | vn -0.9614 -0.2063 -0.1823 741 | vn -0.6881 0.0408 -0.7245 742 | vn -0.9681 -0.1689 -0.1851 743 | vn -0.9818 -0.1120 -0.1534 744 | vn -0.7353 -0.0451 -0.6762 745 | vn -0.9546 0.2532 -0.1569 746 | vn -0.7852 0.2014 -0.5856 747 | vn -0.8475 0.5166 -0.1217 748 | vn -0.5637 0.6100 -0.5568 749 | vn -0.9991 -0.0416 0.0065 750 | vn -0.9596 -0.2708 0.0760 751 | vn -0.9640 -0.2652 0.0195 752 | vn -0.9971 0.0717 0.0253 753 | vn -0.9659 -0.2586 0.0105 754 | vn -0.9815 -0.1789 -0.0678 755 | vn -0.9946 -0.0968 -0.0366 756 | vn -0.9885 -0.1341 0.0705 757 | vn -0.9811 0.1924 -0.0206 758 | vn -0.8523 0.5070 0.1284 759 | vn -0.6825 0.7230 0.1075 760 | vn -0.6475 0.7601 0.0547 761 | vn -0.9966 -0.0741 0.0350 762 | vn -0.9471 -0.3118 0.0764 763 | vn -0.9944 0.1052 -0.0102 764 | vn -0.9682 -0.2501 0.0035 765 | vn -0.9733 -0.2230 0.0534 766 | vn -0.9939 -0.0336 0.1055 767 | vn -0.9865 -0.0901 0.1368 768 | vn -0.9737 0.1587 0.1634 769 | vn -0.9888 0.0000 0.1492 770 | vn 0.5185 0.8549 -0.0166 771 | vn -0.8066 0.5901 -0.0349 772 | vn -0.8236 0.5410 0.1701 773 | vn -0.9860 -0.1632 0.0334 774 | vn -0.9269 -0.3732 0.0411 775 | vn -0.9960 0.0805 -0.0387 776 | vn -0.9898 -0.1421 -0.0097 777 | vn -0.9886 -0.0964 0.1153 778 | vn -0.9760 -0.0127 0.2174 779 | vn -0.9760 -0.1018 0.1926 780 | vn -0.9312 0.3030 0.2026 781 | vn -0.7654 0.5906 0.2557 782 | vn -0.9637 -0.1671 0.2084 783 | vn -0.9246 -0.3709 0.0867 784 | vn -0.9822 0.0406 0.1832 785 | vn -0.9843 -0.1010 0.1449 786 | vn -0.9775 -0.0546 0.2037 787 | vn -0.9737 0.0283 0.2260 788 | vn -0.9508 -0.1086 0.2902 789 | vn -0.9328 0.1829 0.3107 790 | vn -0.7563 0.5832 0.2966 791 | vn -0.6949 -0.0268 0.7186 792 | vn -0.7563 -0.3626 0.5446 793 | vn -0.5755 0.0597 0.8156 794 | vn -0.5678 -0.1028 0.8168 795 | vn -0.7555 -0.0415 0.6538 796 | vn -0.8434 0.0213 0.5368 797 | vn -0.8529 -0.0701 0.5173 798 | vn -0.7719 0.1368 0.6208 799 | vn -0.0087 0.9999 -0.0088 800 | vn -0.6028 0.7464 0.2819 801 | vn -0.7195 0.6643 0.2026 802 | vn -0.3870 0.2356 0.8915 803 | # 397 vertex normals 804 | 805 | vt 0.9902 0.2607 0.0000 806 | vt 0.9651 0.2592 0.0000 807 | vt 0.9620 0.2049 0.0000 808 | vt 0.9844 0.2031 0.0000 809 | vt 0.0318 0.2770 0.0000 810 | vt 0.0098 0.2822 0.0000 811 | vt 0.0098 0.2246 0.0000 812 | vt 0.0349 0.2231 0.0000 813 | vt 0.9912 0.3105 0.0000 814 | vt 0.9640 0.3081 0.0000 815 | vt 0.0353 0.3341 0.0000 816 | vt 0.0098 0.3311 0.0000 817 | vt 0.9479 0.1111 0.0000 818 | vt 0.9190 0.1137 0.0000 819 | vt 0.9142 0.0826 0.0000 820 | vt 0.9405 0.0845 0.0000 821 | vt 0.9697 0.1006 0.0000 822 | vt 0.9541 0.0576 0.0000 823 | vt 0.9165 0.0526 0.0000 824 | vt 0.9556 0.1577 0.0000 825 | vt 0.9247 0.1599 0.0000 826 | vt 0.9824 0.1514 0.0000 827 | vt 0.9304 0.2078 0.0000 828 | vt 0.9326 0.2603 0.0000 829 | vt 0.9343 0.3118 0.0000 830 | vt 0.9626 0.3648 0.0000 831 | vt 0.9290 0.3665 0.0000 832 | vt 0.9844 0.3711 0.0000 833 | vt 0.9586 0.4212 0.0000 834 | vt 0.9293 0.4185 0.0000 835 | vt 0.9805 0.4209 0.0000 836 | vt 0.9549 0.4925 0.0000 837 | vt 0.9222 0.4896 0.0000 838 | vt 0.9785 0.4971 0.0000 839 | vt 0.9481 0.5402 0.0000 840 | vt 0.9171 0.5418 0.0000 841 | vt 0.9570 0.5527 0.0000 842 | vt 0.9185 0.5643 0.0000 843 | vt 0.8780 0.1167 0.0000 844 | vt 0.8750 0.0845 0.0000 845 | vt 0.8712 0.0544 0.0000 846 | vt 0.8860 0.1639 0.0000 847 | vt 0.8887 0.2129 0.0000 848 | vt 0.8930 0.2620 0.0000 849 | vt 0.8901 0.3140 0.0000 850 | vt 0.8910 0.3664 0.0000 851 | vt 0.8841 0.4181 0.0000 852 | vt 0.8805 0.4854 0.0000 853 | vt 0.8748 0.5452 0.0000 854 | vt 0.8734 0.5705 0.0000 855 | vt 0.8363 0.1259 0.0000 856 | vt 0.8288 0.0918 0.0000 857 | vt 0.8222 0.0590 0.0000 858 | vt 0.8398 0.1681 0.0000 859 | vt 0.8458 0.2141 0.0000 860 | vt 0.8449 0.2673 0.0000 861 | vt 0.8482 0.3147 0.0000 862 | vt 0.8433 0.3672 0.0000 863 | vt 0.8409 0.4177 0.0000 864 | vt 0.8337 0.4853 0.0000 865 | vt 0.8285 0.5464 0.0000 866 | vt 0.8249 0.5754 0.0000 867 | vt 0.8254 0.6001 0.0000 868 | vt 0.8723 0.5929 0.0000 869 | vt 0.7983 0.1748 0.0000 870 | vt 0.7890 0.1346 0.0000 871 | vt 0.7824 0.1013 0.0000 872 | vt 0.7990 0.2162 0.0000 873 | vt 0.8043 0.2631 0.0000 874 | vt 0.8022 0.3129 0.0000 875 | vt 0.8034 0.3591 0.0000 876 | vt 0.7993 0.4165 0.0000 877 | vt 0.7940 0.4855 0.0000 878 | vt 0.7863 0.5456 0.0000 879 | vt 0.7852 0.5748 0.0000 880 | vt 0.7780 0.6014 0.0000 881 | vt 0.7582 0.1829 0.0000 882 | vt 0.7503 0.1463 0.0000 883 | vt 0.7415 0.1160 0.0000 884 | vt 0.7664 0.2196 0.0000 885 | vt 0.7652 0.2636 0.0000 886 | vt 0.7705 0.3047 0.0000 887 | vt 0.7665 0.3549 0.0000 888 | vt 0.7651 0.4097 0.0000 889 | vt 0.7442 0.4080 0.0000 890 | vt 0.7434 0.3465 0.0000 891 | vt 0.7656 0.4820 0.0000 892 | vt 0.7586 0.5417 0.0000 893 | vt 0.7539 0.5687 0.0000 894 | vt 0.7381 0.5994 0.0000 895 | vt 0.7415 0.2225 0.0000 896 | vt 0.7393 0.1917 0.0000 897 | vt 0.7137 0.2158 0.0000 898 | vt 0.7153 0.1672 0.0000 899 | vt 0.7425 0.2617 0.0000 900 | vt 0.7169 0.2636 0.0000 901 | vt 0.7457 0.3052 0.0000 902 | vt 0.7183 0.3060 0.0000 903 | vt 0.7225 0.3472 0.0000 904 | vt 0.7417 0.4845 0.0000 905 | vt 0.7199 0.4886 0.0000 906 | vt 0.7250 0.4100 0.0000 907 | vt 0.7428 0.5348 0.0000 908 | vt 0.7253 0.5538 0.0000 909 | vt 0.0408 0.1734 0.0000 910 | vt 0.0166 0.1729 0.0000 911 | vt 0.0215 0.1221 0.0000 912 | vt 0.0502 0.1248 0.0000 913 | vt 0.0763 0.1749 0.0000 914 | vt 0.0853 0.1264 0.0000 915 | vt 0.0704 0.2231 0.0000 916 | vt 0.0679 0.2775 0.0000 917 | vt 0.0685 0.3274 0.0000 918 | vt 0.0381 0.3845 0.0000 919 | vt 0.0176 0.3916 0.0000 920 | vt 0.0761 0.3894 0.0000 921 | vt 0.0487 0.4493 0.0000 922 | vt 0.0244 0.4434 0.0000 923 | vt 0.0777 0.4335 0.0000 924 | vt 0.0577 0.5144 0.0000 925 | vt 0.0361 0.5215 0.0000 926 | vt 0.0905 0.5157 0.0000 927 | vt 0.0730 0.5724 0.0000 928 | vt 0.0410 0.5830 0.0000 929 | vt 0.0998 0.5668 0.0000 930 | vt 0.9150 0.0176 0.0000 931 | vt 0.9434 0.0225 0.0000 932 | vt 0.0593 0.0806 0.0000 933 | vt 0.0254 0.0791 0.0000 934 | vt 0.0391 0.0459 0.0000 935 | vt 0.0684 0.0420 0.0000 936 | vt 0.4661 0.9216 0.0000 937 | vt 0.4640 0.9815 0.0000 938 | vt 0.4175 0.9645 0.0000 939 | vt 0.4130 0.9196 0.0000 940 | vt 0.9496 0.5826 0.0000 941 | vt 0.9170 0.5881 0.0000 942 | vt 0.0924 0.6065 0.0000 943 | vt 0.0601 0.6083 0.0000 944 | vt 0.1048 0.9118 0.0000 945 | vt 0.1057 0.9681 0.0000 946 | vt 0.0498 0.9684 0.0000 947 | vt 0.0335 0.9192 0.0000 948 | vt 0.8672 0.0195 0.0000 949 | vt 0.4628 0.8519 0.0000 950 | vt 0.4097 0.8503 0.0000 951 | vt 0.1860 0.9401 0.0000 952 | vt 0.1807 0.9785 0.0000 953 | vt 0.8154 0.0273 0.0000 954 | vt 0.4646 0.7792 0.0000 955 | vt 0.4139 0.7740 0.0000 956 | vt 0.2580 0.9499 0.0000 957 | vt 0.2553 0.9933 0.0000 958 | vt 0.2607 0.9120 0.0000 959 | vt 0.1885 0.8935 0.0000 960 | vt 0.7719 0.0692 0.0000 961 | vt 0.7617 0.0352 0.0000 962 | vt 0.4747 0.7107 0.0000 963 | vt 0.4255 0.7001 0.0000 964 | vt 0.3211 0.9543 0.0000 965 | vt 0.3259 0.9851 0.0000 966 | vt 0.3155 0.9120 0.0000 967 | vt 0.7231 0.0843 0.0000 968 | vt 0.7021 0.0527 0.0000 969 | vt 0.3559 0.9460 0.0000 970 | vt 0.3736 0.9686 0.0000 971 | vt 0.3624 0.9130 0.0000 972 | vt 0.3848 0.9095 0.0000 973 | vt 0.7154 0.1317 0.0000 974 | vt 0.6840 0.1624 0.0000 975 | vt 0.6908 0.1033 0.0000 976 | vt 0.6839 0.2121 0.0000 977 | vt 0.6868 0.2616 0.0000 978 | vt 0.6868 0.3076 0.0000 979 | vt 0.6907 0.3601 0.0000 980 | vt 0.6895 0.4154 0.0000 981 | vt 0.6876 0.4907 0.0000 982 | vt 0.6902 0.5526 0.0000 983 | vt 0.7179 0.5798 0.0000 984 | vt 0.6890 0.5827 0.0000 985 | vt 0.6939 0.6059 0.0000 986 | vt 0.0972 0.0813 0.0000 987 | vt 0.1225 0.1312 0.0000 988 | vt 0.1327 0.0917 0.0000 989 | vt 0.1167 0.1772 0.0000 990 | vt 0.1121 0.2259 0.0000 991 | vt 0.1107 0.2759 0.0000 992 | vt 0.1123 0.3293 0.0000 993 | vt 0.1161 0.3799 0.0000 994 | vt 0.1256 0.4436 0.0000 995 | vt 0.1279 0.5058 0.0000 996 | vt 0.1369 0.5643 0.0000 997 | vt 0.1087 0.5860 0.0000 998 | vt 0.1411 0.5892 0.0000 999 | vt 0.1387 0.6090 0.0000 1000 | vt 0.1191 0.0371 0.0000 1001 | vt 0.5394 0.9263 0.0000 1002 | vt 0.5417 0.9910 0.0000 1003 | vt 0.0829 0.8457 0.0000 1004 | vt 0.0296 0.8456 0.0000 1005 | vt 0.5369 0.8510 0.0000 1006 | vt 0.1415 0.8870 0.0000 1007 | vt 0.1231 0.8346 0.0000 1008 | vt 0.1884 0.8511 0.0000 1009 | vt 0.5328 0.7798 0.0000 1010 | vt 0.2451 0.8529 0.0000 1011 | vt 0.5279 0.7100 0.0000 1012 | vt 0.3167 0.8663 0.0000 1013 | vt 0.4521 0.6260 0.0000 1014 | vt 0.4850 0.6629 0.0000 1015 | vt 0.5293 0.6084 0.0000 1016 | vt 0.5264 0.6568 0.0000 1017 | vt 0.3521 0.8598 0.0000 1018 | vt 0.3808 0.8509 0.0000 1019 | vt 0.6786 0.0767 0.0000 1020 | vt 0.6409 0.1152 0.0000 1021 | vt 0.6407 0.0740 0.0000 1022 | vt 0.6436 0.0469 0.0000 1023 | vt 0.6421 0.1584 0.0000 1024 | vt 0.6449 0.2085 0.0000 1025 | vt 0.6450 0.2636 0.0000 1026 | vt 0.6468 0.3141 0.0000 1027 | vt 0.6459 0.3619 0.0000 1028 | vt 0.6462 0.4219 0.0000 1029 | vt 0.6443 0.4905 0.0000 1030 | vt 0.6465 0.5503 0.0000 1031 | vt 0.6476 0.5795 0.0000 1032 | vt 0.6533 0.6032 0.0000 1033 | vt 0.1397 0.0617 0.0000 1034 | vt 0.1689 0.0971 0.0000 1035 | vt 0.1736 0.0644 0.0000 1036 | vt 0.1758 0.0273 0.0000 1037 | vt 0.1642 0.1358 0.0000 1038 | vt 0.1589 0.1801 0.0000 1039 | vt 0.1568 0.2255 0.0000 1040 | vt 0.1556 0.2743 0.0000 1041 | vt 0.1567 0.3265 0.0000 1042 | vt 0.1595 0.3787 0.0000 1043 | vt 0.1669 0.4286 0.0000 1044 | vt 0.1730 0.5073 0.0000 1045 | vt 0.1801 0.5623 0.0000 1046 | vt 0.1854 0.5869 0.0000 1047 | vt 0.6107 0.9155 0.0000 1048 | vt 0.6223 0.9675 0.0000 1049 | vt 0.1854 0.6148 0.0000 1050 | vt 0.0733 0.7719 0.0000 1051 | vt 0.0299 0.7708 0.0000 1052 | vt 0.6084 0.8557 0.0000 1053 | vt 0.1213 0.7882 0.0000 1054 | vt 0.1719 0.7895 0.0000 1055 | vt 0.6036 0.7810 0.0000 1056 | vt 0.2448 0.8053 0.0000 1057 | vt 0.1697 0.7454 0.0000 1058 | vt 0.2318 0.7419 0.0000 1059 | vt 0.6300 0.6856 0.0000 1060 | vt 0.6427 0.7334 0.0000 1061 | vt 0.5820 0.7091 0.0000 1062 | vt 0.2980 0.8033 0.0000 1063 | vt 0.3007 0.7601 0.0000 1064 | vt 0.6016 0.6221 0.0000 1065 | vt 0.5693 0.6606 0.0000 1066 | vt 0.5985 0.5988 0.0000 1067 | vt 0.6015 0.5740 0.0000 1068 | vt 0.3452 0.8215 0.0000 1069 | vt 0.3515 0.7710 0.0000 1070 | vt 0.5954 0.1159 0.0000 1071 | vt 0.5926 0.0759 0.0000 1072 | vt 0.5908 0.0469 0.0000 1073 | vt 0.5997 0.1570 0.0000 1074 | vt 0.5988 0.2060 0.0000 1075 | vt 0.6022 0.2650 0.0000 1076 | vt 0.6011 0.3173 0.0000 1077 | vt 0.6005 0.3720 0.0000 1078 | vt 0.5997 0.4226 0.0000 1079 | vt 0.5979 0.4887 0.0000 1080 | vt 0.5983 0.5441 0.0000 1081 | vt 0.2049 0.1382 0.0000 1082 | vt 0.2136 0.1034 0.0000 1083 | vt 0.2164 0.0736 0.0000 1084 | vt 0.1997 0.1835 0.0000 1085 | vt 0.1978 0.2264 0.0000 1086 | vt 0.1971 0.2775 0.0000 1087 | vt 0.1958 0.3265 0.0000 1088 | vt 0.2009 0.3755 0.0000 1089 | vt 0.2038 0.4305 0.0000 1090 | vt 0.2147 0.5048 0.0000 1091 | vt 0.2256 0.5563 0.0000 1092 | vt 0.2290 0.5824 0.0000 1093 | vt 0.2346 0.6053 0.0000 1094 | vt 0.2266 0.0381 0.0000 1095 | vt 0.6785 0.9098 0.0000 1096 | vt 0.6917 0.9431 0.0000 1097 | vt 0.0893 0.7096 0.0000 1098 | vt 0.0297 0.6956 0.0000 1099 | vt 0.6705 0.8597 0.0000 1100 | vt 0.1210 0.7397 0.0000 1101 | vt 0.1557 0.6948 0.0000 1102 | vt 0.6930 0.7394 0.0000 1103 | vt 0.6848 0.8050 0.0000 1104 | vt 0.2280 0.6971 0.0000 1105 | vt 0.6836 0.6819 0.0000 1106 | vt 0.2907 0.6919 0.0000 1107 | vt 0.5420 0.0884 0.0000 1108 | vt 0.5361 0.0635 0.0000 1109 | vt 0.6797 0.6211 0.0000 1110 | vt 0.5517 0.5928 0.0000 1111 | vt 0.5487 0.5646 0.0000 1112 | vt 0.3399 0.7022 0.0000 1113 | vt 0.5547 0.1560 0.0000 1114 | vt 0.5541 0.1178 0.0000 1115 | vt 0.5590 0.2063 0.0000 1116 | vt 0.5586 0.2678 0.0000 1117 | vt 0.5602 0.3224 0.0000 1118 | vt 0.5249 0.3223 0.0000 1119 | vt 0.5238 0.2641 0.0000 1120 | vt 0.5590 0.3721 0.0000 1121 | vt 0.5556 0.4254 0.0000 1122 | vt 0.5537 0.4852 0.0000 1123 | vt 0.5509 0.5345 0.0000 1124 | vt 0.2327 0.1904 0.0000 1125 | vt 0.2498 0.1507 0.0000 1126 | vt 0.2596 0.1221 0.0000 1127 | vt 0.2305 0.2346 0.0000 1128 | vt 0.2311 0.2813 0.0000 1129 | vt 0.2605 0.3406 0.0000 1130 | vt 0.2282 0.3295 0.0000 1131 | vt 0.2518 0.2939 0.0000 1132 | vt 0.2305 0.3830 0.0000 1133 | vt 0.2363 0.4280 0.0000 1134 | vt 0.2487 0.4992 0.0000 1135 | vt 0.2546 0.5460 0.0000 1136 | vt 0.2659 0.5715 0.0000 1137 | vt 0.2796 0.5927 0.0000 1138 | vt 0.3013 0.1047 0.0000 1139 | vt 0.2509 0.0798 0.0000 1140 | vt 0.2832 0.0566 0.0000 1141 | vt 0.0820 0.6465 0.0000 1142 | vt 0.0313 0.6406 0.0000 1143 | vt 0.7458 0.8269 0.0000 1144 | vt 0.7551 0.9013 0.0000 1145 | vt 0.7139 0.8931 0.0000 1146 | vt 0.7140 0.8625 0.0000 1147 | vt 0.3493 0.1003 0.0000 1148 | vt 0.3418 0.0547 0.0000 1149 | vt 0.1514 0.6455 0.0000 1150 | vt 0.4007 0.0993 0.0000 1151 | vt 0.4023 0.0664 0.0000 1152 | vt 0.7525 0.7423 0.0000 1153 | vt 0.4260 0.6075 0.0000 1154 | vt 0.3730 0.6110 0.0000 1155 | vt 0.3715 0.5784 0.0000 1156 | vt 0.4211 0.5777 0.0000 1157 | vt 0.2246 0.6445 0.0000 1158 | vt 0.4506 0.1013 0.0000 1159 | vt 0.4521 0.0693 0.0000 1160 | vt 0.7459 0.6779 0.0000 1161 | vt 0.4734 0.5970 0.0000 1162 | vt 0.4635 0.5644 0.0000 1163 | vt 0.2881 0.6445 0.0000 1164 | vt 0.5016 0.1092 0.0000 1165 | vt 0.4980 0.0801 0.0000 1166 | vt 0.7305 0.6250 0.0000 1167 | vt 0.4965 0.3210 0.0000 1168 | vt 0.4947 0.2650 0.0000 1169 | vt 0.5021 0.5544 0.0000 1170 | vt 0.5089 0.5221 0.0000 1171 | vt 0.5072 0.5817 0.0000 1172 | vt 0.3301 0.6436 0.0000 1173 | vt 0.5235 0.1578 0.0000 1174 | vt 0.4968 0.1596 0.0000 1175 | vt 0.5217 0.1227 0.0000 1176 | vt 0.5203 0.1983 0.0000 1177 | vt 0.4946 0.2012 0.0000 1178 | vt 0.5217 0.3761 0.0000 1179 | vt 0.4960 0.3715 0.0000 1180 | vt 0.5214 0.4210 0.0000 1181 | vt 0.4970 0.4221 0.0000 1182 | vt 0.5185 0.4774 0.0000 1183 | vt 0.2757 0.2279 0.0000 1184 | vt 0.2532 0.2390 0.0000 1185 | vt 0.2545 0.2007 0.0000 1186 | vt 0.2736 0.1816 0.0000 1187 | vt 0.2797 0.2943 0.0000 1188 | vt 0.2906 0.3908 0.0000 1189 | vt 0.2559 0.3670 0.0000 1190 | vt 0.2829 0.3382 0.0000 1191 | vt 0.2942 0.4326 0.0000 1192 | vt 0.2624 0.4366 0.0000 1193 | vt 0.3003 0.4931 0.0000 1194 | vt 0.2755 0.4942 0.0000 1195 | vt 0.2928 0.5465 0.0000 1196 | vt 0.2720 0.5391 0.0000 1197 | vt 0.3121 0.1791 0.0000 1198 | vt 0.2796 0.1482 0.0000 1199 | vt 0.3108 0.1474 0.0000 1200 | vt 0.3155 0.2289 0.0000 1201 | vt 0.3155 0.2917 0.0000 1202 | vt 0.3197 0.3392 0.0000 1203 | vt 0.3231 0.3835 0.0000 1204 | vt 0.3265 0.4286 0.0000 1205 | vt 0.3370 0.4907 0.0000 1206 | vt 0.3290 0.5489 0.0000 1207 | vt 0.3270 0.5768 0.0000 1208 | vt 0.2989 0.5717 0.0000 1209 | vt 0.3223 0.6059 0.0000 1210 | vt 0.3571 0.1770 0.0000 1211 | vt 0.3539 0.1383 0.0000 1212 | vt 0.3581 0.2207 0.0000 1213 | vt 0.3612 0.2821 0.0000 1214 | vt 0.3614 0.3276 0.0000 1215 | vt 0.3626 0.3772 0.0000 1216 | vt 0.3662 0.4196 0.0000 1217 | vt 0.3789 0.4897 0.0000 1218 | vt 0.3535 0.4914 0.0000 1219 | vt 0.3712 0.5504 0.0000 1220 | vt 0.4022 0.1718 0.0000 1221 | vt 0.4021 0.1369 0.0000 1222 | vt 0.4045 0.2200 0.0000 1223 | vt 0.4051 0.2672 0.0000 1224 | vt 0.4057 0.3236 0.0000 1225 | vt 0.4058 0.3684 0.0000 1226 | vt 0.4062 0.4150 0.0000 1227 | vt 0.4125 0.4866 0.0000 1228 | vt 0.4161 0.5434 0.0000 1229 | vt 0.4412 0.1726 0.0000 1230 | vt 0.4424 0.1350 0.0000 1231 | vt 0.4417 0.2140 0.0000 1232 | vt 0.4433 0.2690 0.0000 1233 | vt 0.4423 0.3167 0.0000 1234 | vt 0.4441 0.3681 0.0000 1235 | vt 0.4452 0.4140 0.0000 1236 | vt 0.4428 0.4833 0.0000 1237 | vt 0.4553 0.5406 0.0000 1238 | vt 0.4750 0.1686 0.0000 1239 | vt 0.4727 0.1381 0.0000 1240 | vt 0.4744 0.2138 0.0000 1241 | vt 0.4740 0.2639 0.0000 1242 | vt 0.4708 0.3199 0.0000 1243 | vt 0.4727 0.3711 0.0000 1244 | vt 0.4724 0.4162 0.0000 1245 | vt 0.4712 0.4814 0.0000 1246 | vt 0.4616 0.4800 0.0000 1247 | vt 0.4767 0.5218 0.0000 1248 | vt 0.4944 0.4711 0.0000 1249 | # 444 texture coords 1250 | 1251 | g low 1252 | usemtl 03___Default 1253 | s 1 1254 | f 1/1/1 2/2/2 3/3/3 4/4/4 1255 | f 5/5/5 1/6/1 4/7/4 6/8/6 1256 | f 7/9/7 8/10/8 2/2/2 1/1/1 1257 | f 9/11/9 7/12/7 1/6/1 5/5/5 1258 | f 10/13/10 11/14/11 12/15/12 13/16/13 1259 | f 14/17/14 10/13/10 13/16/13 15/18/15 1260 | f 16/19/16 15/18/15 13/16/13 12/15/12 1261 | f 17/20/17 18/21/18 11/14/11 10/13/10 1262 | f 19/22/19 17/20/17 10/13/10 14/17/14 1263 | f 3/3/3 20/23/20 18/21/18 17/20/17 1264 | f 4/4/4 3/3/3 17/20/17 19/22/19 1265 | f 2/2/2 21/24/21 20/23/20 3/3/3 1266 | f 8/10/8 22/25/22 21/24/21 2/2/2 1267 | f 23/26/23 24/27/24 22/25/22 8/10/8 1268 | f 25/28/25 23/26/23 8/10/8 7/9/7 1269 | f 26/29/26 27/30/27 24/27/24 23/26/23 1270 | f 28/31/28 26/29/26 23/26/23 25/28/25 1271 | f 29/32/29 30/33/30 27/30/27 26/29/26 1272 | f 31/34/31 29/32/29 26/29/26 28/31/28 1273 | f 32/35/32 33/36/33 30/33/30 29/32/29 1274 | f 34/37/34 32/35/32 29/32/29 31/34/31 1275 | f 35/38/35 33/36/33 32/35/32 34/37/34 1276 | f 11/14/11 36/39/36 37/40/37 12/15/12 1277 | f 38/41/38 16/19/16 12/15/12 37/40/37 1278 | f 18/21/18 39/42/39 36/39/36 11/14/11 1279 | f 20/23/20 40/43/40 39/42/39 18/21/18 1280 | f 21/24/21 41/44/41 40/43/40 20/23/20 1281 | f 22/25/22 42/45/42 41/44/41 21/24/21 1282 | f 24/27/24 43/46/43 42/45/42 22/25/22 1283 | f 27/30/27 44/47/44 43/46/43 24/27/24 1284 | f 30/33/30 45/48/45 44/47/44 27/30/27 1285 | f 33/36/33 46/49/46 45/48/45 30/33/30 1286 | f 47/50/47 46/49/46 33/36/33 35/38/35 1287 | f 36/39/36 48/51/48 49/52/49 37/40/37 1288 | f 50/53/50 38/41/38 37/40/37 49/52/49 1289 | f 39/42/39 51/54/51 48/51/48 36/39/36 1290 | f 40/43/40 52/55/52 51/54/51 39/42/39 1291 | f 41/44/41 53/56/53 52/55/52 40/43/40 1292 | f 42/45/42 54/57/54 53/56/53 41/44/41 1293 | f 43/46/43 55/58/55 54/57/54 42/45/42 1294 | f 44/47/44 56/59/56 55/58/55 43/46/43 1295 | f 45/48/45 57/60/57 56/59/56 44/47/44 1296 | f 46/49/46 58/61/58 57/60/57 45/48/45 1297 | f 47/50/47 59/62/59 58/61/58 46/49/46 1298 | f 60/63/60 59/62/59 47/50/47 61/64/61 1299 | f 51/54/51 62/65/62 63/66/63 48/51/48 1300 | f 64/67/64 49/52/49 48/51/48 63/66/63 1301 | f 52/55/52 65/68/65 62/65/62 51/54/51 1302 | f 53/56/53 66/69/66 65/68/65 52/55/52 1303 | f 54/57/54 67/70/67 66/69/66 53/56/53 1304 | f 55/58/55 68/71/68 67/70/67 54/57/54 1305 | f 56/59/56 69/72/69 68/71/68 55/58/55 1306 | f 57/60/57 70/73/70 69/72/69 56/59/56 1307 | f 58/61/58 71/74/71 70/73/70 57/60/57 1308 | f 59/62/59 72/75/72 71/74/71 58/61/58 1309 | f 73/76/73 72/75/72 59/62/59 60/63/60 1310 | f 62/65/62 74/77/74 75/78/75 63/66/63 1311 | f 76/79/76 64/67/64 63/66/63 75/78/75 1312 | f 65/68/65 77/80/77 74/77/74 62/65/62 1313 | f 66/69/66 78/81/78 77/80/77 65/68/65 1314 | f 67/70/67 79/82/79 78/81/78 66/69/66 1315 | f 68/71/68 80/83/80 79/82/79 67/70/67 1316 | f 69/72/69 81/84/81 80/83/80 68/71/68 1317 | f 81/84/81 82/85/82 83/86/83 80/83/80 1318 | f 70/73/70 84/87/84 81/84/81 69/72/69 1319 | f 71/74/71 85/88/85 84/87/84 70/73/70 1320 | f 72/75/72 86/89/86 85/88/85 71/74/71 1321 | f 87/90/87 86/89/86 72/75/72 73/76/73 1322 | f 77/80/77 88/91/88 89/92/89 74/77/74 1323 | f 88/91/88 90/93/90 91/94/91 89/92/89 1324 | f 91/94/91 75/78/75 74/77/74 89/92/89 1325 | f 78/81/78 92/95/92 88/91/88 77/80/77 1326 | f 92/95/92 93/96/93 90/93/90 88/91/88 1327 | f 79/82/79 94/97/94 92/95/92 78/81/78 1328 | f 94/97/94 95/98/95 93/96/93 92/95/92 1329 | f 80/83/80 83/86/83 94/97/94 79/82/79 1330 | f 83/86/83 96/99/96 95/98/95 94/97/94 1331 | f 84/87/84 97/100/97 82/85/82 81/84/81 1332 | f 97/100/97 98/101/98 99/102/99 82/85/82 1333 | f 85/88/85 100/103/100 97/100/97 84/87/84 1334 | f 100/103/100 101/104/101 98/101/98 97/100/97 1335 | f 101/104/101 100/103/100 85/88/85 86/89/86 1336 | f 102/105/102 19/106/19 14/107/14 103/108/103 1337 | f 104/109/104 102/105/102 103/108/103 105/110/105 1338 | f 6/8/6 4/7/4 19/106/19 102/105/102 1339 | f 106/111/106 6/8/6 102/105/102 104/109/104 1340 | f 107/112/107 5/5/5 6/8/6 106/111/106 1341 | f 108/113/108 9/11/9 5/5/5 107/112/107 1342 | f 109/114/109 25/115/25 7/12/7 9/11/9 1343 | f 110/116/110 109/114/109 9/11/9 108/113/108 1344 | f 111/117/111 28/118/28 25/115/25 109/114/109 1345 | f 112/119/112 111/117/111 109/114/109 110/116/110 1346 | f 113/120/113 31/121/31 28/118/28 111/117/111 1347 | f 114/122/114 113/120/113 111/117/111 112/119/112 1348 | f 115/123/115 34/124/34 31/121/31 113/120/113 1349 | f 116/125/116 115/123/115 113/120/113 114/122/114 1350 | f 15/18/15 16/19/16 117/126/117 118/127/118 1351 | f 119/128/119 15/129/15 118/130/118 120/131/120 1352 | f 121/132/121 120/133/120 118/134/118 117/135/117 1353 | f 103/108/103 14/107/14 15/129/15 119/128/119 1354 | f 122/136/122 123/137/123 35/38/35 34/37/34 1355 | f 124/138/124 122/139/122 34/124/34 115/123/115 1356 | f 125/140/125 123/141/123 122/142/122 124/143/124 1357 | f 16/19/16 38/41/38 126/144/126 117/126/117 1358 | f 127/145/127 121/132/121 117/135/117 126/146/126 1359 | f 123/137/123 61/64/61 47/50/47 35/38/35 1360 | f 128/147/128 61/148/61 123/141/123 125/140/125 1361 | f 38/41/38 50/53/50 129/149/129 126/144/126 1362 | f 130/150/130 127/145/127 126/146/126 129/151/129 1363 | f 128/147/128 131/152/131 60/153/60 61/148/61 1364 | f 132/154/132 131/152/131 128/147/128 133/155/133 1365 | f 50/53/50 134/156/134 135/157/135 129/149/129 1366 | f 136/158/136 130/150/130 129/151/129 135/159/135 1367 | f 49/52/49 64/67/64 134/156/134 50/53/50 1368 | f 131/152/131 137/160/137 73/161/73 60/153/60 1369 | f 138/162/138 137/160/137 131/152/131 132/154/132 1370 | f 64/67/64 76/79/76 139/163/139 134/156/134 1371 | f 140/164/140 135/157/135 134/156/134 139/163/139 1372 | f 137/160/137 141/165/141 87/166/87 73/161/73 1373 | f 141/165/141 142/167/142 143/168/143 87/166/87 1374 | f 142/167/142 141/165/141 137/160/137 138/162/138 1375 | f 75/78/75 91/94/91 144/169/144 76/79/76 1376 | f 91/94/91 145/170/145 146/171/146 144/169/144 1377 | f 146/171/146 139/163/139 76/79/76 144/169/144 1378 | f 90/93/90 147/172/147 145/170/145 91/94/91 1379 | f 93/96/93 148/173/148 147/172/147 90/93/90 1380 | f 95/98/95 149/174/149 148/173/148 93/96/93 1381 | f 96/99/96 150/175/150 149/174/149 95/98/95 1382 | f 82/85/82 99/102/99 96/99/96 83/86/83 1383 | f 99/102/99 151/176/151 150/175/150 96/99/96 1384 | f 98/101/98 152/177/152 151/176/151 99/102/99 1385 | f 101/104/101 153/178/153 152/177/152 98/101/98 1386 | f 87/90/87 154/179/154 101/104/101 86/89/86 1387 | f 154/179/154 155/180/155 153/178/153 101/104/101 1388 | f 155/180/155 154/179/154 87/90/87 143/181/143 1389 | f 105/110/105 103/108/103 119/128/119 156/182/156 1390 | f 157/183/157 105/110/105 156/182/156 158/184/158 1391 | f 159/185/159 104/109/104 105/110/105 157/183/157 1392 | f 160/186/160 106/111/106 104/109/104 159/185/159 1393 | f 161/187/161 107/112/107 106/111/106 160/186/160 1394 | f 162/188/162 108/113/108 107/112/107 161/187/161 1395 | f 163/189/163 110/116/110 108/113/108 162/188/162 1396 | f 164/190/164 112/119/112 110/116/110 163/189/163 1397 | f 165/191/165 114/122/114 112/119/112 164/190/164 1398 | f 166/192/166 116/125/116 114/122/114 165/191/165 1399 | f 167/193/167 124/138/124 115/123/115 116/125/116 1400 | f 168/194/168 167/193/167 116/125/116 166/192/166 1401 | f 169/195/169 124/138/124 167/193/167 168/194/168 1402 | f 156/182/156 119/128/119 120/131/120 170/196/170 1403 | f 171/197/171 170/198/170 120/133/120 121/132/121 1404 | f 172/199/172 125/140/125 124/143/124 169/200/169 1405 | f 173/201/173 171/197/171 121/132/121 127/145/127 1406 | f 174/202/174 133/155/133 128/147/128 125/140/125 1407 | f 175/203/175 174/202/174 125/140/125 172/199/172 1408 | f 176/204/176 133/155/133 174/202/174 175/203/175 1409 | f 177/205/177 173/201/173 127/145/127 130/150/130 1410 | f 178/206/178 132/154/132 133/155/133 176/204/176 1411 | f 179/207/179 177/205/177 130/150/130 136/158/136 1412 | f 180/208/180 138/162/138 132/154/132 178/206/178 1413 | f 135/159/135 140/209/140 181/210/181 136/158/136 1414 | f 140/209/140 182/211/182 183/212/183 181/210/181 1415 | f 183/212/183 179/207/179 136/158/136 181/210/181 1416 | f 142/167/142 184/213/184 185/214/185 143/168/143 1417 | f 184/213/184 142/167/142 138/162/138 180/208/180 1418 | f 139/163/139 146/171/146 186/215/186 140/164/140 1419 | f 146/171/146 187/216/187 188/217/188 186/215/186 1420 | f 188/217/188 182/218/182 140/164/140 186/215/186 1421 | f 145/170/145 189/219/189 187/216/187 146/171/146 1422 | f 147/172/147 190/220/190 189/219/189 145/170/145 1423 | f 148/173/148 191/221/191 190/220/190 147/172/147 1424 | f 149/174/149 192/222/192 191/221/191 148/173/148 1425 | f 150/175/150 193/223/193 192/222/192 149/174/149 1426 | f 151/176/151 194/224/194 193/223/193 150/175/150 1427 | f 152/177/152 195/225/195 194/224/194 151/176/151 1428 | f 153/178/153 196/226/196 195/225/195 152/177/152 1429 | f 155/180/155 197/227/197 196/226/196 153/178/153 1430 | f 197/227/197 155/180/155 143/181/143 185/228/185 1431 | f 158/184/158 156/182/156 170/196/170 198/229/198 1432 | f 199/230/199 158/184/158 198/229/198 200/231/200 1433 | f 201/232/201 200/231/200 198/229/198 170/196/170 1434 | f 202/233/202 157/183/157 158/184/158 199/230/199 1435 | f 203/234/203 159/185/159 157/183/157 202/233/202 1436 | f 204/235/204 160/186/160 159/185/159 203/234/203 1437 | f 205/236/205 161/187/161 160/186/160 204/235/204 1438 | f 206/237/206 162/188/162 161/187/161 205/236/205 1439 | f 207/238/207 163/189/163 162/188/162 206/237/206 1440 | f 208/239/208 164/190/164 163/189/163 207/238/207 1441 | f 209/240/209 165/191/165 164/190/164 208/239/208 1442 | f 210/241/210 166/192/166 165/191/165 209/240/209 1443 | f 211/242/211 168/194/168 166/192/166 210/241/210 1444 | f 212/243/212 201/244/201 170/198/170 171/197/171 1445 | f 213/245/213 169/195/169 168/194/168 211/242/211 1446 | f 214/246/214 172/199/172 169/200/169 213/247/213 1447 | f 215/248/215 212/243/212 171/197/171 173/201/173 1448 | f 216/249/216 175/203/175 172/199/172 214/246/214 1449 | f 217/250/217 176/204/176 175/203/175 216/249/216 1450 | f 218/251/218 215/248/215 173/201/173 177/205/177 1451 | f 219/252/219 217/250/217 220/253/220 221/254/221 1452 | f 219/252/219 178/206/178 176/204/176 217/250/217 1453 | f 222/255/222 223/256/223 218/251/218 224/257/224 1454 | f 224/257/224 218/251/218 177/205/177 179/207/179 1455 | f 225/258/225 219/252/219 221/254/221 226/259/226 1456 | f 225/258/225 180/208/180 178/206/178 219/252/219 1457 | f 227/260/227 222/255/222 224/257/224 228/261/228 1458 | f 182/211/182 227/260/227 228/261/228 183/212/183 1459 | f 228/261/228 224/257/224 179/207/179 183/212/183 1460 | f 185/228/185 229/262/229 230/263/230 197/227/197 1461 | f 231/264/231 225/258/225 226/259/226 229/265/229 1462 | f 184/213/184 231/264/231 229/265/229 185/214/185 1463 | f 231/264/231 184/213/184 180/208/180 225/258/225 1464 | f 187/216/187 232/266/232 233/267/233 188/217/188 1465 | f 233/267/233 227/268/227 182/218/182 188/217/188 1466 | f 189/219/189 234/269/234 232/266/232 187/216/187 1467 | f 190/220/190 235/270/235 234/269/234 189/219/189 1468 | f 191/221/191 236/271/236 235/270/235 190/220/190 1469 | f 192/222/192 237/272/237 236/271/236 191/221/191 1470 | f 193/223/193 238/273/238 237/272/237 192/222/192 1471 | f 194/224/194 239/274/239 238/273/238 193/223/193 1472 | f 195/225/195 240/275/240 239/274/239 194/224/194 1473 | f 196/226/196 241/276/241 240/275/240 195/225/195 1474 | f 241/276/241 196/226/196 197/227/197 230/263/230 1475 | f 242/277/242 202/233/202 199/230/199 243/278/243 1476 | f 244/279/244 243/278/243 199/230/199 200/231/200 1477 | f 245/280/245 203/234/203 202/233/202 242/277/242 1478 | f 246/281/246 204/235/204 203/234/203 245/280/245 1479 | f 247/282/247 205/236/205 204/235/204 246/281/246 1480 | f 248/283/248 206/237/206 205/236/205 247/282/247 1481 | f 249/284/249 207/238/207 206/237/206 248/283/248 1482 | f 250/285/250 208/239/208 207/238/207 249/284/249 1483 | f 251/286/251 209/240/209 208/239/208 250/285/250 1484 | f 252/287/252 210/241/210 209/240/209 251/286/251 1485 | f 253/288/253 211/242/211 210/241/210 252/287/252 1486 | f 254/289/254 213/245/213 211/242/211 253/288/253 1487 | f 244/279/244 200/231/200 201/232/201 255/290/255 1488 | f 256/291/256 255/292/255 201/244/201 212/243/212 1489 | f 257/293/257 214/246/214 213/247/213 254/294/254 1490 | f 258/295/258 256/291/256 212/243/212 215/248/215 1491 | f 220/253/220 259/296/259 257/293/257 260/297/260 1492 | f 259/296/259 216/249/216 214/246/214 257/293/257 1493 | f 220/253/220 217/250/217 216/249/216 259/296/259 1494 | f 223/256/223 261/298/261 262/299/262 218/251/218 1495 | f 262/299/262 258/295/258 215/248/215 218/251/218 1496 | f 263/300/263 221/254/221 220/253/220 260/297/260 1497 | f 264/301/264 261/298/261 223/256/223 222/255/222 1498 | f 265/302/265 226/259/226 221/254/221 263/300/263 1499 | f 233/267/233 266/303/266 267/304/267 227/268/227 1500 | f 267/305/267 264/301/264 222/255/222 227/260/227 1501 | f 229/262/229 268/306/268 269/307/269 230/263/230 1502 | f 268/308/268 229/265/229 226/259/226 265/302/265 1503 | f 234/269/234 270/309/270 271/310/271 232/266/232 1504 | f 271/310/271 266/303/266 233/267/233 232/266/232 1505 | f 235/270/235 272/311/272 270/309/270 234/269/234 1506 | f 236/271/236 273/312/273 272/311/272 235/270/235 1507 | f 274/313/274 275/314/275 276/315/276 273/312/273 1508 | f 237/272/237 274/313/274 273/312/273 236/271/236 1509 | f 238/273/238 277/316/277 274/313/274 237/272/237 1510 | f 239/274/239 278/317/278 277/316/277 238/273/238 1511 | f 240/275/240 279/318/279 278/317/278 239/274/239 1512 | f 241/276/241 280/319/280 279/318/279 240/275/240 1513 | f 280/319/280 241/276/241 230/263/230 269/307/269 1514 | f 281/320/281 245/280/245 242/277/242 282/321/282 1515 | f 283/322/283 282/321/282 242/277/242 243/278/243 1516 | f 284/323/284 246/281/246 245/280/245 281/320/281 1517 | f 285/324/285 247/282/247 246/281/246 284/323/284 1518 | f 286/325/286 287/326/287 285/324/285 288/327/288 1519 | f 287/326/287 248/283/248 247/282/247 285/324/285 1520 | f 289/328/289 249/284/249 248/283/248 287/326/287 1521 | f 290/329/290 250/285/250 249/284/249 289/328/289 1522 | f 291/330/291 251/286/251 250/285/250 290/329/290 1523 | f 292/331/292 252/287/252 251/286/251 291/330/291 1524 | f 293/332/293 253/288/253 252/287/252 292/331/292 1525 | f 294/333/294 254/289/254 253/288/253 293/332/293 1526 | f 295/334/295 283/322/283 296/335/296 297/336/297 1527 | f 283/322/283 243/278/243 244/279/244 296/335/296 1528 | f 297/336/297 296/335/296 244/279/244 255/290/255 1529 | f 298/337/298 257/293/257 254/294/254 294/338/294 1530 | f 299/339/299 297/340/297 300/341/300 301/342/301 1531 | f 297/340/297 255/292/255 256/291/256 300/341/300 1532 | f 262/299/262 299/339/299 301/342/301 258/295/258 1533 | f 301/342/301 300/341/300 256/291/256 258/295/258 1534 | f 302/343/302 295/334/295 297/336/297 299/344/299 1535 | f 303/345/303 260/297/260 257/293/257 298/337/298 1536 | f 304/346/304 302/343/302 299/344/299 305/347/305 1537 | f 305/348/305 299/339/299 262/299/262 261/298/261 1538 | f 306/349/306 303/350/303 307/351/307 308/352/308 1539 | f 306/353/306 263/300/263 260/297/260 303/345/303 1540 | f 309/354/309 304/346/304 305/347/305 310/355/310 1541 | f 310/356/310 305/348/305 261/298/261 264/301/264 1542 | f 311/357/311 306/349/306 308/352/308 312/358/312 1543 | f 311/359/311 265/302/265 263/300/263 306/353/306 1544 | f 313/360/313 309/354/309 310/355/310 314/361/314 1545 | f 266/303/266 313/360/313 314/361/314 267/304/267 1546 | f 314/362/314 310/356/310 264/301/264 267/305/267 1547 | f 275/314/275 315/363/315 316/364/316 276/315/276 1548 | f 269/307/269 317/365/317 318/366/318 280/319/280 1549 | f 319/367/319 311/357/311 312/358/312 317/365/317 1550 | f 268/306/268 319/367/319 317/365/317 269/307/269 1551 | f 319/368/319 268/308/268 265/302/265 311/359/311 1552 | f 320/369/320 321/370/321 313/360/313 322/371/322 1553 | f 270/309/270 320/369/320 322/371/322 271/310/271 1554 | f 322/371/322 313/360/313 266/303/266 271/310/271 1555 | f 323/372/323 324/373/324 321/370/321 320/369/320 1556 | f 272/311/272 323/372/323 320/369/320 270/309/270 1557 | f 276/315/276 316/364/316 324/373/324 323/372/323 1558 | f 273/312/273 276/315/276 323/372/323 272/311/272 1559 | f 325/374/325 326/375/326 315/363/315 275/314/275 1560 | f 277/316/277 325/374/325 275/314/275 274/313/274 1561 | f 327/376/327 328/377/328 326/375/326 325/374/325 1562 | f 278/317/278 327/376/327 325/374/325 277/316/277 1563 | f 279/318/279 329/378/329 327/376/327 278/317/278 1564 | f 329/378/329 279/318/279 280/319/280 318/366/318 1565 | f 330/379/330 331/380/331 332/381/332 333/382/333 1566 | f 331/380/331 284/323/284 281/320/281 332/381/332 1567 | f 333/382/333 332/381/332 281/320/281 282/321/282 1568 | f 334/383/334 288/327/288 331/380/331 330/379/330 1569 | f 288/327/288 285/324/285 284/323/284 331/380/331 1570 | f 335/384/335 336/385/336 286/325/286 337/386/337 1571 | f 336/385/336 289/328/289 287/326/287 286/325/286 1572 | f 338/387/338 339/388/339 336/385/336 335/384/335 1573 | f 339/388/339 290/329/290 289/328/289 336/385/336 1574 | f 340/389/340 341/390/341 339/388/339 338/387/338 1575 | f 341/390/341 291/330/291 290/329/290 339/388/339 1576 | f 342/391/342 343/392/343 341/390/341 340/389/340 1577 | f 343/392/343 292/331/292 291/330/291 341/390/341 1578 | f 342/391/342 293/332/293 292/331/292 343/392/343 1579 | f 344/393/344 333/382/333 345/394/345 346/395/346 1580 | f 333/382/333 282/321/282 283/322/283 345/394/345 1581 | f 346/395/346 345/394/345 283/322/283 295/334/295 1582 | f 347/396/347 330/379/330 333/382/333 344/393/344 1583 | f 348/397/348 334/383/334 330/379/330 347/396/347 1584 | f 349/398/349 337/386/337 334/383/334 348/397/348 1585 | f 337/386/337 286/325/286 288/327/288 334/383/334 1586 | f 350/399/350 335/384/335 337/386/337 349/398/349 1587 | f 351/400/351 338/387/338 335/384/335 350/399/350 1588 | f 352/401/352 340/389/340 338/387/338 351/400/351 1589 | f 353/402/353 342/391/342 340/389/340 352/401/352 1590 | f 354/403/354 355/404/355 342/391/342 353/402/353 1591 | f 355/404/355 294/333/294 293/332/293 342/391/342 1592 | f 354/403/354 298/405/298 294/333/294 355/404/355 1593 | f 356/406/356 344/393/344 346/395/346 357/407/357 1594 | f 357/407/357 346/395/346 295/334/295 302/343/302 1595 | f 358/408/358 347/396/347 344/393/344 356/406/356 1596 | f 359/409/359 348/397/348 347/396/347 358/408/358 1597 | f 360/410/360 349/398/349 348/397/348 359/409/359 1598 | f 361/411/361 350/399/350 349/398/349 360/410/360 1599 | f 362/412/362 351/400/351 350/399/350 361/411/361 1600 | f 351/400/351 362/412/362 363/413/363 352/401/352 1601 | f 363/413/363 364/414/364 352/401/352 1602 | f 352/401/365 364/414/364 363/413/365 1603 | f 352/401/366 363/413/366 365/415/367 1604 | f 352/401/352 365/415/367 353/402/353 1605 | f 307/351/307 354/403/354 353/402/353 365/415/367 1606 | f 307/351/307 303/350/303 298/405/298 354/403/354 1607 | f 366/416/368 356/406/356 357/407/357 367/417/369 1608 | f 367/417/369 357/407/357 302/343/302 304/346/304 1609 | f 368/418/370 358/408/358 356/406/356 366/416/368 1610 | f 369/419/371 359/409/359 358/408/358 368/418/370 1611 | f 370/420/372 360/410/360 359/409/359 369/419/371 1612 | f 371/421/373 361/411/361 360/410/360 370/420/372 1613 | f 372/422/374 362/412/362 361/411/361 371/421/373 1614 | f 362/412/362 372/422/374 373/423/375 363/413/363 1615 | f 363/413/363 373/423/375 374/424/376 365/415/367 1616 | f 374/424/376 308/352/308 307/351/307 365/415/367 1617 | f 375/425/377 366/416/368 367/417/369 376/426/378 1618 | f 376/426/378 367/417/369 304/346/304 309/354/309 1619 | f 377/427/379 368/418/370 366/416/368 375/425/377 1620 | f 378/428/380 369/419/371 368/418/370 377/427/379 1621 | f 379/429/381 370/420/372 369/419/371 378/428/380 1622 | f 380/430/382 371/421/373 370/420/372 379/429/381 1623 | f 381/431/383 372/422/374 371/421/373 380/430/382 1624 | f 372/422/374 381/431/383 382/432/384 373/423/375 1625 | f 373/423/375 382/432/384 383/433/385 374/424/376 1626 | f 383/433/385 312/358/312 308/352/308 374/424/376 1627 | f 384/434/386 375/425/377 376/426/378 385/435/387 1628 | f 321/370/321 384/434/386 385/435/387 313/360/313 1629 | f 385/435/387 376/426/378 309/354/309 313/360/313 1630 | f 386/436/388 377/427/379 375/425/377 384/434/386 1631 | f 324/373/324 386/436/388 384/434/386 321/370/321 1632 | f 387/437/389 378/428/380 377/427/379 386/436/388 1633 | f 316/364/316 387/437/389 386/436/388 324/373/324 1634 | f 388/438/390 379/429/381 378/428/380 387/437/389 1635 | f 315/363/315 388/438/390 387/437/389 316/364/316 1636 | f 389/439/391 380/430/382 379/429/381 388/438/390 1637 | f 326/375/326 389/439/391 388/438/390 315/363/315 1638 | f 390/440/392 381/431/383 380/430/382 389/439/391 1639 | f 328/377/328 390/440/392 389/439/391 326/375/326 1640 | f 381/431/383 390/440/392 391/441/393 382/432/384 1641 | f 391/441/393 392/442/364 382/432/384 1642 | f 382/432/394 392/442/364 391/441/394 1643 | f 382/432/395 391/441/395 393/443/396 1644 | f 382/432/384 393/443/396 383/433/385 1645 | f 317/365/317 393/443/396 391/441/393 318/366/318 1646 | f 393/443/396 317/365/317 312/358/312 383/433/385 1647 | f 394/444/397 391/441/393 390/440/392 328/377/328 1648 | f 329/378/329 394/444/397 328/377/328 327/376/327 1649 | f 394/444/397 329/378/329 318/366/318 391/441/393 1650 | # 388 polygons - 8 triangles 1651 | 1652 | -------------------------------------------------------------------------------- /exercice/res/rock_diffuse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/exercice/res/rock_diffuse.jpg -------------------------------------------------------------------------------- /exercice/res/rock_normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/exercice/res/rock_normal.jpg -------------------------------------------------------------------------------- /intro/base/base.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | var scene = new THREE.Scene(); 4 | /* 5 | la scène est un graphe représentant une hiérarchie d'objets 3D. 6 | elle est maintenue côté CPU, il peut y avoir plusieurs scènes dans la même application. 7 | les scènes possèdent une matrice de transformation qui se répercute sur tous ses enfants. 8 | */ 9 | 10 | 11 | var camera = new THREE.PerspectiveCamera( 60, 16 / 9, 1, 10000 ); 12 | /* 13 | la caméra représente notre "oeil" dans la scène, il permet de choisir ce qu'on regarde. 14 | il en existe deux types: 15 | 16 | - perspective: 17 | la caméra "normale", avec un angle d'ouverture variable (focale) 18 | distorsion des objets en fonction de leur distance 19 | la plus utilisée dans les environnements 3D "normaux" 20 | 21 | - orthographique: 22 | une caméra "2D" sans focale, sans profondeur 23 | rend tous les objets "à plat", sans perspective 24 | utile pour les UI, les HUD, le post processing 25 | 26 | */ 27 | 28 | 29 | var renderer = new THREE.WebGLRenderer( {/* [+] parameters */} ); 30 | /* 31 | le moteur de rendu, ce qui permet de produire une image de notre scène 3D. 32 | il existe plusieurs types de moteurs de rendu: 33 | 34 | - Canvas 2D: 35 | les objets sont calculés, transformés et rendus sur le CPU 36 | pas d'accéleration matérielle et des artefacts de rendu 37 | possibilité d'avoir des options de stylisation avancées 38 | option valide pour des scènes simples, cross platform 39 | 40 | - CSS: 41 | les objets sont des élément du DOM HTML 42 | on calcule / assigne uniquement leur matrice de transformation 43 | le rendu proprement dit est pris en charge par le navigateur, souvent accéléré 44 | option valide pour des scènes simples, cross platform % prise en charge CSS 3 45 | 46 | - WebGL 2D/3D: 47 | les objets sont passés au GPU, transformés et rendus avec des shaders 48 | temps de marshalling non négligeable, meilleurs temps de rendu 49 | recommandé pour des scènes 2D/3D ayant soit un nombre important d'éléments soit des maillages de grande taille 50 | 51 | le moteur de rendu attend 2 paramètres ; une scène et une caméra. 52 | */ 53 | 54 | 55 | var geometry = new THREE.CylinderGeometry(6,18,50,64,32,false); 56 | /* 57 | une géométrie contient des informations sur la partie "physique" d'un objet: 58 | - les positions des points (vertices) 59 | - les coordonnées de texture (uvs) 60 | - les indices de faces: comment connecter les points pour dessiner des triangles 61 | + des attributs personnalisés 62 | */ 63 | 64 | 65 | var material = new THREE.MeshBasicMaterial({color:0xFF0000 /*, [+] parameters */}); 66 | /* 67 | un matériau contient des informations sur l'aspect d'un objet. 68 | il y a un nombre variable de paramètres. 69 | certains paramètres nécessitent l'ajout de propiétés géométriques 70 | */ 71 | 72 | 73 | var mesh = new THREE.Mesh( geometry, material ); 74 | /* 75 | Mesh est un object 3d qui met en relation une géométrie et un matériau. 76 | le mesh maintient une matrice de transformation permettant de positionner, pivoter et mettre l'objet à l'échelle. 77 | les propiétés sont accessibles via: 78 | - mesh.position.x/y/z: 79 | positionne l'objet dans l'espace 3D aux coordonnées passées en paramètres 80 | 81 | - mesh.rotation.x/y/z 82 | pivote l'objet sur les axes X,Y,Z, les mesures sont en radians (1 RAD = Math.PI/180) 83 | 84 | - mesh.scale.x/y/z 85 | met à l'échelle sur les axes X,Y,Z, les valeurs doivent toujours être différentes de 0, au moins sur un axe. 86 | */ 87 | 88 | //on recule l'object sur l'axe Z pour qu'il soit visible par la caméra. 89 | mesh.position.z = -100; 90 | 91 | //NB on peut manipuler le mesh sans qu'il soit ajouté à la scène 92 | //on ajoute le mesh au graphe de la scène 93 | scene.add( mesh ); 94 | 95 | //le renderer WebGL crée un élément canvas, pour voir quelque chose. 96 | //il faut ajouter ce canvas au DOM. 97 | document.body.appendChild( renderer.domElement ); 98 | 99 | //on appelle un rendu en lui passant la scène et la caméra 100 | renderer.render( scene, camera ); 101 | -------------------------------------------------------------------------------- /intro/base/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | base scene 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /intro/slides/Callouts_Internet_LOL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/intro/slides/Callouts_Internet_LOL.png -------------------------------------------------------------------------------- /intro/slides/Callouts_Internet_OMG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/intro/slides/Callouts_Internet_OMG.png -------------------------------------------------------------------------------- /intro/slides/Callouts_Internet_RAD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/intro/slides/Callouts_Internet_RAD.png -------------------------------------------------------------------------------- /intro/slides/Callouts_Positive_Hot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/intro/slides/Callouts_Positive_Hot.png -------------------------------------------------------------------------------- /intro/slides/Callouts_Positive_WOW.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/intro/slides/Callouts_Positive_WOW.png -------------------------------------------------------------------------------- /intro/slides/base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/intro/slides/base.png -------------------------------------------------------------------------------- /intro/slides/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/intro/slides/cover.jpg -------------------------------------------------------------------------------- /intro/slides/fragment_operations.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/intro/slides/fragment_operations.jpg -------------------------------------------------------------------------------- /intro/slides/intro_0_stats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/intro/slides/intro_0_stats.png -------------------------------------------------------------------------------- /intro/slides/intro_stats_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/intro/slides/intro_stats_1.png -------------------------------------------------------------------------------- /intro/slides/intro_stats_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/intro/slides/intro_stats_2.png -------------------------------------------------------------------------------- /intro/slides/intro_stats_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/intro/slides/intro_stats_3.png -------------------------------------------------------------------------------- /intro/slides/intro_stats_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/intro/slides/intro_stats_4.png -------------------------------------------------------------------------------- /intro/slides/shaders.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/intro/slides/shaders.png -------------------------------------------------------------------------------- /intro/slides/stats.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/intro/slides/stats.psd -------------------------------------------------------------------------------- /intro/slides/tp.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/intro/slides/tp.psd -------------------------------------------------------------------------------- /intro/slides/webgl_graphics_pipeline.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicoptere/epic_workshop/d20c27771b966faed19faa1c7661388141458b1f/intro/slides/webgl_graphics_pipeline.jpg -------------------------------------------------------------------------------- /libre/exercices.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | suivi 4 | 5 | construire une scène pas à pas 6 | 7 | - setup 8 | - import transforms 9 | - matériaux 10 | - lumières 11 | - * effets 12 | 13 | libre 14 | 15 | 30 minutes 16 | 17 | désosser les fichiers de RO.ME ( http://www.ro.me/tech/ ) 18 | soit un des ceux de res/libre/, soit un du site 19 | 20 | 1h30 21 | créer un mesh custom avec: 22 | - une BufferGeometry composée uniquement de buffers plats 23 | - un ShaderMaterial (ou un RawShaderMaterial) qui colore les vertices 24 | 25 | 2h 26 | 27 | continuer le mesh ou bien au choix 28 | 29 | - utiliser une InstancedBufferGeometry 30 | - créer 100.000 instances 31 | - les déplacer avec un curl noise 32 | 33 | - implémenter une boucle de marche sur le shader 34 | - morpher entre plus de 2 targets 35 | 36 | - implémenter du color picking sur le shader: 37 | - créer un icosahèdre custom 38 | - créer un shader custom qui crée une couleur par face 39 | - créer un buffer supplémentaire 40 | - créer une méthode côté CPU pour rendre et li 41 | 42 | - utiliser un shader shaderToy en texture ou en arrière plan -------------------------------------------------------------------------------- /three.js/examples/js/controls/OrbitControls.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author qiao / https://github.com/qiao 3 | * @author mrdoob / http://mrdoob.com 4 | * @author alteredq / http://alteredqualia.com/ 5 | * @author WestLangley / http://github.com/WestLangley 6 | * @author erich666 / http://erichaines.com 7 | */ 8 | 9 | // This set of controls performs orbiting, dollying (zooming), and panning. 10 | // Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default). 11 | // 12 | // Orbit - left mouse / touch: one finger move 13 | // Zoom - middle mouse, or mousewheel / touch: two finger spread or squish 14 | // Pan - right mouse, or arrow keys / touch: three finger swipe 15 | 16 | THREE.OrbitControls = function ( object, domElement ) { 17 | 18 | this.object = object; 19 | 20 | this.domElement = ( domElement !== undefined ) ? domElement : document; 21 | 22 | // Set to false to disable this control 23 | this.enabled = true; 24 | 25 | // "target" sets the location of focus, where the object orbits around 26 | this.target = new THREE.Vector3(); 27 | 28 | // How far you can dolly in and out ( PerspectiveCamera only ) 29 | this.minDistance = 0; 30 | this.maxDistance = Infinity; 31 | 32 | // How far you can zoom in and out ( OrthographicCamera only ) 33 | this.minZoom = 0; 34 | this.maxZoom = Infinity; 35 | 36 | // How far you can orbit vertically, upper and lower limits. 37 | // Range is 0 to Math.PI radians. 38 | this.minPolarAngle = 0; // radians 39 | this.maxPolarAngle = Math.PI; // radians 40 | 41 | // How far you can orbit horizontally, upper and lower limits. 42 | // If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ]. 43 | this.minAzimuthAngle = - Infinity; // radians 44 | this.maxAzimuthAngle = Infinity; // radians 45 | 46 | // Set to true to enable damping (inertia) 47 | // If damping is enabled, you must call controls.update() in your animation loop 48 | this.enableDamping = false; 49 | this.dampingFactor = 0.25; 50 | 51 | // This option actually enables dollying in and out; left as "zoom" for backwards compatibility. 52 | // Set to false to disable zooming 53 | this.enableZoom = true; 54 | this.zoomSpeed = 1.0; 55 | 56 | // Set to false to disable rotating 57 | this.enableRotate = true; 58 | this.rotateSpeed = 1.0; 59 | 60 | // Set to false to disable panning 61 | this.enablePan = true; 62 | this.keyPanSpeed = 7.0; // pixels moved per arrow key push 63 | 64 | // Set to true to automatically rotate around the target 65 | // If auto-rotate is enabled, you must call controls.update() in your animation loop 66 | this.autoRotate = false; 67 | this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60 68 | 69 | // Set to false to disable use of the keys 70 | this.enableKeys = true; 71 | 72 | // The four arrow keys 73 | this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 }; 74 | 75 | // Mouse buttons 76 | this.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT }; 77 | 78 | // for reset 79 | this.target0 = this.target.clone(); 80 | this.position0 = this.object.position.clone(); 81 | this.zoom0 = this.object.zoom; 82 | 83 | // 84 | // public methods 85 | // 86 | 87 | this.getPolarAngle = function () { 88 | 89 | return spherical.phi; 90 | 91 | }; 92 | 93 | this.getAzimuthalAngle = function () { 94 | 95 | return spherical.theta; 96 | 97 | }; 98 | 99 | this.reset = function () { 100 | 101 | scope.target.copy( scope.target0 ); 102 | scope.object.position.copy( scope.position0 ); 103 | scope.object.zoom = scope.zoom0; 104 | 105 | scope.object.updateProjectionMatrix(); 106 | scope.dispatchEvent( changeEvent ); 107 | 108 | scope.update(); 109 | 110 | state = STATE.NONE; 111 | 112 | }; 113 | 114 | // this method is exposed, but perhaps it would be better if we can make it private... 115 | this.update = function () { 116 | 117 | var offset = new THREE.Vector3(); 118 | 119 | // so camera.up is the orbit axis 120 | var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) ); 121 | var quatInverse = quat.clone().inverse(); 122 | 123 | var lastPosition = new THREE.Vector3(); 124 | var lastQuaternion = new THREE.Quaternion(); 125 | 126 | return function update() { 127 | 128 | var position = scope.object.position; 129 | 130 | offset.copy( position ).sub( scope.target ); 131 | 132 | // rotate offset to "y-axis-is-up" space 133 | offset.applyQuaternion( quat ); 134 | 135 | // angle from z-axis around y-axis 136 | spherical.setFromVector3( offset ); 137 | 138 | if ( scope.autoRotate && state === STATE.NONE ) { 139 | 140 | rotateLeft( getAutoRotationAngle() ); 141 | 142 | } 143 | 144 | spherical.theta += sphericalDelta.theta; 145 | spherical.phi += sphericalDelta.phi; 146 | 147 | // restrict theta to be between desired limits 148 | spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) ); 149 | 150 | // restrict phi to be between desired limits 151 | spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) ); 152 | 153 | spherical.makeSafe(); 154 | 155 | 156 | spherical.radius *= scale; 157 | 158 | // restrict radius to be between desired limits 159 | spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) ); 160 | 161 | // move target to panned location 162 | scope.target.add( panOffset ); 163 | 164 | offset.setFromSpherical( spherical ); 165 | 166 | // rotate offset back to "camera-up-vector-is-up" space 167 | offset.applyQuaternion( quatInverse ); 168 | 169 | position.copy( scope.target ).add( offset ); 170 | 171 | scope.object.lookAt( scope.target ); 172 | 173 | if ( scope.enableDamping === true ) { 174 | 175 | sphericalDelta.theta *= ( 1 - scope.dampingFactor ); 176 | sphericalDelta.phi *= ( 1 - scope.dampingFactor ); 177 | 178 | } else { 179 | 180 | sphericalDelta.set( 0, 0, 0 ); 181 | 182 | } 183 | 184 | scale = 1; 185 | panOffset.set( 0, 0, 0 ); 186 | 187 | // update condition is: 188 | // min(camera displacement, camera rotation in radians)^2 > EPS 189 | // using small-angle approximation cos(x/2) = 1 - x^2 / 8 190 | 191 | if ( zoomChanged || 192 | lastPosition.distanceToSquared( scope.object.position ) > EPS || 193 | 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) { 194 | 195 | scope.dispatchEvent( changeEvent ); 196 | 197 | lastPosition.copy( scope.object.position ); 198 | lastQuaternion.copy( scope.object.quaternion ); 199 | zoomChanged = false; 200 | 201 | return true; 202 | 203 | } 204 | 205 | return false; 206 | 207 | }; 208 | 209 | }(); 210 | 211 | this.dispose = function () { 212 | 213 | scope.domElement.removeEventListener( 'contextmenu', onContextMenu, false ); 214 | scope.domElement.removeEventListener( 'mousedown', onMouseDown, false ); 215 | scope.domElement.removeEventListener( 'wheel', onMouseWheel, false ); 216 | 217 | scope.domElement.removeEventListener( 'touchstart', onTouchStart, false ); 218 | scope.domElement.removeEventListener( 'touchend', onTouchEnd, false ); 219 | scope.domElement.removeEventListener( 'touchmove', onTouchMove, false ); 220 | 221 | document.removeEventListener( 'mousemove', onMouseMove, false ); 222 | document.removeEventListener( 'mouseup', onMouseUp, false ); 223 | 224 | window.removeEventListener( 'keydown', onKeyDown, false ); 225 | 226 | //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here? 227 | 228 | }; 229 | 230 | // 231 | // internals 232 | // 233 | 234 | var scope = this; 235 | 236 | var changeEvent = { type: 'change' }; 237 | var startEvent = { type: 'start' }; 238 | var endEvent = { type: 'end' }; 239 | 240 | var STATE = { NONE: - 1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY: 4, TOUCH_PAN: 5 }; 241 | 242 | var state = STATE.NONE; 243 | 244 | var EPS = 0.000001; 245 | 246 | // current position in spherical coordinates 247 | var spherical = new THREE.Spherical(); 248 | var sphericalDelta = new THREE.Spherical(); 249 | 250 | var scale = 1; 251 | var panOffset = new THREE.Vector3(); 252 | var zoomChanged = false; 253 | 254 | var rotateStart = new THREE.Vector2(); 255 | var rotateEnd = new THREE.Vector2(); 256 | var rotateDelta = new THREE.Vector2(); 257 | 258 | var panStart = new THREE.Vector2(); 259 | var panEnd = new THREE.Vector2(); 260 | var panDelta = new THREE.Vector2(); 261 | 262 | var dollyStart = new THREE.Vector2(); 263 | var dollyEnd = new THREE.Vector2(); 264 | var dollyDelta = new THREE.Vector2(); 265 | 266 | function getAutoRotationAngle() { 267 | 268 | return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed; 269 | 270 | } 271 | 272 | function getZoomScale() { 273 | 274 | return Math.pow( 0.95, scope.zoomSpeed ); 275 | 276 | } 277 | 278 | function rotateLeft( angle ) { 279 | 280 | sphericalDelta.theta -= angle; 281 | 282 | } 283 | 284 | function rotateUp( angle ) { 285 | 286 | sphericalDelta.phi -= angle; 287 | 288 | } 289 | 290 | var panLeft = function () { 291 | 292 | var v = new THREE.Vector3(); 293 | 294 | return function panLeft( distance, objectMatrix ) { 295 | 296 | v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix 297 | v.multiplyScalar( - distance ); 298 | 299 | panOffset.add( v ); 300 | 301 | }; 302 | 303 | }(); 304 | 305 | var panUp = function () { 306 | 307 | var v = new THREE.Vector3(); 308 | 309 | return function panUp( distance, objectMatrix ) { 310 | 311 | v.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix 312 | v.multiplyScalar( distance ); 313 | 314 | panOffset.add( v ); 315 | 316 | }; 317 | 318 | }(); 319 | 320 | // deltaX and deltaY are in pixels; right and down are positive 321 | var pan = function () { 322 | 323 | var offset = new THREE.Vector3(); 324 | 325 | return function pan( deltaX, deltaY ) { 326 | 327 | var element = scope.domElement === document ? scope.domElement.body : scope.domElement; 328 | 329 | if ( scope.object instanceof THREE.PerspectiveCamera ) { 330 | 331 | // perspective 332 | var position = scope.object.position; 333 | offset.copy( position ).sub( scope.target ); 334 | var targetDistance = offset.length(); 335 | 336 | // half of the fov is center to top of screen 337 | targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 ); 338 | 339 | // we actually don't use screenWidth, since perspective camera is fixed to screen height 340 | panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix ); 341 | panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix ); 342 | 343 | } else if ( scope.object instanceof THREE.OrthographicCamera ) { 344 | 345 | // orthographic 346 | panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix ); 347 | panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix ); 348 | 349 | } else { 350 | 351 | // camera neither orthographic nor perspective 352 | console.warn( 'WARNING: OrbitControls.finished encountered an unknown camera type - pan disabled.' ); 353 | scope.enablePan = false; 354 | 355 | } 356 | 357 | }; 358 | 359 | }(); 360 | 361 | function dollyIn( dollyScale ) { 362 | 363 | if ( scope.object instanceof THREE.PerspectiveCamera ) { 364 | 365 | scale /= dollyScale; 366 | 367 | } else if ( scope.object instanceof THREE.OrthographicCamera ) { 368 | 369 | scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) ); 370 | scope.object.updateProjectionMatrix(); 371 | zoomChanged = true; 372 | 373 | } else { 374 | 375 | console.warn( 'WARNING: OrbitControls.finished encountered an unknown camera type - dolly/zoom disabled.' ); 376 | scope.enableZoom = false; 377 | 378 | } 379 | 380 | } 381 | 382 | function dollyOut( dollyScale ) { 383 | 384 | if ( scope.object instanceof THREE.PerspectiveCamera ) { 385 | 386 | scale *= dollyScale; 387 | 388 | } else if ( scope.object instanceof THREE.OrthographicCamera ) { 389 | 390 | scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) ); 391 | scope.object.updateProjectionMatrix(); 392 | zoomChanged = true; 393 | 394 | } else { 395 | 396 | console.warn( 'WARNING: OrbitControls.finished encountered an unknown camera type - dolly/zoom disabled.' ); 397 | scope.enableZoom = false; 398 | 399 | } 400 | 401 | } 402 | 403 | // 404 | // event callbacks - update the object state 405 | // 406 | 407 | function handleMouseDownRotate( event ) { 408 | 409 | //console.log( 'handleMouseDownRotate' ); 410 | 411 | rotateStart.set( event.clientX, event.clientY ); 412 | 413 | } 414 | 415 | function handleMouseDownDolly( event ) { 416 | 417 | //console.log( 'handleMouseDownDolly' ); 418 | 419 | dollyStart.set( event.clientX, event.clientY ); 420 | 421 | } 422 | 423 | function handleMouseDownPan( event ) { 424 | 425 | //console.log( 'handleMouseDownPan' ); 426 | 427 | panStart.set( event.clientX, event.clientY ); 428 | 429 | } 430 | 431 | function handleMouseMoveRotate( event ) { 432 | 433 | //console.log( 'handleMouseMoveRotate' ); 434 | 435 | rotateEnd.set( event.clientX, event.clientY ); 436 | rotateDelta.subVectors( rotateEnd, rotateStart ); 437 | 438 | var element = scope.domElement === document ? scope.domElement.body : scope.domElement; 439 | 440 | // rotating across whole screen goes 360 degrees around 441 | rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed ); 442 | 443 | // rotating up and down along whole screen attempts to go 360, but limited to 180 444 | rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed ); 445 | 446 | rotateStart.copy( rotateEnd ); 447 | 448 | scope.update(); 449 | 450 | } 451 | 452 | function handleMouseMoveDolly( event ) { 453 | 454 | //console.log( 'handleMouseMoveDolly' ); 455 | 456 | dollyEnd.set( event.clientX, event.clientY ); 457 | 458 | dollyDelta.subVectors( dollyEnd, dollyStart ); 459 | 460 | if ( dollyDelta.y > 0 ) { 461 | 462 | dollyIn( getZoomScale() ); 463 | 464 | } else if ( dollyDelta.y < 0 ) { 465 | 466 | dollyOut( getZoomScale() ); 467 | 468 | } 469 | 470 | dollyStart.copy( dollyEnd ); 471 | 472 | scope.update(); 473 | 474 | } 475 | 476 | function handleMouseMovePan( event ) { 477 | 478 | //console.log( 'handleMouseMovePan' ); 479 | 480 | panEnd.set( event.clientX, event.clientY ); 481 | 482 | panDelta.subVectors( panEnd, panStart ); 483 | 484 | pan( panDelta.x, panDelta.y ); 485 | 486 | panStart.copy( panEnd ); 487 | 488 | scope.update(); 489 | 490 | } 491 | 492 | function handleMouseUp( event ) { 493 | 494 | // console.log( 'handleMouseUp' ); 495 | 496 | } 497 | 498 | function handleMouseWheel( event ) { 499 | 500 | // console.log( 'handleMouseWheel' ); 501 | 502 | if ( event.deltaY < 0 ) { 503 | 504 | dollyOut( getZoomScale() ); 505 | 506 | } else if ( event.deltaY > 0 ) { 507 | 508 | dollyIn( getZoomScale() ); 509 | 510 | } 511 | 512 | scope.update(); 513 | 514 | } 515 | 516 | function handleKeyDown( event ) { 517 | 518 | //console.log( 'handleKeyDown' ); 519 | 520 | switch ( event.keyCode ) { 521 | 522 | case scope.keys.UP: 523 | pan( 0, scope.keyPanSpeed ); 524 | scope.update(); 525 | break; 526 | 527 | case scope.keys.BOTTOM: 528 | pan( 0, - scope.keyPanSpeed ); 529 | scope.update(); 530 | break; 531 | 532 | case scope.keys.LEFT: 533 | pan( scope.keyPanSpeed, 0 ); 534 | scope.update(); 535 | break; 536 | 537 | case scope.keys.RIGHT: 538 | pan( - scope.keyPanSpeed, 0 ); 539 | scope.update(); 540 | break; 541 | 542 | } 543 | 544 | } 545 | 546 | function handleTouchStartRotate( event ) { 547 | 548 | //console.log( 'handleTouchStartRotate' ); 549 | 550 | rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); 551 | 552 | } 553 | 554 | function handleTouchStartDolly( event ) { 555 | 556 | //console.log( 'handleTouchStartDolly' ); 557 | 558 | var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; 559 | var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; 560 | 561 | var distance = Math.sqrt( dx * dx + dy * dy ); 562 | 563 | dollyStart.set( 0, distance ); 564 | 565 | } 566 | 567 | function handleTouchStartPan( event ) { 568 | 569 | //console.log( 'handleTouchStartPan' ); 570 | 571 | panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); 572 | 573 | } 574 | 575 | function handleTouchMoveRotate( event ) { 576 | 577 | //console.log( 'handleTouchMoveRotate' ); 578 | 579 | rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); 580 | rotateDelta.subVectors( rotateEnd, rotateStart ); 581 | 582 | var element = scope.domElement === document ? scope.domElement.body : scope.domElement; 583 | 584 | // rotating across whole screen goes 360 degrees around 585 | rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed ); 586 | 587 | // rotating up and down along whole screen attempts to go 360, but limited to 180 588 | rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed ); 589 | 590 | rotateStart.copy( rotateEnd ); 591 | 592 | scope.update(); 593 | 594 | } 595 | 596 | function handleTouchMoveDolly( event ) { 597 | 598 | //console.log( 'handleTouchMoveDolly' ); 599 | 600 | var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; 601 | var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; 602 | 603 | var distance = Math.sqrt( dx * dx + dy * dy ); 604 | 605 | dollyEnd.set( 0, distance ); 606 | 607 | dollyDelta.subVectors( dollyEnd, dollyStart ); 608 | 609 | if ( dollyDelta.y > 0 ) { 610 | 611 | dollyOut( getZoomScale() ); 612 | 613 | } else if ( dollyDelta.y < 0 ) { 614 | 615 | dollyIn( getZoomScale() ); 616 | 617 | } 618 | 619 | dollyStart.copy( dollyEnd ); 620 | 621 | scope.update(); 622 | 623 | } 624 | 625 | function handleTouchMovePan( event ) { 626 | 627 | //console.log( 'handleTouchMovePan' ); 628 | 629 | panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); 630 | 631 | panDelta.subVectors( panEnd, panStart ); 632 | 633 | pan( panDelta.x, panDelta.y ); 634 | 635 | panStart.copy( panEnd ); 636 | 637 | scope.update(); 638 | 639 | } 640 | 641 | function handleTouchEnd( event ) { 642 | 643 | //console.log( 'handleTouchEnd' ); 644 | 645 | } 646 | 647 | // 648 | // event handlers - FSM: listen for events and reset state 649 | // 650 | 651 | function onMouseDown( event ) { 652 | 653 | if ( scope.enabled === false ) return; 654 | 655 | event.preventDefault(); 656 | 657 | if ( event.button === scope.mouseButtons.ORBIT ) { 658 | 659 | if ( scope.enableRotate === false ) return; 660 | 661 | handleMouseDownRotate( event ); 662 | 663 | state = STATE.ROTATE; 664 | 665 | } else if ( event.button === scope.mouseButtons.ZOOM ) { 666 | 667 | if ( scope.enableZoom === false ) return; 668 | 669 | handleMouseDownDolly( event ); 670 | 671 | state = STATE.DOLLY; 672 | 673 | } else if ( event.button === scope.mouseButtons.PAN ) { 674 | 675 | if ( scope.enablePan === false ) return; 676 | 677 | handleMouseDownPan( event ); 678 | 679 | state = STATE.PAN; 680 | 681 | } 682 | 683 | if ( state !== STATE.NONE ) { 684 | 685 | document.addEventListener( 'mousemove', onMouseMove, false ); 686 | document.addEventListener( 'mouseup', onMouseUp, false ); 687 | 688 | scope.dispatchEvent( startEvent ); 689 | 690 | } 691 | 692 | } 693 | 694 | function onMouseMove( event ) { 695 | 696 | if ( scope.enabled === false ) return; 697 | 698 | event.preventDefault(); 699 | 700 | if ( state === STATE.ROTATE ) { 701 | 702 | if ( scope.enableRotate === false ) return; 703 | 704 | handleMouseMoveRotate( event ); 705 | 706 | } else if ( state === STATE.DOLLY ) { 707 | 708 | if ( scope.enableZoom === false ) return; 709 | 710 | handleMouseMoveDolly( event ); 711 | 712 | } else if ( state === STATE.PAN ) { 713 | 714 | if ( scope.enablePan === false ) return; 715 | 716 | handleMouseMovePan( event ); 717 | 718 | } 719 | 720 | } 721 | 722 | function onMouseUp( event ) { 723 | 724 | if ( scope.enabled === false ) return; 725 | 726 | handleMouseUp( event ); 727 | 728 | document.removeEventListener( 'mousemove', onMouseMove, false ); 729 | document.removeEventListener( 'mouseup', onMouseUp, false ); 730 | 731 | scope.dispatchEvent( endEvent ); 732 | 733 | state = STATE.NONE; 734 | 735 | } 736 | 737 | function onMouseWheel( event ) { 738 | 739 | if ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return; 740 | 741 | event.preventDefault(); 742 | event.stopPropagation(); 743 | 744 | handleMouseWheel( event ); 745 | 746 | scope.dispatchEvent( startEvent ); // not sure why these are here... 747 | scope.dispatchEvent( endEvent ); 748 | 749 | } 750 | 751 | function onKeyDown( event ) { 752 | 753 | if ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return; 754 | 755 | handleKeyDown( event ); 756 | 757 | } 758 | 759 | function onTouchStart( event ) { 760 | 761 | if ( scope.enabled === false ) return; 762 | 763 | switch ( event.touches.length ) { 764 | 765 | case 1: // one-fingered touch: rotate 766 | 767 | if ( scope.enableRotate === false ) return; 768 | 769 | handleTouchStartRotate( event ); 770 | 771 | state = STATE.TOUCH_ROTATE; 772 | 773 | break; 774 | 775 | case 2: // two-fingered touch: dolly 776 | 777 | if ( scope.enableZoom === false ) return; 778 | 779 | handleTouchStartDolly( event ); 780 | 781 | state = STATE.TOUCH_DOLLY; 782 | 783 | break; 784 | 785 | case 3: // three-fingered touch: pan 786 | 787 | if ( scope.enablePan === false ) return; 788 | 789 | handleTouchStartPan( event ); 790 | 791 | state = STATE.TOUCH_PAN; 792 | 793 | break; 794 | 795 | default: 796 | 797 | state = STATE.NONE; 798 | 799 | } 800 | 801 | if ( state !== STATE.NONE ) { 802 | 803 | scope.dispatchEvent( startEvent ); 804 | 805 | } 806 | 807 | } 808 | 809 | function onTouchMove( event ) { 810 | 811 | if ( scope.enabled === false ) return; 812 | 813 | event.preventDefault(); 814 | event.stopPropagation(); 815 | 816 | switch ( event.touches.length ) { 817 | 818 | case 1: // one-fingered touch: rotate 819 | 820 | if ( scope.enableRotate === false ) return; 821 | if ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?... 822 | 823 | handleTouchMoveRotate( event ); 824 | 825 | break; 826 | 827 | case 2: // two-fingered touch: dolly 828 | 829 | if ( scope.enableZoom === false ) return; 830 | if ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?... 831 | 832 | handleTouchMoveDolly( event ); 833 | 834 | break; 835 | 836 | case 3: // three-fingered touch: pan 837 | 838 | if ( scope.enablePan === false ) return; 839 | if ( state !== STATE.TOUCH_PAN ) return; // is this needed?... 840 | 841 | handleTouchMovePan( event ); 842 | 843 | break; 844 | 845 | default: 846 | 847 | state = STATE.NONE; 848 | 849 | } 850 | 851 | } 852 | 853 | function onTouchEnd( event ) { 854 | 855 | if ( scope.enabled === false ) return; 856 | 857 | handleTouchEnd( event ); 858 | 859 | scope.dispatchEvent( endEvent ); 860 | 861 | state = STATE.NONE; 862 | 863 | } 864 | 865 | function onContextMenu( event ) { 866 | 867 | event.preventDefault(); 868 | 869 | } 870 | 871 | // 872 | 873 | scope.domElement.addEventListener( 'contextmenu', onContextMenu, false ); 874 | 875 | scope.domElement.addEventListener( 'mousedown', onMouseDown, false ); 876 | scope.domElement.addEventListener( 'wheel', onMouseWheel, false ); 877 | 878 | scope.domElement.addEventListener( 'touchstart', onTouchStart, false ); 879 | scope.domElement.addEventListener( 'touchend', onTouchEnd, false ); 880 | scope.domElement.addEventListener( 'touchmove', onTouchMove, false ); 881 | 882 | window.addEventListener( 'keydown', onKeyDown, false ); 883 | 884 | // force an update at start 885 | 886 | this.update(); 887 | 888 | }; 889 | 890 | THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype ); 891 | THREE.OrbitControls.prototype.constructor = THREE.OrbitControls; 892 | 893 | Object.defineProperties( THREE.OrbitControls.prototype, { 894 | 895 | center: { 896 | 897 | get: function () { 898 | 899 | console.warn( 'THREE.OrbitControls: .center has been renamed to .target' ); 900 | return this.target; 901 | 902 | } 903 | 904 | }, 905 | 906 | // backward compatibility 907 | 908 | noZoom: { 909 | 910 | get: function () { 911 | 912 | console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' ); 913 | return ! this.enableZoom; 914 | 915 | }, 916 | 917 | set: function ( value ) { 918 | 919 | console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' ); 920 | this.enableZoom = ! value; 921 | 922 | } 923 | 924 | }, 925 | 926 | noRotate: { 927 | 928 | get: function () { 929 | 930 | console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' ); 931 | return ! this.enableRotate; 932 | 933 | }, 934 | 935 | set: function ( value ) { 936 | 937 | console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' ); 938 | this.enableRotate = ! value; 939 | 940 | } 941 | 942 | }, 943 | 944 | noPan: { 945 | 946 | get: function () { 947 | 948 | console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' ); 949 | return ! this.enablePan; 950 | 951 | }, 952 | 953 | set: function ( value ) { 954 | 955 | console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' ); 956 | this.enablePan = ! value; 957 | 958 | } 959 | 960 | }, 961 | 962 | noKeys: { 963 | 964 | get: function () { 965 | 966 | console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' ); 967 | return ! this.enableKeys; 968 | 969 | }, 970 | 971 | set: function ( value ) { 972 | 973 | console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' ); 974 | this.enableKeys = ! value; 975 | 976 | } 977 | 978 | }, 979 | 980 | staticMoving: { 981 | 982 | get: function () { 983 | 984 | console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' ); 985 | return ! this.enableDamping; 986 | 987 | }, 988 | 989 | set: function ( value ) { 990 | 991 | console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' ); 992 | this.enableDamping = ! value; 993 | 994 | } 995 | 996 | }, 997 | 998 | dynamicDampingFactor: { 999 | 1000 | get: function () { 1001 | 1002 | console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' ); 1003 | return this.dampingFactor; 1004 | 1005 | }, 1006 | 1007 | set: function ( value ) { 1008 | 1009 | console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' ); 1010 | this.dampingFactor = value; 1011 | 1012 | } 1013 | 1014 | } 1015 | 1016 | } ); 1017 | -------------------------------------------------------------------------------- /three.js/examples/js/loaders/OBJLoader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | */ 4 | 5 | THREE.OBJLoader = function ( manager ) { 6 | 7 | this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; 8 | 9 | this.materials = null; 10 | 11 | this.regexp = { 12 | // v float float float 13 | vertex_pattern : /^v\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)/, 14 | // vn float float float 15 | normal_pattern : /^vn\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)/, 16 | // vt float float 17 | uv_pattern : /^vt\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)/, 18 | // f vertex vertex vertex 19 | face_vertex : /^f\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)(?:\s+(-?\d+))?/, 20 | // f vertex/uv vertex/uv vertex/uv 21 | face_vertex_uv : /^f\s+(-?\d+)\/(-?\d+)\s+(-?\d+)\/(-?\d+)\s+(-?\d+)\/(-?\d+)(?:\s+(-?\d+)\/(-?\d+))?/, 22 | // f vertex/uv/normal vertex/uv/normal vertex/uv/normal 23 | face_vertex_uv_normal : /^f\s+(-?\d+)\/(-?\d+)\/(-?\d+)\s+(-?\d+)\/(-?\d+)\/(-?\d+)\s+(-?\d+)\/(-?\d+)\/(-?\d+)(?:\s+(-?\d+)\/(-?\d+)\/(-?\d+))?/, 24 | // f vertex//normal vertex//normal vertex//normal 25 | face_vertex_normal : /^f\s+(-?\d+)\/\/(-?\d+)\s+(-?\d+)\/\/(-?\d+)\s+(-?\d+)\/\/(-?\d+)(?:\s+(-?\d+)\/\/(-?\d+))?/, 26 | // o object_name | g group_name 27 | object_pattern : /^[og]\s*(.+)?/, 28 | // s boolean 29 | smoothing_pattern : /^s\s+(\d+|on|off)/, 30 | // mtllib file_reference 31 | material_library_pattern : /^mtllib /, 32 | // usemtl material_name 33 | material_use_pattern : /^usemtl / 34 | }; 35 | 36 | }; 37 | 38 | THREE.OBJLoader.prototype = { 39 | 40 | constructor: THREE.OBJLoader, 41 | 42 | load: function ( url, onLoad, onProgress, onError ) { 43 | 44 | var scope = this; 45 | 46 | var loader = new THREE.FileLoader( scope.manager ); 47 | loader.setPath( this.path ); 48 | loader.load( url, function ( text ) { 49 | 50 | onLoad( scope.parse( text ) ); 51 | 52 | }, onProgress, onError ); 53 | 54 | }, 55 | 56 | setPath: function ( value ) { 57 | 58 | this.path = value; 59 | 60 | }, 61 | 62 | setMaterials: function ( materials ) { 63 | 64 | this.materials = materials; 65 | 66 | }, 67 | 68 | _createParserState : function () { 69 | 70 | var state = { 71 | objects : [], 72 | object : {}, 73 | 74 | vertices : [], 75 | normals : [], 76 | uvs : [], 77 | 78 | materialLibraries : [], 79 | 80 | startObject: function ( name, fromDeclaration ) { 81 | 82 | // If the current object (initial from reset) is not from a g/o declaration in the parsed 83 | // file. We need to use it for the first parsed g/o to keep things in sync. 84 | if ( this.object && this.object.fromDeclaration === false ) { 85 | 86 | this.object.name = name; 87 | this.object.fromDeclaration = ( fromDeclaration !== false ); 88 | return; 89 | 90 | } 91 | 92 | var previousMaterial = ( this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined ); 93 | 94 | if ( this.object && typeof this.object._finalize === 'function' ) { 95 | 96 | this.object._finalize( true ); 97 | 98 | } 99 | 100 | this.object = { 101 | name : name || '', 102 | fromDeclaration : ( fromDeclaration !== false ), 103 | 104 | geometry : { 105 | vertices : [], 106 | normals : [], 107 | uvs : [] 108 | }, 109 | materials : [], 110 | smooth : true, 111 | 112 | startMaterial : function( name, libraries ) { 113 | 114 | var previous = this._finalize( false ); 115 | 116 | // New usemtl declaration overwrites an inherited material, except if faces were declared 117 | // after the material, then it must be preserved for proper MultiMaterial continuation. 118 | if ( previous && ( previous.inherited || previous.groupCount <= 0 ) ) { 119 | 120 | this.materials.splice( previous.index, 1 ); 121 | 122 | } 123 | 124 | var material = { 125 | index : this.materials.length, 126 | name : name || '', 127 | mtllib : ( Array.isArray( libraries ) && libraries.length > 0 ? libraries[ libraries.length - 1 ] : '' ), 128 | smooth : ( previous !== undefined ? previous.smooth : this.smooth ), 129 | groupStart : ( previous !== undefined ? previous.groupEnd : 0 ), 130 | groupEnd : -1, 131 | groupCount : -1, 132 | inherited : false, 133 | 134 | clone : function( index ) { 135 | var cloned = { 136 | index : ( typeof index === 'number' ? index : this.index ), 137 | name : this.name, 138 | mtllib : this.mtllib, 139 | smooth : this.smooth, 140 | groupStart : 0, 141 | groupEnd : -1, 142 | groupCount : -1, 143 | inherited : false 144 | }; 145 | cloned.clone = this.clone.bind(cloned); 146 | return cloned; 147 | } 148 | }; 149 | 150 | this.materials.push( material ); 151 | 152 | return material; 153 | 154 | }, 155 | 156 | currentMaterial : function() { 157 | 158 | if ( this.materials.length > 0 ) { 159 | return this.materials[ this.materials.length - 1 ]; 160 | } 161 | 162 | return undefined; 163 | 164 | }, 165 | 166 | _finalize : function( end ) { 167 | 168 | var lastMultiMaterial = this.currentMaterial(); 169 | if ( lastMultiMaterial && lastMultiMaterial.groupEnd === -1 ) { 170 | 171 | lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3; 172 | lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart; 173 | lastMultiMaterial.inherited = false; 174 | 175 | } 176 | 177 | // Ignore objects tail 2_materials if no face declarations followed them before a new o/g started. 178 | if ( end && this.materials.length > 1 ) { 179 | 180 | for ( var mi = this.materials.length - 1; mi >= 0; mi-- ) { 181 | if ( this.materials[mi].groupCount <= 0 ) { 182 | this.materials.splice( mi, 1 ); 183 | } 184 | } 185 | 186 | } 187 | 188 | // Guarantee at least one empty material, this makes the creation later more straight forward. 189 | if ( end && this.materials.length === 0 ) { 190 | 191 | this.materials.push({ 192 | name : '', 193 | smooth : this.smooth 194 | }); 195 | 196 | } 197 | 198 | return lastMultiMaterial; 199 | 200 | } 201 | }; 202 | 203 | // Inherit previous objects material. 204 | // Spec tells us that a declared material must be set to all objects until a new material is declared. 205 | // If a usemtl declaration is encountered while this new object is being parsed, it will 206 | // overwrite the inherited material. Exception being that there was already face declarations 207 | // to the inherited material, then it will be preserved for proper MultiMaterial continuation. 208 | 209 | if ( previousMaterial && previousMaterial.name && typeof previousMaterial.clone === "function" ) { 210 | 211 | var declared = previousMaterial.clone( 0 ); 212 | declared.inherited = true; 213 | this.object.materials.push( declared ); 214 | 215 | } 216 | 217 | this.objects.push( this.object ); 218 | 219 | }, 220 | 221 | finalize : function() { 222 | 223 | if ( this.object && typeof this.object._finalize === 'function' ) { 224 | 225 | this.object._finalize( true ); 226 | 227 | } 228 | 229 | }, 230 | 231 | parseVertexIndex: function ( value, len ) { 232 | 233 | var index = parseInt( value, 10 ); 234 | return ( index >= 0 ? index - 1 : index + len / 3 ) * 3; 235 | 236 | }, 237 | 238 | parseNormalIndex: function ( value, len ) { 239 | 240 | var index = parseInt( value, 10 ); 241 | return ( index >= 0 ? index - 1 : index + len / 3 ) * 3; 242 | 243 | }, 244 | 245 | parseUVIndex: function ( value, len ) { 246 | 247 | var index = parseInt( value, 10 ); 248 | return ( index >= 0 ? index - 1 : index + len / 2 ) * 2; 249 | 250 | }, 251 | 252 | addVertex: function ( a, b, c ) { 253 | 254 | var src = this.vertices; 255 | var dst = this.object.geometry.vertices; 256 | 257 | dst.push( src[ a + 0 ] ); 258 | dst.push( src[ a + 1 ] ); 259 | dst.push( src[ a + 2 ] ); 260 | dst.push( src[ b + 0 ] ); 261 | dst.push( src[ b + 1 ] ); 262 | dst.push( src[ b + 2 ] ); 263 | dst.push( src[ c + 0 ] ); 264 | dst.push( src[ c + 1 ] ); 265 | dst.push( src[ c + 2 ] ); 266 | 267 | }, 268 | 269 | addVertexLine: function ( a ) { 270 | 271 | var src = this.vertices; 272 | var dst = this.object.geometry.vertices; 273 | 274 | dst.push( src[ a + 0 ] ); 275 | dst.push( src[ a + 1 ] ); 276 | dst.push( src[ a + 2 ] ); 277 | 278 | }, 279 | 280 | addNormal : function ( a, b, c ) { 281 | 282 | var src = this.normals; 283 | var dst = this.object.geometry.normals; 284 | 285 | dst.push( src[ a + 0 ] ); 286 | dst.push( src[ a + 1 ] ); 287 | dst.push( src[ a + 2 ] ); 288 | dst.push( src[ b + 0 ] ); 289 | dst.push( src[ b + 1 ] ); 290 | dst.push( src[ b + 2 ] ); 291 | dst.push( src[ c + 0 ] ); 292 | dst.push( src[ c + 1 ] ); 293 | dst.push( src[ c + 2 ] ); 294 | 295 | }, 296 | 297 | addUV: function ( a, b, c ) { 298 | 299 | var src = this.uvs; 300 | var dst = this.object.geometry.uvs; 301 | 302 | dst.push( src[ a + 0 ] ); 303 | dst.push( src[ a + 1 ] ); 304 | dst.push( src[ b + 0 ] ); 305 | dst.push( src[ b + 1 ] ); 306 | dst.push( src[ c + 0 ] ); 307 | dst.push( src[ c + 1 ] ); 308 | 309 | }, 310 | 311 | addUVLine: function ( a ) { 312 | 313 | var src = this.uvs; 314 | var dst = this.object.geometry.uvs; 315 | 316 | dst.push( src[ a + 0 ] ); 317 | dst.push( src[ a + 1 ] ); 318 | 319 | }, 320 | 321 | addFace: function ( a, b, c, d, ua, ub, uc, ud, na, nb, nc, nd ) { 322 | 323 | var vLen = this.vertices.length; 324 | 325 | var ia = this.parseVertexIndex( a, vLen ); 326 | var ib = this.parseVertexIndex( b, vLen ); 327 | var ic = this.parseVertexIndex( c, vLen ); 328 | var id; 329 | 330 | if ( d === undefined ) { 331 | 332 | this.addVertex( ia, ib, ic ); 333 | 334 | } else { 335 | 336 | id = this.parseVertexIndex( d, vLen ); 337 | 338 | this.addVertex( ia, ib, id ); 339 | this.addVertex( ib, ic, id ); 340 | 341 | } 342 | 343 | if ( ua !== undefined ) { 344 | 345 | var uvLen = this.uvs.length; 346 | 347 | ia = this.parseUVIndex( ua, uvLen ); 348 | ib = this.parseUVIndex( ub, uvLen ); 349 | ic = this.parseUVIndex( uc, uvLen ); 350 | 351 | if ( d === undefined ) { 352 | 353 | this.addUV( ia, ib, ic ); 354 | 355 | } else { 356 | 357 | id = this.parseUVIndex( ud, uvLen ); 358 | 359 | this.addUV( ia, ib, id ); 360 | this.addUV( ib, ic, id ); 361 | 362 | } 363 | 364 | } 365 | 366 | if ( na !== undefined ) { 367 | 368 | // Normals are many times the same. If so, skip function call and parseInt. 369 | var nLen = this.normals.length; 370 | ia = this.parseNormalIndex( na, nLen ); 371 | 372 | ib = na === nb ? ia : this.parseNormalIndex( nb, nLen ); 373 | ic = na === nc ? ia : this.parseNormalIndex( nc, nLen ); 374 | 375 | if ( d === undefined ) { 376 | 377 | this.addNormal( ia, ib, ic ); 378 | 379 | } else { 380 | 381 | id = this.parseNormalIndex( nd, nLen ); 382 | 383 | this.addNormal( ia, ib, id ); 384 | this.addNormal( ib, ic, id ); 385 | 386 | } 387 | 388 | } 389 | 390 | }, 391 | 392 | addLineGeometry: function ( vertices, uvs ) { 393 | 394 | this.object.geometry.type = 'Line'; 395 | 396 | var vLen = this.vertices.length; 397 | var uvLen = this.uvs.length; 398 | 399 | for ( var vi = 0, l = vertices.length; vi < l; vi ++ ) { 400 | 401 | this.addVertexLine( this.parseVertexIndex( vertices[ vi ], vLen ) ); 402 | 403 | } 404 | 405 | for ( var uvi = 0, l = uvs.length; uvi < l; uvi ++ ) { 406 | 407 | this.addUVLine( this.parseUVIndex( uvs[ uvi ], uvLen ) ); 408 | 409 | } 410 | 411 | } 412 | 413 | }; 414 | 415 | state.startObject( '', false ); 416 | 417 | return state; 418 | 419 | }, 420 | 421 | parse: function ( text ) { 422 | 423 | console.time( 'OBJLoader' ); 424 | 425 | var state = this._createParserState(); 426 | 427 | if ( text.indexOf( '\r\n' ) !== - 1 ) { 428 | 429 | // This is faster than String.split with regex that splits on both 430 | text = text.replace( /\r\n/g, '\n' ); 431 | 432 | } 433 | 434 | if ( text.indexOf( '\\\n' ) !== - 1) { 435 | 436 | // join lines separated by a line continuation character (\) 437 | text = text.replace( /\\\n/g, '' ); 438 | 439 | } 440 | 441 | var lines = text.split( '\n' ); 442 | var line = '', lineFirstChar = '', lineSecondChar = ''; 443 | var lineLength = 0; 444 | var result = []; 445 | 446 | // Faster to just trim left side of the line. Use if available. 447 | var trimLeft = ( typeof ''.trimLeft === 'function' ); 448 | 449 | for ( var i = 0, l = lines.length; i < l; i ++ ) { 450 | 451 | line = lines[ i ]; 452 | 453 | line = trimLeft ? line.trimLeft() : line.trim(); 454 | 455 | lineLength = line.length; 456 | 457 | if ( lineLength === 0 ) continue; 458 | 459 | lineFirstChar = line.charAt( 0 ); 460 | 461 | // @todo invoke passed in handler if any 462 | if ( lineFirstChar === '#' ) continue; 463 | 464 | if ( lineFirstChar === 'v' ) { 465 | 466 | lineSecondChar = line.charAt( 1 ); 467 | 468 | if ( lineSecondChar === ' ' && ( result = this.regexp.vertex_pattern.exec( line ) ) !== null ) { 469 | 470 | // 0 1 2 3 471 | // ["v 1.0 2.0 3.0", "1.0", "2.0", "3.0"] 472 | 473 | state.vertices.push( 474 | parseFloat( result[ 1 ] ), 475 | parseFloat( result[ 2 ] ), 476 | parseFloat( result[ 3 ] ) 477 | ); 478 | 479 | } else if ( lineSecondChar === 'n' && ( result = this.regexp.normal_pattern.exec( line ) ) !== null ) { 480 | 481 | // 0 1 2 3 482 | // ["vn 1.0 2.0 3.0", "1.0", "2.0", "3.0"] 483 | 484 | state.normals.push( 485 | parseFloat( result[ 1 ] ), 486 | parseFloat( result[ 2 ] ), 487 | parseFloat( result[ 3 ] ) 488 | ); 489 | 490 | } else if ( lineSecondChar === 't' && ( result = this.regexp.uv_pattern.exec( line ) ) !== null ) { 491 | 492 | // 0 1 2 493 | // ["vt 0.1 0.2", "0.1", "0.2"] 494 | 495 | state.uvs.push( 496 | parseFloat( result[ 1 ] ), 497 | parseFloat( result[ 2 ] ) 498 | ); 499 | 500 | } else { 501 | 502 | throw new Error( "Unexpected vertex/normal/uv line: '" + line + "'" ); 503 | 504 | } 505 | 506 | } else if ( lineFirstChar === "f" ) { 507 | 508 | if ( ( result = this.regexp.face_vertex_uv_normal.exec( line ) ) !== null ) { 509 | 510 | // f vertex/uv/normal vertex/uv/normal vertex/uv/normal 511 | // 0 1 2 3 4 5 6 7 8 9 10 11 12 512 | // ["f 1/1/1 2/2/2 3/3/3", "1", "1", "1", "2", "2", "2", "3", "3", "3", undefined, undefined, undefined] 513 | 514 | state.addFace( 515 | result[ 1 ], result[ 4 ], result[ 7 ], result[ 10 ], 516 | result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ], 517 | result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ] 518 | ); 519 | 520 | } else if ( ( result = this.regexp.face_vertex_uv.exec( line ) ) !== null ) { 521 | 522 | // f vertex/uv vertex/uv vertex/uv 523 | // 0 1 2 3 4 5 6 7 8 524 | // ["f 1/1 2/2 3/3", "1", "1", "2", "2", "3", "3", undefined, undefined] 525 | 526 | state.addFace( 527 | result[ 1 ], result[ 3 ], result[ 5 ], result[ 7 ], 528 | result[ 2 ], result[ 4 ], result[ 6 ], result[ 8 ] 529 | ); 530 | 531 | } else if ( ( result = this.regexp.face_vertex_normal.exec( line ) ) !== null ) { 532 | 533 | // f vertex//normal vertex//normal vertex//normal 534 | // 0 1 2 3 4 5 6 7 8 535 | // ["f 1//1 2//2 3//3", "1", "1", "2", "2", "3", "3", undefined, undefined] 536 | 537 | state.addFace( 538 | result[ 1 ], result[ 3 ], result[ 5 ], result[ 7 ], 539 | undefined, undefined, undefined, undefined, 540 | result[ 2 ], result[ 4 ], result[ 6 ], result[ 8 ] 541 | ); 542 | 543 | } else if ( ( result = this.regexp.face_vertex.exec( line ) ) !== null ) { 544 | 545 | // f vertex vertex vertex 546 | // 0 1 2 3 4 547 | // ["f 1 2 3", "1", "2", "3", undefined] 548 | 549 | state.addFace( 550 | result[ 1 ], result[ 2 ], result[ 3 ], result[ 4 ] 551 | ); 552 | 553 | } else { 554 | 555 | throw new Error( "Unexpected face line: '" + line + "'" ); 556 | 557 | } 558 | 559 | } else if ( lineFirstChar === "l" ) { 560 | 561 | var lineParts = line.substring( 1 ).trim().split( " " ); 562 | var lineVertices = [], lineUVs = []; 563 | 564 | if ( line.indexOf( "/" ) === - 1 ) { 565 | 566 | lineVertices = lineParts; 567 | 568 | } else { 569 | 570 | for ( var li = 0, llen = lineParts.length; li < llen; li ++ ) { 571 | 572 | var parts = lineParts[ li ].split( "/" ); 573 | 574 | if ( parts[ 0 ] !== "" ) lineVertices.push( parts[ 0 ] ); 575 | if ( parts[ 1 ] !== "" ) lineUVs.push( parts[ 1 ] ); 576 | 577 | } 578 | 579 | } 580 | state.addLineGeometry( lineVertices, lineUVs ); 581 | 582 | } else if ( ( result = this.regexp.object_pattern.exec( line ) ) !== null ) { 583 | 584 | // o object_name 585 | // or 586 | // g group_name 587 | 588 | // WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869 589 | // var name = result[ 0 ].substr( 1 ).trim(); 590 | var name = ( " " + result[ 0 ].substr( 1 ).trim() ).substr( 1 ); 591 | 592 | state.startObject( name ); 593 | 594 | } else if ( this.regexp.material_use_pattern.test( line ) ) { 595 | 596 | // material 597 | 598 | state.object.startMaterial( line.substring( 7 ).trim(), state.materialLibraries ); 599 | 600 | } else if ( this.regexp.material_library_pattern.test( line ) ) { 601 | 602 | // mtl file 603 | 604 | state.materialLibraries.push( line.substring( 7 ).trim() ); 605 | 606 | } else if ( ( result = this.regexp.smoothing_pattern.exec( line ) ) !== null ) { 607 | 608 | // smooth shading 609 | 610 | // @todo Handle files that have varying smooth values for a set of faces inside one geometry, 611 | // but does not define a usemtl for each face set. 612 | // This should be detected and a dummy material created (later MultiMaterial and geometry groups). 613 | // This requires some care to not create extra material on each smooth value for "normal" obj files. 614 | // where explicit usemtl defines geometry groups. 615 | // Example asset: examples/models/obj/cerberus/Cerberus.obj 616 | 617 | var value = result[ 1 ].trim().toLowerCase(); 618 | state.object.smooth = ( value === '1' || value === 'on' ); 619 | 620 | var material = state.object.currentMaterial(); 621 | if ( material ) { 622 | 623 | material.smooth = state.object.smooth; 624 | 625 | } 626 | 627 | } else { 628 | 629 | // Handle null terminated files without exception 630 | if ( line === '\0' ) continue; 631 | 632 | throw new Error( "Unexpected line: '" + line + "'" ); 633 | 634 | } 635 | 636 | } 637 | 638 | state.finalize(); 639 | 640 | var container = new THREE.Group(); 641 | container.materialLibraries = [].concat( state.materialLibraries ); 642 | 643 | for ( var i = 0, l = state.objects.length; i < l; i ++ ) { 644 | 645 | var object = state.objects[ i ]; 646 | var geometry = object.geometry; 647 | var materials = object.materials; 648 | var isLine = ( geometry.type === 'Line' ); 649 | 650 | // Skip o/g line declarations that did not follow with any faces 651 | if ( geometry.vertices.length === 0 ) continue; 652 | 653 | var buffergeometry = new THREE.BufferGeometry(); 654 | 655 | buffergeometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( geometry.vertices ), 3 ) ); 656 | 657 | if ( geometry.normals.length > 0 ) { 658 | 659 | buffergeometry.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( geometry.normals ), 3 ) ); 660 | 661 | } else { 662 | 663 | buffergeometry.computeVertexNormals(); 664 | 665 | } 666 | 667 | if ( geometry.uvs.length > 0 ) { 668 | 669 | buffergeometry.addAttribute( 'uv', new THREE.BufferAttribute( new Float32Array( geometry.uvs ), 2 ) ); 670 | 671 | } 672 | 673 | // Create 2_materials 674 | 675 | var createdMaterials = []; 676 | 677 | for ( var mi = 0, miLen = materials.length; mi < miLen ; mi++ ) { 678 | 679 | var sourceMaterial = materials[mi]; 680 | var material = undefined; 681 | 682 | if ( this.materials !== null ) { 683 | 684 | material = this.materials.create( sourceMaterial.name ); 685 | 686 | // mtl etc. loaders probably can't create line 2_materials correctly, copy properties to a line material. 687 | if ( isLine && material && ! ( material instanceof THREE.LineBasicMaterial ) ) { 688 | 689 | var materialLine = new THREE.LineBasicMaterial(); 690 | materialLine.copy( material ); 691 | material = materialLine; 692 | 693 | } 694 | 695 | } 696 | 697 | if ( ! material ) { 698 | 699 | material = ( ! isLine ? new THREE.MeshPhongMaterial() : new THREE.LineBasicMaterial() ); 700 | material.name = sourceMaterial.name; 701 | 702 | } 703 | 704 | material.shading = sourceMaterial.smooth ? THREE.SmoothShading : THREE.FlatShading; 705 | 706 | createdMaterials.push(material); 707 | 708 | } 709 | 710 | // Create mesh 711 | 712 | var mesh; 713 | 714 | if ( createdMaterials.length > 1 ) { 715 | 716 | for ( var mi = 0, miLen = materials.length; mi < miLen ; mi++ ) { 717 | 718 | var sourceMaterial = materials[mi]; 719 | buffergeometry.addGroup( sourceMaterial.groupStart, sourceMaterial.groupCount, mi ); 720 | 721 | } 722 | 723 | var multiMaterial = new THREE.MultiMaterial( createdMaterials ); 724 | mesh = ( ! isLine ? new THREE.Mesh( buffergeometry, multiMaterial ) : new THREE.LineSegments( buffergeometry, multiMaterial ) ); 725 | 726 | } else { 727 | 728 | mesh = ( ! isLine ? new THREE.Mesh( buffergeometry, createdMaterials[ 0 ] ) : new THREE.LineSegments( buffergeometry, createdMaterials[ 0 ] ) ); 729 | } 730 | 731 | mesh.name = object.name; 732 | 733 | container.add( mesh ); 734 | 735 | } 736 | 737 | console.timeEnd( 'OBJLoader' ); 738 | 739 | return container; 740 | 741 | } 742 | 743 | }; 744 | -------------------------------------------------------------------------------- /three.js/examples/js/postprocessing/EffectComposer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.EffectComposer = function ( renderer, renderTarget ) { 6 | 7 | this.renderer = renderer; 8 | 9 | if ( renderTarget === undefined ) { 10 | 11 | var parameters = { 12 | minFilter: THREE.LinearFilter, 13 | magFilter: THREE.LinearFilter, 14 | format: THREE.RGBAFormat, 15 | stencilBuffer: false 16 | }; 17 | var size = renderer.getSize(); 18 | renderTarget = new THREE.WebGLRenderTarget( size.width, size.height, parameters ); 19 | 20 | } 21 | 22 | this.renderTarget1 = renderTarget; 23 | this.renderTarget2 = renderTarget.clone(); 24 | 25 | this.writeBuffer = this.renderTarget1; 26 | this.readBuffer = this.renderTarget2; 27 | 28 | this.passes = []; 29 | 30 | if ( THREE.CopyShader === undefined ) 31 | console.error( "THREE.EffectComposer relies on THREE.CopyShader" ); 32 | 33 | this.copyPass = new THREE.ShaderPass( THREE.CopyShader ); 34 | 35 | }; 36 | 37 | Object.assign( THREE.EffectComposer.prototype, { 38 | 39 | swapBuffers: function() { 40 | 41 | var tmp = this.readBuffer; 42 | this.readBuffer = this.writeBuffer; 43 | this.writeBuffer = tmp; 44 | 45 | }, 46 | 47 | addPass: function ( pass ) { 48 | 49 | this.passes.push( pass ); 50 | 51 | var size = this.renderer.getSize(); 52 | pass.setSize( size.width, size.height ); 53 | 54 | }, 55 | 56 | insertPass: function ( pass, index ) { 57 | 58 | this.passes.splice( index, 0, pass ); 59 | 60 | }, 61 | 62 | render: function ( delta ) { 63 | 64 | var maskActive = false; 65 | 66 | var pass, i, il = this.passes.length; 67 | 68 | for ( i = 0; i < il; i ++ ) { 69 | 70 | pass = this.passes[ i ]; 71 | 72 | if ( pass.enabled === false ) continue; 73 | 74 | pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive ); 75 | 76 | if ( pass.needsSwap ) { 77 | 78 | if ( maskActive ) { 79 | 80 | var context = this.renderer.context; 81 | 82 | context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff ); 83 | 84 | this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta ); 85 | 86 | context.stencilFunc( context.EQUAL, 1, 0xffffffff ); 87 | 88 | } 89 | 90 | this.swapBuffers(); 91 | 92 | } 93 | 94 | if ( THREE.MaskPass !== undefined ) { 95 | 96 | if ( pass instanceof THREE.MaskPass ) { 97 | 98 | maskActive = true; 99 | 100 | } else if ( pass instanceof THREE.ClearMaskPass ) { 101 | 102 | maskActive = false; 103 | 104 | } 105 | 106 | } 107 | 108 | } 109 | 110 | }, 111 | 112 | reset: function ( renderTarget ) { 113 | 114 | if ( renderTarget === undefined ) { 115 | 116 | var size = this.renderer.getSize(); 117 | 118 | renderTarget = this.renderTarget1.clone(); 119 | renderTarget.setSize( size.width, size.height ); 120 | 121 | } 122 | 123 | this.renderTarget1.dispose(); 124 | this.renderTarget2.dispose(); 125 | this.renderTarget1 = renderTarget; 126 | this.renderTarget2 = renderTarget.clone(); 127 | 128 | this.writeBuffer = this.renderTarget1; 129 | this.readBuffer = this.renderTarget2; 130 | 131 | }, 132 | 133 | setSize: function ( width, height ) { 134 | 135 | this.renderTarget1.setSize( width, height ); 136 | this.renderTarget2.setSize( width, height ); 137 | 138 | for ( var i = 0; i < this.passes.length; i ++ ) { 139 | 140 | this.passes[i].setSize( width, height ); 141 | 142 | } 143 | 144 | } 145 | 146 | } ); 147 | 148 | 149 | THREE.Pass = function () { 150 | 151 | // if set to true, the pass is processed by the composer 152 | this.enabled = true; 153 | 154 | // if set to true, the pass indicates to swap read and write buffer after rendering 155 | this.needsSwap = true; 156 | 157 | // if set to true, the pass clears its buffer before rendering 158 | this.clear = false; 159 | 160 | // if set to true, the result of the pass is rendered to screen 161 | this.renderToScreen = false; 162 | 163 | }; 164 | 165 | Object.assign( THREE.Pass.prototype, { 166 | 167 | setSize: function( width, height ) {}, 168 | 169 | render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { 170 | 171 | console.error( "THREE.Pass: .render() must be implemented in derived pass." ); 172 | 173 | } 174 | 175 | } ); 176 | -------------------------------------------------------------------------------- /three.js/examples/js/postprocessing/MaskPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.MaskPass = function ( scene, camera ) { 6 | 7 | THREE.Pass.call( this ); 8 | 9 | this.scene = scene; 10 | this.camera = camera; 11 | 12 | this.clear = true; 13 | this.needsSwap = false; 14 | 15 | this.inverse = false; 16 | 17 | }; 18 | 19 | THREE.MaskPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), { 20 | 21 | constructor: THREE.MaskPass, 22 | 23 | render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { 24 | 25 | var context = renderer.context; 26 | var state = renderer.state; 27 | 28 | // don't update color or depth 29 | 30 | state.buffers.color.setMask( false ); 31 | state.buffers.depth.setMask( false ); 32 | 33 | // lock buffers 34 | 35 | state.buffers.color.setLocked( true ); 36 | state.buffers.depth.setLocked( true ); 37 | 38 | // set up stencil 39 | 40 | var writeValue, clearValue; 41 | 42 | if ( this.inverse ) { 43 | 44 | writeValue = 0; 45 | clearValue = 1; 46 | 47 | } else { 48 | 49 | writeValue = 1; 50 | clearValue = 0; 51 | 52 | } 53 | 54 | state.buffers.stencil.setTest( true ); 55 | state.buffers.stencil.setOp( context.REPLACE, context.REPLACE, context.REPLACE ); 56 | state.buffers.stencil.setFunc( context.ALWAYS, writeValue, 0xffffffff ); 57 | state.buffers.stencil.setClear( clearValue ); 58 | 59 | // draw into the stencil buffer 60 | 61 | renderer.render( this.scene, this.camera, readBuffer, this.clear ); 62 | renderer.render( this.scene, this.camera, writeBuffer, this.clear ); 63 | 64 | // unlock color and depth buffer for subsequent rendering 65 | 66 | state.buffers.color.setLocked( false ); 67 | state.buffers.depth.setLocked( false ); 68 | 69 | // only render where stencil is set to 1 70 | 71 | state.buffers.stencil.setFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1 72 | state.buffers.stencil.setOp( context.KEEP, context.KEEP, context.KEEP ); 73 | 74 | } 75 | 76 | } ); 77 | 78 | 79 | THREE.ClearMaskPass = function () { 80 | 81 | THREE.Pass.call( this ); 82 | 83 | this.needsSwap = false; 84 | 85 | }; 86 | 87 | THREE.ClearMaskPass.prototype = Object.create( THREE.Pass.prototype ); 88 | 89 | Object.assign( THREE.ClearMaskPass.prototype, { 90 | 91 | render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { 92 | 93 | renderer.state.buffers.stencil.setTest( false ); 94 | 95 | } 96 | 97 | } ); 98 | -------------------------------------------------------------------------------- /three.js/examples/js/postprocessing/RenderPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.RenderPass = function ( scene, camera, overrideMaterial, clearColor, clearAlpha ) { 6 | 7 | THREE.Pass.call( this ); 8 | 9 | this.scene = scene; 10 | this.camera = camera; 11 | 12 | this.overrideMaterial = overrideMaterial; 13 | 14 | this.clearColor = clearColor; 15 | this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 0; 16 | 17 | this.clear = true; 18 | this.clearDepth = false; 19 | this.needsSwap = false; 20 | 21 | }; 22 | 23 | THREE.RenderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), { 24 | 25 | constructor: THREE.RenderPass, 26 | 27 | render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { 28 | 29 | var oldAutoClear = renderer.autoClear; 30 | renderer.autoClear = false; 31 | 32 | this.scene.overrideMaterial = this.overrideMaterial; 33 | 34 | var oldClearColor, oldClearAlpha; 35 | 36 | if ( this.clearColor ) { 37 | 38 | oldClearColor = renderer.getClearColor().getHex(); 39 | oldClearAlpha = renderer.getClearAlpha(); 40 | 41 | renderer.setClearColor( this.clearColor, this.clearAlpha ); 42 | 43 | } 44 | 45 | if ( this.clearDepth ) { 46 | 47 | renderer.clearDepth(); 48 | 49 | } 50 | 51 | renderer.render( this.scene, this.camera, this.renderToScreen ? null : readBuffer, this.clear ); 52 | 53 | if ( this.clearColor ) { 54 | 55 | renderer.setClearColor( oldClearColor, oldClearAlpha ); 56 | 57 | } 58 | 59 | this.scene.overrideMaterial = null; 60 | renderer.autoClear = oldAutoClear; 61 | } 62 | 63 | } ); 64 | -------------------------------------------------------------------------------- /three.js/examples/js/postprocessing/ShaderPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.ShaderPass = function ( shader, textureID ) { 6 | 7 | THREE.Pass.call( this ); 8 | 9 | this.textureID = ( textureID !== undefined ) ? textureID : "tDiffuse"; 10 | 11 | if ( shader instanceof THREE.ShaderMaterial ) { 12 | 13 | this.uniforms = shader.uniforms; 14 | 15 | this.material = shader; 16 | 17 | } else if ( shader ) { 18 | 19 | this.uniforms = Object.assign( {}, shader.uniforms ); 20 | 21 | this.material = new THREE.ShaderMaterial( { 22 | 23 | defines: shader.defines || {}, 24 | uniforms: this.uniforms, 25 | vertexShader: shader.vertexShader, 26 | fragmentShader: shader.fragmentShader 27 | 28 | } ); 29 | 30 | } 31 | 32 | this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); 33 | this.scene = new THREE.Scene(); 34 | 35 | this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null ); 36 | this.scene.add( this.quad ); 37 | 38 | }; 39 | 40 | THREE.ShaderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), { 41 | 42 | constructor: THREE.ShaderPass, 43 | 44 | render: function( renderer, writeBuffer, readBuffer, delta, maskActive ) { 45 | 46 | if ( this.uniforms[ this.textureID ] ) { 47 | 48 | this.uniforms[ this.textureID ] = new THREE.Uniform( readBuffer.texture ); 49 | 50 | } 51 | 52 | this.quad.material = this.material; 53 | 54 | if ( this.renderToScreen ) { 55 | 56 | renderer.render( this.scene, this.camera ); 57 | 58 | } else { 59 | 60 | renderer.render( this.scene, this.camera, writeBuffer, this.clear ); 61 | 62 | } 63 | 64 | } 65 | 66 | } ); 67 | -------------------------------------------------------------------------------- /three.js/examples/js/postprocessing/UnrealBloomPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author spidersharma / http://eduperiment.com/ 3 | Inspired from Unreal Engine:: 4 | https://docs.unrealengine.com/latest/INT/Engine/Rendering/PostProcessEffects/Bloom/ 5 | */ 6 | 7 | THREE.UnrealBloomPass = function ( resolution, strength, radius, threshold ) { 8 | 9 | THREE.Pass.call( this ); 10 | 11 | this.strength = ( strength !== undefined ) ? strength : 1; 12 | this.radius = radius; 13 | this.threshold = threshold; 14 | this.resolution = ( resolution !== undefined ) ? new THREE.Vector2(resolution.x, resolution.y) : new THREE.Vector2(256, 256); 15 | 16 | // render targets 17 | var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat }; 18 | this.renderTargetsHorizontal = []; 19 | this.renderTargetsVertical = []; 20 | this.nMips = 5; 21 | var resx = Math.round(this.resolution.x/2); 22 | var resy = Math.round(this.resolution.y/2); 23 | 24 | this.renderTargetBright = new THREE.WebGLRenderTarget( resx, resy, pars ); 25 | this.renderTargetBright.texture.generateMipmaps = false; 26 | 27 | for( var i=0; i\ 246 | varying vec2 vUv;\n\ 247 | uniform sampler2D colorTexture;\n\ 248 | uniform vec2 texSize;\ 249 | uniform vec2 direction;\ 250 | \ 251 | float gaussianPdf(in float x, in float sigma) {\ 252 | return 0.39894 * exp( -0.5 * x * x/( sigma * sigma))/sigma;\ 253 | }\ 254 | void main() {\n\ 255 | vec2 invSize = 1.0 / texSize;\ 256 | float fSigma = float(SIGMA);\ 257 | float weightSum = gaussianPdf(0.0, fSigma);\ 258 | vec3 diffuseSum = texture2D( colorTexture, vUv).rgb * weightSum;\ 259 | for( int i = 1; i < KERNEL_RADIUS; i ++ ) {\ 260 | float x = float(i);\ 261 | float w = gaussianPdf(x, fSigma);\ 262 | vec2 uvOffset = direction * invSize * x;\ 263 | vec3 sample1 = texture2D( colorTexture, vUv + uvOffset).rgb;\ 264 | vec3 sample2 = texture2D( colorTexture, vUv - uvOffset).rgb;\ 265 | diffuseSum += (sample1 + sample2) * w;\ 266 | weightSum += 2.0 * w;\ 267 | }\ 268 | gl_FragColor = vec4(diffuseSum/weightSum, 1.0);\n\ 269 | }" 270 | } ); 271 | }, 272 | 273 | getCompositeMaterial: function(nMips) { 274 | 275 | return new THREE.ShaderMaterial( { 276 | 277 | defines:{ 278 | "NUM_MIPS" : nMips 279 | }, 280 | 281 | uniforms: { 282 | "blurTexture1": { value: null }, 283 | "blurTexture2": { value: null }, 284 | "blurTexture3": { value: null }, 285 | "blurTexture4": { value: null }, 286 | "blurTexture5": { value: null }, 287 | "dirtTexture": { value: null }, 288 | "bloomStrength" : { value: 1.0 }, 289 | "bloomFactors" : { value: null }, 290 | "bloomTintColors" : { value: null }, 291 | "bloomRadius" : { value: 0.0 } 292 | }, 293 | 294 | vertexShader: 295 | "varying vec2 vUv;\n\ 296 | void main() {\n\ 297 | vUv = uv;\n\ 298 | gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\ 299 | }", 300 | 301 | fragmentShader: 302 | "varying vec2 vUv;\ 303 | uniform sampler2D blurTexture1;\ 304 | uniform sampler2D blurTexture2;\ 305 | uniform sampler2D blurTexture3;\ 306 | uniform sampler2D blurTexture4;\ 307 | uniform sampler2D blurTexture5;\ 308 | uniform sampler2D dirtTexture;\ 309 | uniform float bloomStrength;\ 310 | uniform float bloomRadius;\ 311 | uniform float bloomFactors[NUM_MIPS];\ 312 | uniform vec3 bloomTintColors[NUM_MIPS];\ 313 | \ 314 | float lerpBloomFactor(const in float factor) { \ 315 | float mirrorFactor = 1.2 - factor;\ 316 | return mix(factor, mirrorFactor, bloomRadius);\ 317 | }\ 318 | \ 319 | void main() {\ 320 | gl_FragColor = bloomStrength * ( lerpBloomFactor(bloomFactors[0]) * vec4(bloomTintColors[0], 1.0) * texture2D(blurTexture1, vUv) + \ 321 | lerpBloomFactor(bloomFactors[1]) * vec4(bloomTintColors[1], 1.0) * texture2D(blurTexture2, vUv) + \ 322 | lerpBloomFactor(bloomFactors[2]) * vec4(bloomTintColors[2], 1.0) * texture2D(blurTexture3, vUv) + \ 323 | lerpBloomFactor(bloomFactors[3]) * vec4(bloomTintColors[3], 1.0) * texture2D(blurTexture4, vUv) + \ 324 | lerpBloomFactor(bloomFactors[4]) * vec4(bloomTintColors[4], 1.0) * texture2D(blurTexture5, vUv) );\ 325 | }" 326 | } ); 327 | } 328 | 329 | } ); 330 | 331 | THREE.UnrealBloomPass.BlurDirectionX = new THREE.Vector2( 1.0, 0.0 ); 332 | THREE.UnrealBloomPass.BlurDirectionY = new THREE.Vector2( 0.0, 1.0 ); 333 | -------------------------------------------------------------------------------- /three.js/examples/js/shaders/ConvolutionShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Convolution shader 5 | * ported from o3d sample to WebGL / GLSL 6 | * http://o3d.googlecode.com/svn/trunk/samples/convolution.html 7 | */ 8 | 9 | THREE.ConvolutionShader = { 10 | 11 | defines: { 12 | 13 | "KERNEL_SIZE_FLOAT": "25.0", 14 | "KERNEL_SIZE_INT": "25" 15 | 16 | }, 17 | 18 | uniforms: { 19 | 20 | "tDiffuse": { value: null }, 21 | "uImageIncrement": { value: new THREE.Vector2( 0.001953125, 0.0 ) }, 22 | "cKernel": { value: [] } 23 | 24 | }, 25 | 26 | vertexShader: [ 27 | 28 | "uniform vec2 uImageIncrement;", 29 | 30 | "varying vec2 vUv;", 31 | 32 | "void main() {", 33 | 34 | "vUv = uv - ( ( KERNEL_SIZE_FLOAT - 1.0 ) / 2.0 ) * uImageIncrement;", 35 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 36 | 37 | "}" 38 | 39 | ].join( "\n" ), 40 | 41 | fragmentShader: [ 42 | 43 | "uniform float cKernel[ KERNEL_SIZE_INT ];", 44 | 45 | "uniform sampler2D tDiffuse;", 46 | "uniform vec2 uImageIncrement;", 47 | 48 | "varying vec2 vUv;", 49 | 50 | "void main() {", 51 | 52 | "vec2 imageCoord = vUv;", 53 | "vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );", 54 | 55 | "for( int i = 0; i < KERNEL_SIZE_INT; i ++ ) {", 56 | 57 | "sum += texture2D( tDiffuse, imageCoord ) * cKernel[ i ];", 58 | "imageCoord += uImageIncrement;", 59 | 60 | "}", 61 | 62 | "gl_FragColor = sum;", 63 | 64 | "}" 65 | 66 | 67 | ].join( "\n" ), 68 | 69 | buildKernel: function ( sigma ) { 70 | 71 | // We lop off the sqrt(2 * pi) * sigma term, since we're going to normalize anyway. 72 | 73 | function gauss( x, sigma ) { 74 | 75 | return Math.exp( - ( x * x ) / ( 2.0 * sigma * sigma ) ); 76 | 77 | } 78 | 79 | var i, values, sum, halfWidth, kMaxKernelSize = 25, kernelSize = 2 * Math.ceil( sigma * 3.0 ) + 1; 80 | 81 | if ( kernelSize > kMaxKernelSize ) kernelSize = kMaxKernelSize; 82 | halfWidth = ( kernelSize - 1 ) * 0.5; 83 | 84 | values = new Array( kernelSize ); 85 | sum = 0.0; 86 | for ( i = 0; i < kernelSize; ++ i ) { 87 | 88 | values[ i ] = gauss( i - halfWidth, sigma ); 89 | sum += values[ i ]; 90 | 91 | } 92 | 93 | // normalize the kernel 94 | 95 | for ( i = 0; i < kernelSize; ++ i ) values[ i ] /= sum; 96 | 97 | return values; 98 | 99 | } 100 | 101 | }; 102 | -------------------------------------------------------------------------------- /three.js/examples/js/shaders/CopyShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Full-screen textured quad shader 5 | */ 6 | 7 | THREE.CopyShader = { 8 | 9 | uniforms: { 10 | 11 | "tDiffuse": { value: null }, 12 | "opacity": { value: 1.0 } 13 | 14 | }, 15 | 16 | vertexShader: [ 17 | 18 | "varying vec2 vUv;", 19 | 20 | "void main() {", 21 | 22 | "vUv = uv;", 23 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 24 | 25 | "}" 26 | 27 | ].join( "\n" ), 28 | 29 | fragmentShader: [ 30 | 31 | "uniform float opacity;", 32 | 33 | "uniform sampler2D tDiffuse;", 34 | 35 | "varying vec2 vUv;", 36 | 37 | "void main() {", 38 | 39 | "vec4 texel = texture2D( tDiffuse, vUv );", 40 | "gl_FragColor = opacity * texel;", 41 | 42 | "}" 43 | 44 | ].join( "\n" ) 45 | 46 | }; 47 | -------------------------------------------------------------------------------- /three.js/examples/js/shaders/FXAAShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * @author davidedc / http://www.sketchpatch.net/ 4 | * 5 | * NVIDIA FXAA by Timothy Lottes 6 | * http://timothylottes.blogspot.com/2011/06/fxaa3-source-released.html 7 | * - WebGL port by @supereggbert 8 | * http://www.glge.org/demos/fxaa/ 9 | */ 10 | 11 | THREE.FXAAShader = { 12 | 13 | uniforms: { 14 | 15 | "tDiffuse": { value: null }, 16 | "resolution": { value: new THREE.Vector2( 1 / 1024, 1 / 512 ) } 17 | 18 | }, 19 | 20 | vertexShader: [ 21 | 22 | "void main() {", 23 | 24 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 25 | 26 | "}" 27 | 28 | ].join( "\n" ), 29 | 30 | fragmentShader: [ 31 | 32 | "uniform sampler2D tDiffuse;", 33 | "uniform vec2 resolution;", 34 | 35 | "#define FXAA_REDUCE_MIN (1.0/128.0)", 36 | "#define FXAA_REDUCE_MUL (1.0/8.0)", 37 | "#define FXAA_SPAN_MAX 8.0", 38 | 39 | "void main() {", 40 | 41 | "vec3 rgbNW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ).xyz;", 42 | "vec3 rgbNE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ).xyz;", 43 | "vec3 rgbSW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ).xyz;", 44 | "vec3 rgbSE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ).xyz;", 45 | "vec4 rgbaM = texture2D( tDiffuse, gl_FragCoord.xy * resolution );", 46 | "vec3 rgbM = rgbaM.xyz;", 47 | "vec3 luma = vec3( 0.299, 0.587, 0.114 );", 48 | 49 | "float lumaNW = dot( rgbNW, luma );", 50 | "float lumaNE = dot( rgbNE, luma );", 51 | "float lumaSW = dot( rgbSW, luma );", 52 | "float lumaSE = dot( rgbSE, luma );", 53 | "float lumaM = dot( rgbM, luma );", 54 | "float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );", 55 | "float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );", 56 | 57 | "vec2 dir;", 58 | "dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));", 59 | "dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));", 60 | 61 | "float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );", 62 | 63 | "float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );", 64 | "dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),", 65 | "max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),", 66 | "dir * rcpDirMin)) * resolution;", 67 | "vec4 rgbA = (1.0/2.0) * (", 68 | "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (1.0/3.0 - 0.5)) +", 69 | "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (2.0/3.0 - 0.5)));", 70 | "vec4 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (", 71 | "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (0.0/3.0 - 0.5)) +", 72 | "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (3.0/3.0 - 0.5)));", 73 | "float lumaB = dot(rgbB, vec4(luma, 0.0));", 74 | 75 | "if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) ) {", 76 | 77 | "gl_FragColor = rgbA;", 78 | 79 | "} else {", 80 | "gl_FragColor = rgbB;", 81 | 82 | "}", 83 | 84 | "}" 85 | 86 | ].join( "\n" ) 87 | 88 | }; 89 | -------------------------------------------------------------------------------- /three.js/examples/js/shaders/LuminosityHighPassShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author bhouston / http://clara.io/ 3 | * 4 | * Luminosity 5 | * http://en.wikipedia.org/wiki/Luminosity 6 | */ 7 | 8 | THREE.LuminosityHighPassShader = { 9 | 10 | shaderID: "luminosityHighPass", 11 | 12 | uniforms: { 13 | 14 | "tDiffuse": { type: "t", value: null }, 15 | "luminosityThreshold": { type: "f", value: 1.0 }, 16 | "smoothWidth": { type: "f", value: 1.0 }, 17 | "defaultColor": { type: "c", value: new THREE.Color( 0x000000 ) }, 18 | "defaultOpacity": { type: "f", value: 0.0 } 19 | 20 | }, 21 | 22 | vertexShader: [ 23 | 24 | "varying vec2 vUv;", 25 | 26 | "void main() {", 27 | 28 | "vUv = uv;", 29 | 30 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 31 | 32 | "}" 33 | 34 | ].join("\n"), 35 | 36 | fragmentShader: [ 37 | 38 | "uniform sampler2D tDiffuse;", 39 | "uniform vec3 defaultColor;", 40 | "uniform float defaultOpacity;", 41 | "uniform float luminosityThreshold;", 42 | "uniform float smoothWidth;", 43 | 44 | "varying vec2 vUv;", 45 | 46 | "void main() {", 47 | 48 | "vec4 texel = texture2D( tDiffuse, vUv );", 49 | 50 | "vec3 luma = vec3( 0.299, 0.587, 0.114 );", 51 | 52 | "float v = dot( texel.xyz, luma );", 53 | 54 | "vec4 outputColor = vec4( defaultColor.rgb, defaultOpacity );", 55 | 56 | "float alpha = smoothstep( luminosityThreshold, luminosityThreshold + smoothWidth, v );", 57 | 58 | "gl_FragColor = mix( outputColor, texel, alpha );", 59 | 60 | "}" 61 | 62 | ].join("\n") 63 | 64 | }; 65 | -------------------------------------------------------------------------------- /three.js/examples/js/shaders/RGBShiftShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author felixturner / http://airtight.cc/ 3 | * 4 | * RGB Shift Shader 5 | * Shifts red and blue channels from center in opposite directions 6 | * Ported from http://kriss.cx/tom/2009/05/rgb-shift/ 7 | * by Tom Butterworth / http://kriss.cx/tom/ 8 | * 9 | * amount: shift distance (1 is width of input) 10 | * angle: shift angle in radians 11 | */ 12 | 13 | THREE.RGBShiftShader = { 14 | 15 | uniforms: { 16 | 17 | "tDiffuse": { value: null }, 18 | "amount": { value: 0.005 }, 19 | "angle": { value: 0.0 } 20 | 21 | }, 22 | 23 | vertexShader: [ 24 | 25 | "varying vec2 vUv;", 26 | 27 | "void main() {", 28 | 29 | "vUv = uv;", 30 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 31 | 32 | "}" 33 | 34 | ].join( "\n" ), 35 | 36 | fragmentShader: [ 37 | 38 | "uniform sampler2D tDiffuse;", 39 | "uniform float amount;", 40 | "uniform float angle;", 41 | 42 | "varying vec2 vUv;", 43 | 44 | "void main() {", 45 | 46 | "vec2 offset = amount * vec2( cos(angle), sin(angle));", 47 | "vec4 cr = texture2D(tDiffuse, vUv + offset);", 48 | "vec4 cga = texture2D(tDiffuse, vUv);", 49 | "vec4 cb = texture2D(tDiffuse, vUv - offset);", 50 | "gl_FragColor = vec4(cr.r, cga.g, cb.b, cga.a);", 51 | 52 | "}" 53 | 54 | ].join( "\n" ) 55 | 56 | }; 57 | -------------------------------------------------------------------------------- /three.js/examples/js/shaders/SSAOShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Screen-space ambient occlusion shader 5 | * - ported from 6 | * SSAO GLSL shader v1.2 7 | * assembled by Martins Upitis (martinsh) (http://devlog-martinsh.blogspot.com) 8 | * original technique is made by ArKano22 (http://www.gamedev.net/topic/550699-ssao-no-halo-artifacts/) 9 | * - modifications 10 | * - modified to use RGBA packed depth texture (use clear color 1,1,1,1 for depth pass) 11 | * - refactoring and optimizations 12 | */ 13 | 14 | THREE.SSAOShader = { 15 | 16 | uniforms: { 17 | 18 | "tDiffuse": { value: null }, 19 | "tDepth": { value: null }, 20 | "size": { value: new THREE.Vector2( 512, 512 ) }, 21 | "cameraNear": { value: 1 }, 22 | "cameraFar": { value: 100 }, 23 | "onlyAO": { value: 0 }, 24 | "aoClamp": { value: 0.5 }, 25 | "lumInfluence": { value: 0.5 } 26 | 27 | }, 28 | 29 | vertexShader: [ 30 | 31 | "varying vec2 vUv;", 32 | 33 | "void main() {", 34 | 35 | "vUv = uv;", 36 | 37 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 38 | 39 | "}" 40 | 41 | ].join( "\n" ), 42 | 43 | fragmentShader: [ 44 | 45 | "uniform float cameraNear;", 46 | "uniform float cameraFar;", 47 | "#ifdef USE_LOGDEPTHBUF", 48 | "uniform float logDepthBufFC;", 49 | "#endif", 50 | 51 | "uniform bool onlyAO;", // use only ambient occlusion pass? 52 | 53 | "uniform vec2 size;", // texture width, height 54 | "uniform float aoClamp;", // depth clamp - reduces haloing at screen edges 55 | 56 | "uniform float lumInfluence;", // how much luminance affects occlusion 57 | 58 | "uniform sampler2D tDiffuse;", 59 | "uniform sampler2D tDepth;", 60 | 61 | "varying vec2 vUv;", 62 | 63 | // "#define PI 3.14159265", 64 | "#define DL 2.399963229728653", // PI * ( 3.0 - sqrt( 5.0 ) ) 65 | "#define EULER 2.718281828459045", 66 | 67 | // user variables 68 | 69 | "const int samples = 8;", // ao sample count 70 | "const float radius = 5.0;", // ao radius 71 | 72 | "const bool useNoise = false;", // use noise instead of pattern for sample dithering 73 | "const float noiseAmount = 0.0003;", // dithering amount 74 | 75 | "const float diffArea = 0.4;", // self-shadowing reduction 76 | "const float gDisplace = 0.4;", // gauss bell center 77 | 78 | 79 | // RGBA depth 80 | 81 | "#include ", 82 | 83 | // generating noise / pattern texture for dithering 84 | 85 | "vec2 rand( const vec2 coord ) {", 86 | 87 | "vec2 noise;", 88 | 89 | "if ( useNoise ) {", 90 | 91 | "float nx = dot ( coord, vec2( 12.9898, 78.233 ) );", 92 | "float ny = dot ( coord, vec2( 12.9898, 78.233 ) * 2.0 );", 93 | 94 | "noise = clamp( fract ( 43758.5453 * sin( vec2( nx, ny ) ) ), 0.0, 1.0 );", 95 | 96 | "} else {", 97 | 98 | "float ff = fract( 1.0 - coord.s * ( size.x / 2.0 ) );", 99 | "float gg = fract( coord.t * ( size.y / 2.0 ) );", 100 | 101 | "noise = vec2( 0.25, 0.75 ) * vec2( ff ) + vec2( 0.75, 0.25 ) * gg;", 102 | 103 | "}", 104 | 105 | "return ( noise * 2.0 - 1.0 ) * noiseAmount;", 106 | 107 | "}", 108 | 109 | "float readDepth( const in vec2 coord ) {", 110 | 111 | "float cameraFarPlusNear = cameraFar + cameraNear;", 112 | "float cameraFarMinusNear = cameraFar - cameraNear;", 113 | "float cameraCoef = 2.0 * cameraNear;", 114 | 115 | "#ifdef USE_LOGDEPTHBUF", 116 | 117 | "float logz = unpackRGBAToDepth( texture2D( tDepth, coord ) );", 118 | "float w = pow(2.0, (logz / logDepthBufFC)) - 1.0;", 119 | "float z = (logz / w) + 1.0;", 120 | 121 | "#else", 122 | 123 | "float z = unpackRGBAToDepth( texture2D( tDepth, coord ) );", 124 | 125 | "#endif", 126 | 127 | "return cameraCoef / ( cameraFarPlusNear - z * cameraFarMinusNear );", 128 | 129 | 130 | "}", 131 | 132 | "float compareDepths( const in float depth1, const in float depth2, inout int far ) {", 133 | 134 | "float garea = 2.0;", // gauss bell width 135 | "float diff = ( depth1 - depth2 ) * 100.0;", // depth difference (0-100) 136 | 137 | // reduce left bell width to avoid self-shadowing 138 | 139 | "if ( diff < gDisplace ) {", 140 | 141 | "garea = diffArea;", 142 | 143 | "} else {", 144 | 145 | "far = 1;", 146 | 147 | "}", 148 | 149 | "float dd = diff - gDisplace;", 150 | "float gauss = pow( EULER, -2.0 * dd * dd / ( garea * garea ) );", 151 | "return gauss;", 152 | 153 | "}", 154 | 155 | "float calcAO( float depth, float dw, float dh ) {", 156 | 157 | "float dd = radius - depth * radius;", 158 | "vec2 vv = vec2( dw, dh );", 159 | 160 | "vec2 coord1 = vUv + dd * vv;", 161 | "vec2 coord2 = vUv - dd * vv;", 162 | 163 | "float temp1 = 0.0;", 164 | "float temp2 = 0.0;", 165 | 166 | "int far = 0;", 167 | "temp1 = compareDepths( depth, readDepth( coord1 ), far );", 168 | 169 | // DEPTH EXTRAPOLATION 170 | 171 | "if ( far > 0 ) {", 172 | 173 | "temp2 = compareDepths( readDepth( coord2 ), depth, far );", 174 | "temp1 += ( 1.0 - temp1 ) * temp2;", 175 | 176 | "}", 177 | 178 | "return temp1;", 179 | 180 | "}", 181 | 182 | "void main() {", 183 | 184 | "vec2 noise = rand( vUv );", 185 | "float depth = readDepth( vUv );", 186 | 187 | "float tt = clamp( depth, aoClamp, 1.0 );", 188 | 189 | "float w = ( 1.0 / size.x ) / tt + ( noise.x * ( 1.0 - noise.x ) );", 190 | "float h = ( 1.0 / size.y ) / tt + ( noise.y * ( 1.0 - noise.y ) );", 191 | 192 | "float ao = 0.0;", 193 | 194 | "float dz = 1.0 / float( samples );", 195 | "float z = 1.0 - dz / 2.0;", 196 | "float l = 0.0;", 197 | 198 | "for ( int i = 0; i <= samples; i ++ ) {", 199 | 200 | "float r = sqrt( 1.0 - z );", 201 | 202 | "float pw = cos( l ) * r;", 203 | "float ph = sin( l ) * r;", 204 | "ao += calcAO( depth, pw * w, ph * h );", 205 | "z = z - dz;", 206 | "l = l + DL;", 207 | 208 | "}", 209 | 210 | "ao /= float( samples );", 211 | "ao = 1.0 - ao;", 212 | 213 | "vec3 color = texture2D( tDiffuse, vUv ).rgb;", 214 | 215 | "vec3 lumcoeff = vec3( 0.299, 0.587, 0.114 );", 216 | "float lum = dot( color.rgb, lumcoeff );", 217 | "vec3 luminance = vec3( lum );", 218 | 219 | "vec3 final = vec3( color * mix( vec3( ao ), vec3( 1.0 ), luminance * lumInfluence ) );", // mix( color * ao, white, luminance ) 220 | 221 | "if ( onlyAO ) {", 222 | 223 | "final = vec3( mix( vec3( ao ), vec3( 1.0 ), luminance * lumInfluence ) );", // ambient occlusion only 224 | 225 | "}", 226 | 227 | "gl_FragColor = vec4( final, 1.0 );", 228 | 229 | "}" 230 | 231 | ].join( "\n" ) 232 | 233 | }; 234 | -------------------------------------------------------------------------------- /three.js/examples/js/shaders/VignetteShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Vignette shader 5 | * based on PaintEffect postprocess from ro.me 6 | * http://code.google.com/p/3-dreams-of-black/source/browse/deploy/js/effects/PaintEffect.js 7 | */ 8 | 9 | THREE.VignetteShader = { 10 | 11 | uniforms: { 12 | 13 | "tDiffuse": { value: null }, 14 | "offset": { value: 1.0 }, 15 | "darkness": { value: 1.0 } 16 | 17 | }, 18 | 19 | vertexShader: [ 20 | 21 | "varying vec2 vUv;", 22 | 23 | "void main() {", 24 | 25 | "vUv = uv;", 26 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 27 | 28 | "}" 29 | 30 | ].join( "\n" ), 31 | 32 | fragmentShader: [ 33 | 34 | "uniform float offset;", 35 | "uniform float darkness;", 36 | 37 | "uniform sampler2D tDiffuse;", 38 | 39 | "varying vec2 vUv;", 40 | 41 | "void main() {", 42 | 43 | // Eskil's vignette 44 | 45 | "vec4 texel = texture2D( tDiffuse, vUv );", 46 | "vec2 uv = ( vUv - vec2( 0.5 ) ) * vec2( offset );", 47 | "gl_FragColor = vec4( mix( texel.rgb, vec3( 1.0 - darkness ), dot( uv, uv ) ), texel.a );", 48 | 49 | /* 50 | // alternative version from glfx.js 51 | // this one makes more "dusty" look (as opposed to "burned") 52 | 53 | "vec4 color = texture2D( tDiffuse, vUv );", 54 | "float dist = distance( vUv, vec2( 0.5 ) );", 55 | "color.rgb *= smoothstep( 0.8, offset * 0.799, dist *( darkness + offset ) );", 56 | "gl_FragColor = color;", 57 | */ 58 | 59 | "}" 60 | 61 | ].join( "\n" ) 62 | 63 | }; 64 | --------------------------------------------------------------------------------